retrieve harddisk`s modell,serial,firmware (Windows only)
What about SATA Drives?
And what about SATA (Serial ATA) HardDrives ?
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?
- 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... )
( The path to enlightenment and the PureBasic Survival Guide right here... )
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.
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]
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
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
Dunno what your problem is; I am using only WD drives on XP.Phant0m`` wrote:Are any of the codes posted in this topic more suited for Western Digital's Hard Drives running Windows XP systems?
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
Intel Centrino 1.4 MHz · 1.5 GB RAM · Radeon 9000 Mobility · Win XP Prof/SP2+IE6.0/Firefox · PB 3.94/4.0
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
You mean, you got a partitioned Western Digital hard disk drive and the code stops here:Phant0m`` wrote: I'm thinking maybe this code isn't suited for Partitioned drive split up into two.
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
Intel Centrino 1.4 MHz · 1.5 GB RAM · Radeon 9000 Mobility · Win XP Prof/SP2+IE6.0/Firefox · PB 3.94/4.0
From a bit of browsing the internet, this seems to be the problem then.Phant0m`` wrote:WD in a raid 0 array, :/
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

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
Intel Centrino 1.4 MHz · 1.5 GB RAM · Radeon 9000 Mobility · Win XP Prof/SP2+IE6.0/Firefox · PB 3.94/4.0