Page 1 of 1

Posted: Fri Dec 06, 2002 12:51 pm
by BackupUser
Restored from previous forum. Originally posted by Tech-Man.

I am trying to get the drive manufacturer string from within PB, I can do it via a vbscript Win32_DriveInfo call, but I cant find a way inside PB..

I cant see any API's that produce the complete drive info's only volumenames/sizes etc...

In case your confused as to what i'm on about i want to retreive the product string from the hard drive i.e
MAXTOR 4D040H2
etc...

thx....

Posted: Fri Dec 06, 2002 1:20 pm
by BackupUser
Restored from previous forum. Originally posted by Jondo.

try GetVolumeInformation :)

Posted: Fri Dec 06, 2002 4:34 pm
by BackupUser
Restored from previous forum. Originally posted by MrVainSCL.

hi Tech-Man,
following example will not show the drive manufactor but maybe it helps you anyway!? I have found the example someone one Paul´s resource site and modified the source a bit to get work with the latest PB version for windows...

Code: Select all

User.s=Space(255)
l.l=255
Result=GetComputerName_(User,@l)
Info.s
Info="Computername:"+Left(User,l)+Chr(13)

User.s=Space(255)
l.l=255
Result=GetUserName_(User,@l)
Info=Info+"User:"+LTrim(User)+Chr(13)

lpRootPathName.s="C:\"
pVolumeNameBuffer.s=Space(256)
nVolumeNameSize.l=256
lpVolumeSerialNumber.l
lpMaximumComponentLength.l
lpFileSystemFlags.l
lpFileSystemNameBuffer.s=Space(256)
nFileSystemNameSize.l=256

Result=GetVolumeInformation_(lpRootPathName,pVolumeNameBuffer,256,@lpVolumeSerialNumber,@lpMaximumComponentLength,@lpFileSystemFlags,lpFileSystemNameBuffer,256)

Info=Info + "ID="+Hex(lpVolumeSerialNumber)+Chr(13)
Info=Info +"VolumeName:"+LTrim(pVolumeNameBuffer) +Chr(13)
Info=Info + "Filesystem:"+LTrim(lpFileSystemNameBuffer)

MessageRequester("HardDisk Info",Info,0)

PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX8.1, SB AWE64, Win2000 + all Updates...

greetz
MrVainSCL! aka Thorsten

Posted: Sat Dec 07, 2002 5:23 pm
by BackupUser
Restored from previous forum. Originally posted by Hi-Toro.

You can get this via the Registry, but there's apparently some way to get it via some call that I don't understand, here: http://msdn.microsoft.com/library/defau ... device.asp . I don't think there's any way to access this from PB, unless someone can prove me wrong?

Here's the Registry way, only tested with Windows 2000!

Code: Select all

