retrieve harddisk`s modell,serial,firmware (Windows only)

Share your advanced PureBasic knowledge/code with the community.
dagcrack
Addict
Addict
Posts: 1868
Joined: Sun Mar 07, 2004 8:47 am
Location: Argentina
Contact:

What about SATA Drives?

Post by dagcrack »

And what about SATA (Serial ATA) HardDrives ?
dagcrack
Addict
Addict
Posts: 1868
Joined: Sun Mar 07, 2004 8:47 am
Location: Argentina
Contact:

Post by dagcrack »

What If I have more than 1 harddrive (I do)...
I havent seen the source yet, Im very busy, but I just compiled it very quick and detected the first harddrive only..
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

if you so busy, sit down , take the source, study it.
......after that replace the names of the drives with your own new needed .
SPAMINATOR NR.1
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

If any client installs WMI, no matter what version of Windows they run, the above code should work.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

would make a nice collection... how to identify a machine...

- harddisk serial numbers
- cpu serial numbers
- mac adresses
- bios checksum (can this still be done under nt / xp?)
- ip address (not the most reliable thing)
- what next? :-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Max.²
Enthusiast
Enthusiast
Posts: 175
Joined: Wed Jul 28, 2004 8:38 am

Post by Max.² »

I extended Rings' snippet a bit so it reads also the S.M.A.R.T. data of an harddisk (if the HDD is capable of).

The values are held in two structures.

bAttrValue is the current value of an attribute. Attribute means certain monitoring parameter, like temperature, read errors and such.

bWorstValue is speaking for itself.

bRawValue is the value translated; for example, for Attribute 194 my system reports "104" as current value, "7" as worst (O_o), "0" as threshold and "39" as raw value. The "39" is "39 °C", as we are talking about temperatures.

bWarrantyThreshold is the value defined by the vendor and the actual value should never be below.

Though standardized to a certain amount, SMART is supported differently by vendors sometimes or special attributes are added and such. Also, different revisions of the ATA specification extend the original SMART features.

To confirm the values or get a hint what they mean, go to http://www.passmark.com and download their SMART tool (free for personal use).

This snippet works with NT based systems; to get it to work win Win 98/ME & Co, have a look at one of the previous postings, where SMARTVSD is used instead of PhysicalDrive.

Code: Select all

Structure DRIVEATTRIBUTE
  bAttrID.b
  wStatusFlags.w
  bAttrValue.b
  bWorstValue.b
  bRawValue.b[6]
  bReserved.b
EndStructure

Structure ATTRTHRESHOLD
  bAttrID.b
  bWarrantyThreshold.b
  bReserved.b[10]
EndStructure
Do not copy and paste the structures; they are already in the code below and reason for posting them seperatly is to get you a pointer.

The code below first reads basic harddisk info (as posted with Rings' snippet), the next call fills the ATTRTHRESHOLD structure and the last call fills the DRIVEATTRIBUTE structure.

Feel free to ask. I hope I can answer. ;)

Code: Select all

Structure IDEREGS 
    bFeaturesReg.b 
    bSectorCountReg.b 
    bSectorNumberReg.b 
    bCylLowReg.b 
    bCylHighReg.b 
    bDriveHeadReg.b 
    bCommandReg.b 
    bReserved.b 
EndStructure 
Structure SENDCMDINPARAMS 
    cBufferSize.l 
    irDriveRegs.IDEREGS 
    bDriveNumber.b 
    bReserved.b[3] 
    dwReserved.l[4] 
EndStructure 

Structure  DRIVERSTATUS 
    bDriveError.b 
    bIDEStatus.b 
    bReserved.b[2] 
    dwReserved.l[2] 
EndStructure 
Structure  SENDCMDOUTPARAMS 
    cBufferSize.l 
    DStatus.DRIVERSTATUS      
    bBuffer.b[512] 
EndStructure 

Structure DRIVEATTRIBUTE
  bAttrID.b
  wStatusFlags.w
  bAttrValue.b
  bWorstValue.b
  bRawValue.b[6]
  bReserved.b
EndStructure

Structure ATTRTHRESHOLD
  bAttrID.b
  bWarrantyThreshold.b
  bReserved.b[10]
EndStructure

#DFP_RECEIVE_DRIVE_DATA = $7C088
#DFP_SEND_DRIVE_COMMAND = $7c084
#SMART_ENABLE_SMART_OPERATIONS = $d8
#SMART_CYL_LOW = $4F
#SMART_CYL_HI = $C2
#IDE_EXECUTE_SMART_FUNCTION = $b0
#SMART_READ_ATTRIBUTE_VALUES = $d0
#SMART_READ_ATTRIBUTE_THRESHOLDS = $d1



bin.SENDCMDINPARAMS 
bout.SENDCMDOUTPARAMS 



Procedure.s ChangeHighLowByte(Instring.s) 
;Change BIG-Little Endian 
sdummy.s="" 
L=Len(Instring) 
For I=1 To L Step 2 
If (I+1)<=L 
  sdummy.s=sdummy.s + Mid(Instring,I+1,1)+Mid(Instring,I,1)  
EndIf 
Next I 
ProcedureReturn sdummy.s 
EndProcedure 


mvarCurrentDrive=0 ;If you have more hard-disks change it here 

hdh = CreateFile_("\\.\PhysicalDrive" + Str(mvarCurrentDrive),#GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ | #FILE_SHARE_WRITE,0, #OPEN_EXISTING, 0, 0) 
If hdh  
        bin\bDriveNumber = mvarCurrentDrive 
        bin\cBufferSize = 512 
        
        If (mvarCurrentDrive & 1) 
          bin\irDriveRegs\bDriveHeadReg = $B0 
        Else 
          bin\irDriveRegs\bDriveHeadReg = $A0 
        EndIf 
        bin\irDriveRegs\bCommandReg = $EC 
        bin\irDriveRegs\bSectorCountReg = 1 
        bin\irDriveRegs\bSectorNumberReg = 1 
    
       br=0 
       Result=DeviceIoControl_( hdh, #DFP_RECEIVE_DRIVE_DATA, bin, SizeOf(SENDCMDINPARAMS), bout, SizeOf(SENDCMDOUTPARAMS), @br, 0) 
       If br>0 
        hddfr = 55:hddln = 40          : 
        Modell.s=ChangeHighLowByte(PeekS(@bout\bBuffer[0]+hddfr-1 ,hddln  ) ) 
        hddfr = 21:hddln = 20          : 
        Serial.s=Trim(ChangeHighLowByte(PeekS(@bout\bBuffer[0]+hddfr-1 ,hddln  ) )) 
        hddfr = 47:hddln = 8          
        Firmware.s=ChangeHighLowByte(PeekS(@bout\bBuffer[0]+hddfr-1 ,hddln  ) ) 
        Debug "Model: "+Modell.s 
        Debug "Serial: "+Serial.s
        Debug  "Firmware: "+Firmware.s 
       EndIf 

       bin\irDriveRegs\bFeaturesReg = #SMART_ENABLE_SMART_OPERATIONS
       bin\irDriveRegs\bSectorCountReg = 1
       bin\irDriveRegs\bSectorNumberReg = 1
       bin\irDriveRegs\bCylLowReg = #SMART_CYL_LOW
       bin\irDriveRegs\bCylHighReg = #SMART_CYL_HI
       bin\irDriveRegs\bCommandReg = #IDE_EXECUTE_SMART_FUNCTION
       bin\bDriveNumber = mvarCurrentDrive
       If (mvarCurrentDrive & 1) 
          bin\irDriveRegs\bDriveHeadReg = $B0 
        Else 
          bin\irDriveRegs\bDriveHeadReg = $A0 
       EndIf 
       br=0 
       Result=DeviceIoControl_( hdh, #DFP_SEND_DRIVE_COMMAND, bin, SizeOf(SENDCMDINPARAMS), bout, SizeOf(SENDCMDOUTPARAMS), @br, 0) 
       Debug hdh
       Debug GetLastError_()
       Debug Result
       If br>0 
        Debug "#SMART_ENABLE_SMART_OPERATIONS successful"
       EndIf
       
       bin\irDriveRegs\bFeaturesReg = #SMART_READ_ATTRIBUTE_THRESHOLDS
       br=0 
       Result=DeviceIoControl_( hdh, #DFP_RECEIVE_DRIVE_DATA, bin, SizeOf(SENDCMDINPARAMS), bout, SizeOf(SENDCMDOUTPARAMS), @br, 0) 
       If br>0 
        Debug "#SMART_READ_ATTRIBUTE_THRESHOLDS successful"
        i=0
        *pTA.ATTRTHRESHOLD = @bout\bBuffer[0]+2
        While *pTA\bAttrID & $FF <> 0
          Debug "Attribute "+Str(*pTA\bAttrID & $FF)
          Debug *pTA\bWarrantyThreshold & $FF
          *pTA.ATTRTHRESHOLD = *pTA.ATTRTHRESHOLD + SizeOf(ATTRTHRESHOLD)
        Wend
       EndIf

       
       bin\irDriveRegs\bFeaturesReg = #SMART_READ_ATTRIBUTE_VALUES
       br=0 
       Result=DeviceIoControl_( hdh, #DFP_RECEIVE_DRIVE_DATA, bin, SizeOf(SENDCMDINPARAMS), bout, SizeOf(SENDCMDOUTPARAMS), @br, 0) 
       If br>0 
        Debug "#SMART_READ_ATTRIBUTE_VALUES successful"
        i=0
        *pDA.DRIVEATTRIBUTE = @bout\bBuffer[0]+2
        While *pDA\bAttrID & $FF <> 0
          Debug "Attribute "+Str(*pDA\bAttrID & $FF)
          Debug *pDA\bAttrValue & $FF
          Debug *pDA\bWorstValue & $FF
          Debug (*pDA\bRawValue[0] & $FF) + (*pDA\bRawValue[1] & $FF) * 256
          Debug ""
          *pDA.DRIVEATTRIBUTE = *pDA.DRIVEATTRIBUTE + SizeOf(DRIVEATTRIBUTE)
        Wend
       EndIf

Else 
  Beep_(100,100) 
EndIf 
[/code]
Phant0m``

Post by Phant0m`` »

Are any of the codes posted in this topic more suited for Western Digital's Hard Drives running Windows XP systems?
Max.
Enthusiast
Enthusiast
Posts: 225
Joined: Fri Apr 25, 2003 8:39 pm

Post by Max. »

Phant0m`` wrote:Are any of the codes posted in this topic more suited for Western Digital's Hard Drives running Windows XP systems?
Dunno what your problem is; I am using only WD drives on XP.
Athlon64 3800+ · 1 GB RAM · Radeon X800 XL · Win XP Prof/SP1+IE6.0/Firefox · PB 3.94/4.0
Intel Centrino 1.4 MHz · 1.5 GB RAM · Radeon 9000 Mobility · Win XP Prof/SP2+IE6.0/Firefox · PB 3.94/4.0
Phant0m``

Post by Phant0m`` »

Code: Select all

Structure IDEREGS 
    bFeaturesReg.b 
    bSectorCountReg.b 
    bSectorNumberReg.b 
    bCylLowReg.b 
    bCylHighReg.b 
    bDriveHeadReg.b 
    bCommandReg.b 
    bReserved.b 
EndStructure 
Structure SENDCMDINPARAMS 
    cBufferSize.l 
    irDriveRegs.IDEREGS 
    bDriveNumber.b 
    bReserved.b[3] 
    dwReserved.l[4]
EndStructure 

Structure  DRIVERSTATUS 
    bDriveError.b 
    bIDEStatus.b 
    bReserved.b[2]
    dwReserved.l[2]
EndStructure 
Structure  SENDCMDOUTPARAMS 
    cBufferSize.l 
    DStatus.DRIVERSTATUS      
    bBuffer.b[512]
EndStructure

#DFP_RECEIVE_DRIVE_DATA = $7C088 

bin.SENDCMDINPARAMS 
bout.SENDCMDOUTPARAMS

Procedure.s ChangeHighLowByte(Instring.s) 
sdummy.s="" 
L=Len(Instring) 
For I=1 To L Step 2 
If (I+1)<=L 
  sdummy.s=sdummy.s + Mid(Instring,I+1,1)+Mid(Instring,I,1)  
EndIf 
Next I 
ProcedureReturn sdummy.s 
EndProcedure 

mvarCurrentDrive=0
#VER_PLATFORM_WIN32_WINDOWS=1 
VersionInfo.OSVERSIONINFO 
  
VersionInfo\dwOSVersionInfoSize = SizeOf(OSVERSIONINFO) 
res=GetVersionEx_(VersionInfo) 
If res 
 If VersionInfo\dwPlatformId=#VER_PLATFORM_WIN32_WINDOWS
  hdh=CreateFile_("\\.\SMARTVSD",#GENERIC_READ,#FILE_SHARE_READ,0,#OPEN_EXISTING,0,0)
 Else
  hdh=CreateFile_("\\.\PhysicalDrive"+Str(mvarCurrentDrive),#GENERIC_READ|#GENERIC_WRITE,#FILE_SHARE_READ|#FILE_SHARE_WRITE,0,#OPEN_EXISTING,0,0)  
 EndIf 
EndIf

If hdh
        bin\bDriveNumber=mvarCurrentDrive 
        bin\cBufferSize=512 
        
        If (mvarCurrentDrive & 1) 
          bin\irDriveRegs\bDriveHeadReg=$B0 
        Else 
          bin\irDriveRegs\bDriveHeadReg=$A0 
        EndIf 
        bin\irDriveRegs\bCommandReg=$EC 
        bin\irDriveRegs\bSectorCountReg=1 
        bin\irDriveRegs\bSectorNumberReg=1
    
       br=0 
       Result=DeviceIoControl_(hdh,#DFP_RECEIVE_DRIVE_DATA,bin,SizeOf(SENDCMDINPARAMS),bout,SizeOf(SENDCMDOUTPARAMS),@br,0) 
       If br>0 
        hddfr = 21:hddln = 20
        ;;;For an XP user, especially, this is the spot it 'should' goto.
        Else
        ;;;With one system running WinXP Home and using WD Hard drive, this is where she ends up...
        End
       EndIf
EndIf
I'm thinking maybe this code isn't suited for Partitioned drive split up into two.
Max.
Enthusiast
Enthusiast
Posts: 225
Joined: Fri Apr 25, 2003 8:39 pm

Post by Max. »

Phant0m`` wrote: I'm thinking maybe this code isn't suited for Partitioned drive split up into two.
You mean, you got a partitioned Western Digital hard disk drive and the code stops here:

Code: Select all

        ;;;With one system running WinXP Home and using WD Hard drive, this is where she ends up...
        End
?
Athlon64 3800+ · 1 GB RAM · Radeon X800 XL · Win XP Prof/SP1+IE6.0/Firefox · PB 3.94/4.0
Intel Centrino 1.4 MHz · 1.5 GB RAM · Radeon 9000 Mobility · Win XP Prof/SP2+IE6.0/Firefox · PB 3.94/4.0
Phant0m``

Post by Phant0m`` »

WD in a raid 0 array, :/
Phant0m``

Post by Phant0m`` »

That is correct Max..
Max.
Enthusiast
Enthusiast
Posts: 225
Joined: Fri Apr 25, 2003 8:39 pm

Post by Max. »

Phant0m`` wrote:WD in a raid 0 array, :/
From a bit of browsing the internet, this seems to be the problem then.

I found one hint that you need to use an ASPI driver which is not required for normal operation to get it to work with SCSI and RAID controllers.

Adaptec provides one here:
http://www.adaptec.com/worldwide/suppor ... =ASPI-4.70

I can not try it due to lack of a raid controller (raid-0... shiver... last time I did set up was 10 years ago. Now I am a bit to cowardous for that :wink: ), but if you try it would be nice to get some report.
Athlon64 3800+ · 1 GB RAM · Radeon X800 XL · Win XP Prof/SP1+IE6.0/Firefox · PB 3.94/4.0
Intel Centrino 1.4 MHz · 1.5 GB RAM · Radeon 9000 Mobility · Win XP Prof/SP2+IE6.0/Firefox · PB 3.94/4.0
Phant0m``

Post by Phant0m`` »

Thanks Max.

I'll keep you posted.. :)
Phant0m``

Post by Phant0m`` »

Nope, didn't work.

The system using Promise 2+0 Stripe/RAID0 SCSI Driver
Post Reply