Procedure.s GetDriveManufacturer (ideChannel, ideUnit)

  ide$ = Str (ideChannel)
  unit$  = Str (ideUnit)
  
  ; Create (or open existing) key, storing handle...

  If RegOpenKeyEx_ (#HKEY_LOCAL_MACHINE, "HARDWARE\DEVICEMAP\Scsi\Scsi Port " + ide$ + "\Scsi Bus 0\Target Id " + unit$ + "\Logical Unit Id 0", 0, #KEY_ALL_ACCESS, @handle) = #ERROR_SUCCESS

      ; Store size of key value data in 'size' variable...
      
      If RegQueryValueEx_ (handle, "Identifier", #NULL, #NULL, #NULL, @size) = #ERROR_SUCCESS

        ; Allocate memory for the data...
            
        hdstring = AllocateMemory (0, size)
        
        ; Shove the value of given size into the memory block...
        
        If RegQueryValueEx_ (handle, "Identifier", #NULL, #NULL, hdstring, @size) = #ERROR_SUCCESS
        
          ; The value is now in 'data'...
          
          value$ = PeekS (hdstring)
          
          ; Don't need this anymore...
          
          FreeMemory (0)
          
        EndIf

      EndIf
      
      RegCloseKey_ (handle)
    
  EndIf

  If value$ = ""
    value$ = "No such IDE unit!"
  EndIf
  
  ProcedureReturn value$
  
EndProcedure

; Check the average PC's two IDE channels/units...

For ide = 0 To 1
  hd$ + Chr (13) + "IDE Channel " + Str (ide) + Chr (13) + Chr (13)
  For unit = 0 To 1
    hd$ + "Unit " + Str (unit) + ": " + GetDriveManufacturer (ide, unit) + Chr (13)
  Next
Next

MessageRequester ("IDE device information", hd$, #MB_ICONINFORMATION)

Note that I don't yet know of a way to match these units with Windows' drive names, and there may well be PCs out there with different IDE setups, though I've only ever seen this kind (ie. 2 IDE channels, 2 drives on each...


--
See ya,
James L Boyd.
http://www.hi-toro.com/
--

Posted: Sat Dec 07, 2002 5:25 pm
by BackupUser
Restored from previous forum. Originally posted by Hi-Toro.

DOH! That will only work on 2000/XP! The drive info in the Registry will be different in '9x, but you get the idea... :wink:


--
See ya,
James L Boyd.
http://www.hi-toro.com/
--

Posted: Sun Dec 08, 2002 4:31 pm
by BackupUser
Restored from previous forum. Originally posted by Tech-Man.

Thx, yeah i found out the same way with the registry nfo, btw it will work on 9x/me as well :)
i have a check for all the de controllers, i.e "atapi" "aliide" "nvide" etc.. so works on any motherboard.

Posted: Mon Dec 09, 2002 9:11 am
by BackupUser
Restored from previous forum. Originally posted by Insomniac.

There is a sample app in C here using the IOCTL api.

http://support.microsoft.com/default.as ... us;q208048

Found it while looking for info on getting the SMART info from IDE drives.

The sample output shows drive as "Model number: WDC AC22500L".

IOCTL samples in PB would be nice if anyone has any.

Insomniac - Registered PB User

Posted: Mon Dec 09, 2002 8:15 pm
by BackupUser
Restored from previous forum. Originally posted by Hi-Toro.

I tried to use IOCTL a while back, but this test version (only drive 0, possibly Win2000 only, can't remember) fails as I haven't got the DISK_GEOMETRY structure properly defined yet -- the problem is that I can't tell how to define the MEDIA_TYPE structure (see Win32 API docs):

Code: Select all

EDIT: Corrected version further down!


--
See ya,
James L Boyd.
http://www.hi-toro.com/
--

Posted: Mon Dec 09, 2002 10:36 pm
by BackupUser
Restored from previous forum. Originally posted by tinman.
Originally posted by Hi-Toro
Here's the MEDIA_TYPE structure as defined in the API docs -- anyone know how to represent this in PB?

Code: Select all

typedef enum _MEDIA_TYPE {  
    Unknown,                // Format is unknown 
    F5_1Pt2_512,            // 5.25", 1.2MB,  512 bytes/sector 
    F3_1Pt44_512,           // 3.5",  1.44MB, 512 bytes/sector 
    F3_2Pt88_512,           // 3.5",  2.88MB, 512 bytes/sector 
    F3_20Pt8_512,           // 3.5",  20.8MB, 512 bytes/sector 
    F3_720_512,             // 3.5",  720KB,  512 bytes/sector 
    F5_360_512,             // 5.25", 360KB,  512 bytes/sector 
    F5_320_512,             // 5.25", 320KB,  512 bytes/sector 

    F5_320_1024,            // 5.25", 320KB,  1024 bytes/sector 
    F5_180_512,             // 5.25", 180KB,  512 bytes/sector 
    F5_160_512,             // 5.25", 160KB,  512 bytes/sector 
    RemovableMedia,         // Removable media other than floppy 
    FixedMedia              // Fixed hard disk media 
} MEDIA_TYPE; 
This isn't really a type. What is happening is that the compiler will enumerate the names in the list, starting from 0 (or assigning specific values if they are specified) and increasing by 1 each time.

So it is like doing

Code: Select all

    #Unknown = 0;                // Format is unknown 
    #F5_1Pt2_512 = 1;            // 5.25", 1.2MB,  512 bytes/sector 
    #F3_1Pt44_512 = 2;           // 3.5",  1.44MB, 512 bytes/sector 
    #F3_2Pt88_512 = 3;           // 3.5",  2.88MB, 512 bytes/sector
and so on.

The typedef part is something else. It tells the compiler to create a new "type" (it is not really a type though - not in the sense of .b, .w, .myfunkytype, etc) out of the enumerated items. Any variables which have a type of MEDIA_TYPE can only have one of those names assigned to it (the compiler will stop you from assigning "random" values to variables of that type if it is strict enough).



--
It's not minimalist - I'm increasing efficiency by reducing input effort.
(Win98first ed. + SP1, PB3.40)

Posted: Mon Dec 09, 2002 11:12 pm
by BackupUser
Restored from previous forum. Originally posted by Hi-Toro.

Ah, interesting -- and sort of what I thought it was (I know about enum in C, but I've never seen it used like this, and I didn't know it would mean you could limit the values a variable could hold like that) -- this is why I tried to define it as a .l -- any idea how to fix the above? It seems to be because the DISK_GEOMETRY structure is the wrong size, which I think is because of how I've defined MEDIA_TYPE... but I can't find any way to fix it :/


--
See ya,
James L Boyd.
http://www.hi-toro.com/
--

Posted: Mon Dec 09, 2002 11:44 pm
by BackupUser
Restored from previous forum. Originally posted by freak.

The Cylinders.l part is wrong.

typedef struct _DISK_GEOMETRY {
LARGE_INTEGER Cylinders;
MEDIA_TYPE MediaType;
DWORD TracksPerCylinder;
DWORD SectorsPerTrack;
DWORD BytesPerSector;
} DISK_GEOMETRY;

LARGE_INTEGER is a Double Value defined like this:

typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
};
LONGLONG QuadPart;
} LARGE_INTEGER, *PLARGE_INTEGER;


PureBasic knows this Structure, so you just have to write it like this:

Code: Select all

Structure DISK_GEOMETRY
   Cylinders.LARGE_INTEGER
   MediaType.l  ;MEDIA_TYPE
   TracksPerCylinder.l
   SectorsPerTrack.l
   BytesPerSector.l 
EndStructure
Note: All this stuff is not supported by Win9x, only by WinNT/2000/XP

Hope this helps...

Timo

Posted: Mon Dec 09, 2002 11:57 pm
by BackupUser
Restored from previous forum. Originally posted by Hi-Toro.

Ah, good stuff, Timo, thanks a lot! Here's the fixed version for anyone interested (there was a pointer bug too) -- I haven't actually checked that the output is correct yet though :wink:

Code: Select all

Structure DISK_GEOMETRY
   Cylinders.LARGE_INTEGER
   MediaType.l  ;MEDIA_TYPE
   TracksPerCylinder.l
   SectorsPerTrack.l
   BytesPerSector.l 
EndStructure

#IOCTL_DISK_GET_DRIVE_GEOMETRY = $70000

Procedure GetDriveGeometry (*pdg.DISK_GEOMETRY)

  hDevice = CreateFile_ ("\\.\PhysicalDrive0", 0, #FILE_SHARE_READ | #FILE_SHARE_WRITE, #NULL, #OPEN_EXISTING, 0, #NULL)

  If hDevice = #NULL
    ProcedureReturn #FALSE
  EndIf

  fResult = DeviceIoControl_ (hDevice, #IOCTL_DISK_GET_DRIVE_GEOMETRY, #NULL, 0, *pdg, SizeOf (DISK_GEOMETRY), @cb.w, #NULL)

  CloseHandle_ (hDevice)

    ; ***** ERROR!!! *****
    
  If fResult = 0
    ProcedureReturn #FALSE
  EndIf

    ProcedureReturn #TRUE
EndProcedure

DefType.DISK_GEOMETRY drive

OpenConsole ()
  PrintN ("Result: " + Str (GetDriveGeometry (drive)))
  PrintN ("Cylinders: " + Str (drive\Cylinders))
  PrintN (""): Print ("Press ENTER to end..."): Input ()
CloseConsole ()

--
See ya,
James L Boyd.
http://www.hi-toro.com/
--

Posted: Tue Dec 10, 2002 12:05 am
by BackupUser
Restored from previous forum. Originally posted by Hi-Toro.
Note: All this stuff is not supported by Win9x, only by WinNT/2000/XP
Wow, didn't notice that, but sure enough the docs say that DRIVE_GEOMETRY is NT only (even though DeviceIOControl is fine for 9x)! They sure don't like to make things easy... :wink:



--
See ya,
James L Boyd.
http://www.hi-toro.com/
--