Get detailed hard disk info [updated 28/6/10]
- doctorized
- Addict
- Posts: 882
- Joined: Fri Mar 27, 2009 9:41 am
- Location: Athens, Greece
- doctorized
- Addict
- Posts: 882
- Joined: Fri Mar 27, 2009 9:41 am
- Location: Athens, Greece
Take a look at: http://kc2000labs.110mb.com/pb/zips/4.3 ... o_4.31.zip
I made some improvements (and changed site location, as yahoo geocities is closing).
Does anyone have SSD or Serial attached SCSI (SAS) drive to test my code?
I made some improvements (and changed site location, as yahoo geocities is closing).
Does anyone have SSD or Serial attached SCSI (SAS) drive to test my code?
Re:
I downloaded this and tried it on a machine w/ SCSI. It did not detect my SCSI Jaz drive. It actually showed two of my primary SATA drives instead.doctorized wrote:Take a look at: http://kc2000labs.110mb.com/pb/zips/4.3 ... o_4.31.zip
I made some improvements (and changed site location, as yahoo geocities is closing).
Does anyone have SSD or Serial attached SCSI (SAS) drive to test my code?
I'd like to modify the code so it can detect and report USB connected drives as well. I have a program called HDDScan 3.3 that can read SMART via USB drives. I know not all USB adapters support this, but many do.
Ultimately, I'd like a program that at boot time will check all connected drives for the reallocation parameter. Optionally maybe have it set so it checks every 5-10 minutes after that (command-line parameters) and throws-up a dialog box if a drive is reallocating. Drives that are reallocating may fail soon and it would be nice to have a program to install on machines I build that tells users their drive may be failing and should be replaced sooner rather than later.
I found some C code that uses iodevicecontrol to talk to USB devices, but it will take me FOREVER to port it to PB. I'm just not that good.
If anyone here knows how to do this quickly, I'd appreciate some code. I'll post the source for my completed project, I'm not trying to make money at this, just prevent data loss.
- doctorized
- Addict
- Posts: 882
- Joined: Fri Mar 27, 2009 9:41 am
- Location: Athens, Greece
Re: Re:
Have you tried CrystalDiskInfo? Does it show your SCSI disk?pthien wrote:I downloaded this and tried it on a machine w/ SCSI. It did not detect my SCSI Jaz drive.
Re: Re:
I installed CrystalDiskInfo and it does not even enumerate the Jaz drive. So I ran HDDScan 3.3 and it does enumerate it, but doesn't provide smart data (gives me error when I ask for smart data).doctorized wrote:Have you tried CrystalDiskInfo? Does it show your SCSI disk?pthien wrote:I downloaded this and tried it on a machine w/ SCSI. It did not detect my SCSI Jaz drive.
The CrystalDiskInfo DOES see the USB hard drive, and DOES provide SMART data for it.
I'd really like to have PureBasic code that can provide SMART data for USB devices.
But if you still need someone to test an actual SCSI drive with your code, I can get that done in the next couple of days I'll bet.
Let me know if you need that, I'd be happy to oblige.
- doctorized
- Addict
- Posts: 882
- Joined: Fri Mar 27, 2009 9:41 am
- Location: Athens, Greece
@ pthien: can you run a WMI program to see the DeviceID of the Jaz drive?
You can use mine, from http://kc2000labs.110mb.com/pb/zips/4.3 ... r_4.41.zip and from the alphabetical tab select Win32_DiskDrive.
You can use mine, from http://kc2000labs.110mb.com/pb/zips/4.3 ... r_4.41.zip and from the alphabetical tab select Win32_DiskDrive.
Re: Get detailed hard disk info [updated 28/6/10]
I downloaded and ran your program and yes, that showed the Jaz drive as item #2.
- doctorized
- Addict
- Posts: 882
- Joined: Fri Mar 27, 2009 9:41 am
- Location: Athens, Greece
Re: Get detailed hard disk info [updated 28/6/10]
I didn't mean this. I want you to tell me the 'DeviceID' property. All IDE/SATA drives have a DeviceID '\\.\PHYSICALDRIVEX' where X is a number. Your Jaz drive has the DeviceID: '\\.\PHYSICALDRIVE2' or something else?pthien wrote:I downloaded and ran your program and yes, that showed the Jaz drive as item #2.
Re: Get detailed hard disk info [updated 28/6/10]
OH, sorry. Here is a screenshot...
It is PHYSICALDRIVE1

It is PHYSICALDRIVE1

- freepurebasic
- Enthusiast
- Posts: 123
- Joined: Fri Sep 24, 2010 12:02 pm
- Location: world wide web
Re: Get detailed hard disk info [updated 28/6/10]
i found an error....
my hard disk was appear in the list (the same hard disk) by twice...
so i modified
...
so is workin' fine right now
nice script!
my hard disk was appear in the list (the same hard disk) by twice...
so i modified
Code: Select all
Procedure.l HDDInfo(CurrentDrive.l, SCSIPort.l, SCSITargetID.l)
;DebugMe("Current drive = " + Str(CurrentDrive))
sYesNo.s
If CheckSmartEnabled(CurrentDrive,SCSIPort, SCSITargetID)
;DebugMe("SMART enabled")
dummy.l
If CurrentDrive > 0
Dim bout.b(527)
With bin
\cBufferSize = 512 ;IDENTIFY_BUFFER_SIZE
\irDriveRegs\bFeaturesReg = 0
\irDriveRegs\bSectorCountReg = 1
\irDriveRegs\bSectorNumberReg = 1
\irDriveRegs\bCylLowReg = 0
\irDriveRegs\bCylHighReg = 0
\irDriveRegs\bDriveHeadReg = $A0
;If Not IsWindowsNT Then .bDriveHeadReg = .bDriveHeadReg Or (DriveNum And 1) * 16
\irDriveRegs\bCommandReg = $EC;CByte(IDCmd)
\bDriveNumber = CurrentDrive
EndWith
Result=DeviceIoControl_(hdh, #DFP_RECEIVE_DRIVE_DATA, @bin, SizeOf(SENDCMDINPARAMS), @bout(), 528,@dummy,0)
CopyMemory(@bout(16),@idsec,512)
Else
Dim buffer.b(SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE)
*p.SRB_IO_CONTROL = @buffer()
*pin.SENDCMDINPARAMS = @buffer() + SizeOf(SRB_IO_CONTROL)
*pout.SENDCMDOUTPARAMS = *pin
With *p
\HeaderLength = SizeOf(SRB_IO_CONTROL)
\Timeout = 2
\Length = SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE
\ControlCode = $1B0501
CopyMemory(@"SCSIDISK", @\Signature, 8)
EndWith
With *pin
\irDriveRegs\bCommandReg = $ec;#SMART_CMD
\bDriveNumber = SCSITargetID
EndWith
Result = DeviceIoControl_(hdh, #IOCTL_SCSI_MINIPORT, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDINPARAMS) - 1, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE, @dummy, #Null)
CopyMemory(@buffer() + SizeOf(SRB_IO_CONTROL)+16,@idsec, SizeOf(SENDCMDOUTPARAMS))
EndIf
;DebugMe("DeviceIOControl returned = " + Str(Result) + " (dummy = " + Str(dummy) + ")")
If dummy>0
;GetSMARTVersion()
;For ii.l=16 To 527 Step 16
;For k.l=0 To 15
;;If bout(ii+k)=2: sms.s + "i= " + Str(ii+k) + " / ":EndIf
;sms.s + "i= " + Str(ii+k) + " == " +Hex(Val(StrU(bout(ii+k),#Byte))) + " / ";Chr(bout(ii+k));Hex(Val(StrU(bout(ii+k),#Byte))) + " / "
;Next
;sms + Chr(10)
;Next
;MessageRequester("", sms)
HDDCount + 1
;MessageRequester("SerialAtaFeaturesSupported",Str(idsec\UltraDmaMode))
;MessageRequester("SerialAtaFeaturesed",Str(idsec\PioMode))
aa.DRIVE_LAYOUT_INFORMATION
PartCount.l
DeviceIoControl_(hdh,475148, #Null,0,@aa, SizeOf(DRIVE_LAYOUT_INFORMATION), @BytesRet.l,0)
For i=0 To aa\PartitionCount-1
If aa\PartitionEntry[i]\RecognizedPartition = 1
;Debug aa\PartitionEntry[i]\PartitionLength
;Debug GetPartitionType(aa\PartitionEntry[i]\PartitionType)
PartCount + 1
EndIf
Next
;DebugMe("hdd data")
di(HDDCount)\PartitionCount = Str(PartCount): PartCount = 0
If HDDCount > 1:ReDim di.DriveInfo(HDDCount): EndIf
di(HDDCount)\SerialNumber =Trim(ChangeHighLowByte(PeekS(@idsec\SerialNumber[0],20)))
di(HDDCount)\Model = Trim(ChangeHighLowByte(PeekS(@idsec\ModelNumber[0],40)))
di(HDDCount)\Family = DiskFamily(di(HDDCount)\Model)
di(HDDCount)\FirmWare = Trim(ChangeHighLowByte(PeekS(@idsec\FirmwareRev[0],8)))
di(HDDCount)\BufferSize = Str(idsec\BufferSize / 2) + " KB"; * 512 / 1024 in KBs.
If di(HDDCount)\BufferSize = "0 KB": di(HDDCount)\BufferSize = "Not available": EndIf
di(HDDCount)\ECCBytes = Str(idsec\ECCSize) + " bytes"
di(HDDCount)\LBASectors = FormatByteSize(idsec\MaxUserLBA)
di(HDDCount)\CurTransferMode = CurrentTransferMode()
di(HDDCount)\MaxTransferMode = MaximumTransferMode()
If idsec\SerialAtaCapabilities <>0 And SerialAtaCapabilities <> $FFFF
di(HDDCount)\InterfaceType = "Serial ATA"
Else
di(HDDCount)\InterfaceType = "Parallel ATA"
EndIf
di(HDDCount)\Standard = GetATAMajorVersion() + " ( " + GetATAMinorVersion() + " )"
If idsec\MaxUserLBA > 0
di(HDDCount)\TheoriticalCapacity = c2str(idsec\MaxUserLba * 512 / 1000000000,2) + " GB"
di(HDDCount)\RealCapacity = c2str(idsec\MaxUserLba * 512 / (1024*1024*1024),2) + " GB"
ElseIf idsec\TotalAddressableSectors > 0
di(HDDCount)\TheoriticalCapacity = c2str(idsec\TotalAddressableSectors * 512 / 1000000000,2) + " GB"
di(HDDCount)\RealCapacity = c2str(idsec\TotalAddressableSectors * 512 / (1024*1024*1024),2) + " GB"
Else
di(HDDCount)\TheoriticalCapacity = "Not Available"
di(HDDCount)\RealCapacity = "Not Available"
EndIf
;FLAGS
; word 82
;DebugMe("Entering hdd flags")
If ATAVersion >= 3 And idsec\CommandSetSupported1 & 1
di(HDDCount)\Flags\SMART = "YES"
If idsec\CommandSetEnabled1 & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\SMART + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\SMART = "NO"
EndIf
;security mode ataversion ?
If ATAVersion >= 5 And (idsec\CommandSetSupported1 >> 1) & 1
di(HDDCount)\Flags\SecMode = "YES"
If (idsec\CommandSetEnabled1 >> 1) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\SecMode + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\SecMode = "NO"
EndIf
;power management ataversion ?
If ATAVersion >= 5 And (idsec\CommandSetSupported1 >> 3) & 1
di(HDDCount)\Flags\PM = "YES"
If (idsec\CommandSetEnabled1 >> 3) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\PM + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\PM = "NO"
EndIf
;WORD 83
;DOWNLOAD MICROCODE.
If idsec\CommandSetSupported2 & 1
di(HDDCount)\Flags\DMicro = "YES"
If idsec\CommandSetEnabled2 & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\DMicro + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\DMicro = "NO"
EndIf
;TCQ
If ATAVersion >= 5 And (idsec\CommandSetSupported2 >> 1) & 1 And (idsec\CommandSetSupported2 >> 14) & 1 And (idsec\CommandSetSupported2 >> 15) & 1 = 0
di(HDDCount)\Flags\TCQ = "YES"
tmi = (idsec\CommandSetEnabled2 >> 1) & 1
di(HDDCount)\Flags\TCQ + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\TCQ = "NO"
EndIf
;CFA
If (idsec\CfaPowerMode1 >> 12) & 1 = 1 Or (idsec\CommandSetSupported2 >> 2) & 1 = 1
di(HDDCount)\Flags\CFA = "YES"
Else
di(HDDCount)\Flags\CFA = "NO"
EndIf
If (idsec\CfaPowerMode1 >> 13) & 1 = 1
di(HDDCount)\Flags\CFA + " , " + "Required : " + "YES"
Else
di(HDDCount)\Flags\CFA + " , " + "Required : " + "NO"
EndIf
;APM
If ATAVersion >= 3 And (idsec\CommandSetSupported2 >> 3) & 1
di(HDDCount)\Flags\APM = "YES"
If (idsec\CommandSetEnabled2 >> 3) & 1 = 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\APM + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\APM = "NO"
EndIf
;PUIS
If ATAVersion >= 3 And (idsec\CommandSetSupported2 >> 5) & 1
di(HDDCount)\Flags\PUIS = "YES"
If (idsec\CommandSetEnabled2 >> 5) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\PUIS + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\PUIS = "NO"
EndIf
;AAM
If ATAVersion >= 5 And (idsec\CommandSetSupported2 >> 9) & 1
di(HDDCount)\Flags\AAM = "YES"
If (idsec\CommandSetEnabled2 >> 9) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\AAM + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\AAM = "NO"
EndIf
;48bit LBA
If ATAVersion >= 5 And (idsec\CommandSetSupported2 >> 10) & 1
di(HDDCount)\Flags\LBA48 = "YES"
If (idsec\CommandSetEnabled2 >> 10) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\LBA48 + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\LBA48 = "NO"
EndIf
;DCO
If ATAVersion >= 6 And (idsec\CommandSetSupported2 >> 11) & 1
di(HDDCount)\Flags\DCO = "YES"
If (idsec\CommandSetEnabled2 >> 11) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\DCO + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\DCO = "NO"
EndIf
;MessageRequester("pio",StrU(idsec\CommandSetSupported2,#PB_Long))
;SCT
If ATAVersion >= 8 And idsec\SctCommandTransport & 1
di(HDDCount)\Flags\SCT = "YES"
Else
di(HDDCount)\Flags\SCT = "NO"
EndIf
;PIO
If (idsec\Field88and7064 >> 1) & 1 = 1;means words 64-70 are valid.
If idsec\PioMode & 1 = 1: di(HDDCount)\Flags\PIO = "Mode 3": EndIf
If (idsec\PioMode >> 1) & 1 = 1: di(HDDCount)\Flags\PIO = "Mode 4": EndIf
Else
di(HDDCount)\Flags\PIO = "Not Available"
EndIf
;UDMA
Dim dmamode.s(6)
dmamode(0) = " (ATA 16)"
dmamode(1) = " (ATA 25)"
dmamode(2) = " (ATA 33)"
dmamode(3) = " (ATA 44)"
dmamode(4) = " (ATA 66)"
dmamode(5) = " (ATA 100)"
dmamode(6) = " (ATA 133)"
For i = 6 To 0 Step -1
If (idsec\UltraDmaMode >> i) & 1 = 1
di(HDDCount)\Flags\UDMA = "Max Supported" + Str(i) + dmamode(i)
Break
EndIf
Next
For i = 14 To 8 Step -1
If (idsec\UltraDmaMode >> i) & 1 = 1
di(HDDCount)\Flags\UDMA + " , " + "Current Enabled" + Str(i-8) + dmamode(i-8)
Break
EndIf
Next
;multi word dma
If idsec\MultiWordDma & 3 = 0
di(HDDCount)\Flags\MWDMA = "Not Supported"
Else
If idsec\MultiWordDma & 1 = 1: di(HDDCount)\Flags\MWDMA = "Supported : " + "Mode 0": EndIf
If (idsec\MultiWordDma >> 1) & 1 = 1: di(HDDCount)\Flags\MWDMA = "Supported : " + "Mode 1": EndIf
If (idsec\MultiWordDma >> 2) & 1 = 1: di(HDDCount)\Flags\MWDMA = "Supported : " + "Mode 2": EndIf
If (idsec\MultiWordDma >> 8) & 1 = 1: di(HDDCount)\Flags\MWDMA + " , " + "Supported : " + "Mode 0": EndIf
If (idsec\MultiWordDma >> 9) & 1 = 1: di(HDDCount)\Flags\MWDMA + " , " + "Supported : " + "Mode 1": EndIf
If (idsec\MultiWordDma >> 10) & 1 = 1: di(HDDCount)\Flags\MWDMA + " , " + "Supported : " + "Mode 2": EndIf
EndIf
;IORDY
If (idsec\Capabilities1 >> 11) & 1 = 1
di(HDDCount)\Flags\IORDY = "YES"
Else
di(HDDCount)\Flags\IORDY = "NO"
EndIf
;Native Command Queuing
If ATAVersion >= 6 And (idsec\SerialAtaCapabilities >> 8) & 1
di(HDDCount)\Flags\NCQ = "YES"
Else
di(HDDCount)\Flags\NCQ = "NO"
EndIf
;NV Cache
If ATAVersion >= 7 And idsec\NvCacheCapabilities & 1
di(HDDCount)\Flags\NVCache = "YES"
Else
di(HDDCount)\Flags\NVCache = "NO"
EndIf
;TRIM
If ATAVersion >= 7 And idsec\DataSetManagement & 1
di(HDDCount)\Flags\TRIM = "YES"
Else
di(HDDCount)\Flags\TRIM = "NO"
EndIf
;rotation rate
If ATAVersion >=7 And idsec\NominalMediaRotationRate > 1000 And idsec\NominalMediaRotationRate < $FFFF
di(HDDCount)\RotationRate = StrU(idsec\NominalMediaRotationRate,#PB_Word) + " RPM"
EndIf
;SSD
If ATAVersion>=7 And idsec\NominalMediaRotationRate = 1
di(HDDCount)\Flags\SSD = "YES"
Else
di(HDDCount)\Flags\SSD = "NO"
EndIf
;DebugMe("Reading Attributes")
ReadAttributes(CurrentDrive, SCSITargetID)
;DebugMe("Reading Thresholds")
ReadThresholds(CurrentDrive, SCSITargetID)
If di(HDDCount)\Temperature = "": di(HDDCount)\Temperature = "Not Available": EndIf
di(HDDCount)\DiskStatus = DiskStatus()
;DebugMe("1 will be returned")
ProcedureReturn 1
Else
;DebugMe("2 will be returned")
ProcedureReturn 0
EndIf
Else
;DebugMe("3 will be returned")
ProcedureReturn 0
EndIf
;DebugMe("10 will be returned")
EndProcedure
...
Code: Select all
751: If CurrentDrive > 0
nice script!
- doctorized
- Addict
- Posts: 882
- Joined: Fri Mar 27, 2009 9:41 am
- Location: Athens, Greece
Re: Get detailed hard disk info [updated 28/6/10]
You are wrong. The command MUST remain "If CurrentDrive >= 0", because otherwise we are missingfreepurebasic wrote:so is workin' fine right nowCode: Select all
751: If CurrentDrive > 0
drive #0. Test the code to a computer with two or more drives to check it out.
I tested it to my computer and the code refers only the second and the third drive, not the fisrt one,
and it is reasonable if you think that drive enumeration begins with "\\.\PhysicalDrive0" and not
"\\.\PhysicalDrive1" to use only "> 0", so ">= 0" is absolutely needed.
That means something else is going on with your computer. (RAID? Windows sucks?)
Re: Get detailed hard disk info [updated 28/6/10]
It shows my IDE drive twice as well, though.doctorized wrote:You are wrong. The command MUST remain "If CurrentDrive >= 0", because otherwise we are missingfreepurebasic wrote:so is workin' fine right nowCode: Select all
751: If CurrentDrive > 0
drive #0. Test the code to a computer with two or more drives to check it out.
I tested it to my computer and the code refers only the second and the third drive, not the fisrt one,
and it is reasonable if you think that drive enumeration begins with "\\.\PhysicalDrive0" and not
"\\.\PhysicalDrive1" to use only "> 0", so ">= 0" is absolutely needed.
That means something else is going on with your computer. (RAID? Windows sucks?)
- doctorized
- Addict
- Posts: 882
- Joined: Fri Mar 27, 2009 9:41 am
- Location: Athens, Greece
Re: Get detailed hard disk info [updated 28/6/10]
Can you send me an image of the debug window?pthien wrote:It shows my IDE drive twice as well, though.
Replace HDDInfo procedure with this:
Code: Select all
Procedure.l HDDInfo(CurrentDrive.l, SCSIPort.l, SCSITargetID.l)
;DebugMe("Current drive = " + Str(CurrentDrive))
sYesNo.s
OpenSmart(CurrentDrive, SCSIPort)
Debug hdh
;IF CheckSmartEnabled(CurrentDrive,SCSIPort, SCSITargetID)
;DebugMe("SMART enabled")
dummy.l
If CurrentDrive >= 0
Dim bout.b(527)
With bin
\cBufferSize = 512 ;IDENTIFY_BUFFER_SIZE
\irDriveRegs\bFeaturesReg = 0
\irDriveRegs\bSectorCountReg = 1
\irDriveRegs\bSectorNumberReg = 1
\irDriveRegs\bCylLowReg = 0
\irDriveRegs\bCylHighReg = 0
\irDriveRegs\bDriveHeadReg = $A0
;If Not IsWindowsNT Then .bDriveHeadReg = .bDriveHeadReg Or (DriveNum And 1) * 16
\irDriveRegs\bCommandReg = $EC;CByte(IDCmd)
\bDriveNumber = CurrentDrive
EndWith
Result=DeviceIoControl_(hdh, #DFP_RECEIVE_DRIVE_DATA, @bin, SizeOf(SENDCMDINPARAMS), @bout(), 528,@dummy,0)
CopyMemory(@bout(16),@idsec,512)
Else
Dim buffer.b(SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE)
*p.SRB_IO_CONTROL = @buffer()
*pin.SENDCMDINPARAMS = @buffer() + SizeOf(SRB_IO_CONTROL)
*pout.SENDCMDOUTPARAMS = *pin
With *p
\HeaderLength = SizeOf(SRB_IO_CONTROL)
\Timeout = 2
\Length = SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE
\ControlCode = $1B0501
CopyMemory(@"SCSIDISK", @\Signature, 8)
EndWith
With *pin
\irDriveRegs\bCommandReg = $ec;#SMART_CMD
\bDriveNumber = SCSITargetID
EndWith
Result = DeviceIoControl_(hdh, #IOCTL_SCSI_MINIPORT, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDINPARAMS) - 1, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE, @dummy, #Null)
CopyMemory(@buffer() + SizeOf(SRB_IO_CONTROL)+16,@idsec, SizeOf(SENDCMDOUTPARAMS))
EndIf
;DebugMe("DeviceIOControl returned = " + Str(Result) + " (dummy = " + Str(dummy) + ")")
Debug "DeviceIOControl returned = " + Str(Result) + " (dummy = " + Str(dummy) + ")"
If dummy>0
;GetSMARTVersion()
;For ii.l=16 To 527 Step 16
;For k.l=0 To 15
;;If bout(ii+k)=2: sms.s + "i= " + Str(ii+k) + " / ":EndIf
;sms.s + "i= " + Str(ii+k) + " == " +Hex(Val(StrU(bout(ii+k),#Byte))) + " / ";Chr(bout(ii+k));Hex(Val(StrU(bout(ii+k),#Byte))) + " / "
;Next
;sms + Chr(10)
;Next
;MessageRequester("", sms)
HDDCount + 1
;MessageRequester("SerialAtaFeaturesSupported",Str(idsec\UltraDmaMode))
;MessageRequester("SerialAtaFeaturesed",Str(idsec\PioMode))
aa.DRIVE_LAYOUT_INFORMATION
PartCount.l
DeviceIoControl_(hdh,475148, #Null,0,@aa, SizeOf(DRIVE_LAYOUT_INFORMATION), @BytesRet.l,0)
For i=0 To aa\PartitionCount-1
If aa\PartitionEntry[i]\RecognizedPartition = 1
;Debug aa\PartitionEntry[i]\PartitionLength
;Debug GetPartitionType(aa\PartitionEntry[i]\PartitionType)
PartCount + 1
EndIf
Next
;DebugMe("hdd data")
If HDDCount > 1: ReDim di.DriveInfo(HDDCount): EndIf
di(HDDCount)\PartitionCount = Str(PartCount): PartCount = 0
di(HDDCount)\SerialNumber =Trim(ChangeHighLowByte(PeekS(@idsec\SerialNumber[0],20)))
di(HDDCount)\Model = Trim(ChangeHighLowByte(PeekS(@idsec\ModelNumber[0],40)))
di(HDDCount)\Family = DiskFamily(di(HDDCount)\Model)
di(HDDCount)\FirmWare = Trim(ChangeHighLowByte(PeekS(@idsec\FirmwareRev[0],8)))
di(HDDCount)\BufferSize = Str(idsec\BufferSize / 2) + " KB"; * 512 / 1024 in KBs.
If di(HDDCount)\BufferSize = "0 KB": di(HDDCount)\BufferSize = "Not available": EndIf
di(HDDCount)\ECCBytes = Str(idsec\ECCSize) + " bytes"
di(HDDCount)\LBASectors = FormatByteSize(idsec\MaxUserLBA)
di(HDDCount)\CurTransferMode = CurrentTransferMode()
di(HDDCount)\MaxTransferMode = MaximumTransferMode()
If idsec\SerialAtaCapabilities <>0 And SerialAtaCapabilities <> $FFFF
di(HDDCount)\InterfaceType = "Serial ATA"
Else
di(HDDCount)\InterfaceType = "Parallel ATA"
EndIf
di(HDDCount)\Standard = GetATAMajorVersion() + " ( " + GetATAMinorVersion() + " )"
If idsec\MaxUserLBA > 0
di(HDDCount)\TheoriticalCapacity = c2str(idsec\MaxUserLba * 512 / 1000000000,2) + " GB"
di(HDDCount)\RealCapacity = c2str(idsec\MaxUserLba * 512 / (1024*1024*1024),2) + " GB"
ElseIf idsec\TotalAddressableSectors > 0
di(HDDCount)\TheoriticalCapacity = c2str(idsec\TotalAddressableSectors * 512 / 1000000000,2) + " GB"
di(HDDCount)\RealCapacity = c2str(idsec\TotalAddressableSectors * 512 / (1024*1024*1024),2) + " GB"
Else
di(HDDCount)\TheoriticalCapacity = "Not Available"
di(HDDCount)\RealCapacity = "Not Available"
EndIf
;FLAGS
; word 82
;DebugMe("Entering hdd flags")
If ATAVersion >= 3 And idsec\CommandSetSupported1 & 1
di(HDDCount)\Flags\SMART = "YES"
If idsec\CommandSetEnabled1 & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\SMART + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\SMART = "NO"
EndIf
;security mode ataversion ?
If ATAVersion >= 5 And (idsec\CommandSetSupported1 >> 1) & 1
di(HDDCount)\Flags\SecMode = "YES"
If (idsec\CommandSetEnabled1 >> 1) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\SecMode + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\SecMode = "NO"
EndIf
;power management ataversion ?
If ATAVersion >= 5 And (idsec\CommandSetSupported1 >> 3) & 1
di(HDDCount)\Flags\PM = "YES"
If (idsec\CommandSetEnabled1 >> 3) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\PM + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\PM = "NO"
EndIf
;WORD 83
;DOWNLOAD MICROCODE.
If idsec\CommandSetSupported2 & 1
di(HDDCount)\Flags\DMicro = "YES"
If idsec\CommandSetEnabled2 & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\DMicro + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\DMicro = "NO"
EndIf
;TCQ
If ATAVersion >= 5 And (idsec\CommandSetSupported2 >> 1) & 1 And (idsec\CommandSetSupported2 >> 14) & 1 And (idsec\CommandSetSupported2 >> 15) & 1 = 0
di(HDDCount)\Flags\TCQ = "YES"
tmi = (idsec\CommandSetEnabled2 >> 1) & 1
di(HDDCount)\Flags\TCQ + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\TCQ = "NO"
EndIf
;CFA
If (idsec\CfaPowerMode1 >> 12) & 1 = 1 Or (idsec\CommandSetSupported2 >> 2) & 1 = 1
di(HDDCount)\Flags\CFA = "YES"
Else
di(HDDCount)\Flags\CFA = "NO"
EndIf
If (idsec\CfaPowerMode1 >> 13) & 1 = 1
di(HDDCount)\Flags\CFA + " , " + "Required : " + "YES"
Else
di(HDDCount)\Flags\CFA + " , " + "Required : " + "NO"
EndIf
;APM
If ATAVersion >= 3 And (idsec\CommandSetSupported2 >> 3) & 1
di(HDDCount)\Flags\APM = "YES"
If (idsec\CommandSetEnabled2 >> 3) & 1 = 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\APM + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\APM = "NO"
EndIf
;PUIS
If ATAVersion >= 3 And (idsec\CommandSetSupported2 >> 5) & 1
di(HDDCount)\Flags\PUIS = "YES"
If (idsec\CommandSetEnabled2 >> 5) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\PUIS + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\PUIS = "NO"
EndIf
;AAM
If ATAVersion >= 5 And (idsec\CommandSetSupported2 >> 9) & 1
di(HDDCount)\Flags\AAM = "YES"
If (idsec\CommandSetEnabled2 >> 9) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\AAM + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\AAM = "NO"
EndIf
;48bit LBA
If ATAVersion >= 5 And (idsec\CommandSetSupported2 >> 10) & 1
di(HDDCount)\Flags\LBA48 = "YES"
If (idsec\CommandSetEnabled2 >> 10) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\LBA48 + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\LBA48 = "NO"
EndIf
;DCO
If ATAVersion >= 6 And (idsec\CommandSetSupported2 >> 11) & 1
di(HDDCount)\Flags\DCO = "YES"
If (idsec\CommandSetEnabled2 >> 11) & 1
sYesNo = "YES"
Else
sYesNo = "NO"
EndIf
di(HDDCount)\Flags\DCO + " ( " + "Enabled : " + sYesNo + " )"
Else
di(HDDCount)\Flags\DCO = "NO"
EndIf
;MessageRequester("pio",StrU(idsec\CommandSetSupported2,#PB_Long))
;SCT
If ATAVersion >= 8 And idsec\SctCommandTransport & 1
di(HDDCount)\Flags\SCT = "YES"
Else
di(HDDCount)\Flags\SCT = "NO"
EndIf
;PIO
If (idsec\Field88and7064 >> 1) & 1 = 1;means words 64-70 are valid.
If idsec\PioMode & 1 = 1: di(HDDCount)\Flags\PIO = "Mode 3": EndIf
If (idsec\PioMode >> 1) & 1 = 1: di(HDDCount)\Flags\PIO = "Mode 4": EndIf
Else
di(HDDCount)\Flags\PIO = "Not Available"
EndIf
;UDMA
Dim dmamode.s(6)
dmamode(0) = " (ATA 16)"
dmamode(1) = " (ATA 25)"
dmamode(2) = " (ATA 33)"
dmamode(3) = " (ATA 44)"
dmamode(4) = " (ATA 66)"
dmamode(5) = " (ATA 100)"
dmamode(6) = " (ATA 133)"
For i = 6 To 0 Step -1
If (idsec\UltraDmaMode >> i) & 1 = 1
di(HDDCount)\Flags\UDMA = "Max Supported" + Str(i) + dmamode(i)
Break
EndIf
Next
For i = 14 To 8 Step -1
If (idsec\UltraDmaMode >> i) & 1 = 1
di(HDDCount)\Flags\UDMA + " , " + "Current Enabled" + Str(i-8) + dmamode(i-8)
Break
EndIf
Next
;multi word dma
If idsec\MultiWordDma & 3 = 0
di(HDDCount)\Flags\MWDMA = "Not Supported"
Else
If idsec\MultiWordDma & 1 = 1: di(HDDCount)\Flags\MWDMA = "Supported : " + "Mode 0": EndIf
If (idsec\MultiWordDma >> 1) & 1 = 1: di(HDDCount)\Flags\MWDMA = "Supported : " + "Mode 1": EndIf
If (idsec\MultiWordDma >> 2) & 1 = 1: di(HDDCount)\Flags\MWDMA = "Supported : " + "Mode 2": EndIf
If (idsec\MultiWordDma >> 8) & 1 = 1: di(HDDCount)\Flags\MWDMA + " , " + "Supported : " + "Mode 0": EndIf
If (idsec\MultiWordDma >> 9) & 1 = 1: di(HDDCount)\Flags\MWDMA + " , " + "Supported : " + "Mode 1": EndIf
If (idsec\MultiWordDma >> 10) & 1 = 1: di(HDDCount)\Flags\MWDMA + " , " + "Supported : " + "Mode 2": EndIf
EndIf
;IORDY
If (idsec\Capabilities1 >> 11) & 1 = 1
di(HDDCount)\Flags\IORDY = "YES"
Else
di(HDDCount)\Flags\IORDY = "NO"
EndIf
;Native Command Queuing
If ATAVersion >= 6 And (idsec\SerialAtaCapabilities >> 8) & 1
di(HDDCount)\Flags\NCQ = "YES"
Else
di(HDDCount)\Flags\NCQ = "NO"
EndIf
;NV Cache
If ATAVersion >= 7 And idsec\NvCacheCapabilities & 1
di(HDDCount)\Flags\NVCache = "YES"
Else
di(HDDCount)\Flags\NVCache = "NO"
EndIf
;TRIM
If ATAVersion >= 7 And idsec\DataSetManagement & 1
di(HDDCount)\Flags\TRIM = "YES"
Else
di(HDDCount)\Flags\TRIM = "NO"
EndIf
;rotation rate
If ATAVersion >=7 And idsec\NominalMediaRotationRate > 1000 And idsec\NominalMediaRotationRate < $FFFF
di(HDDCount)\RotationRate = StrU(idsec\NominalMediaRotationRate,#PB_Word) + " RPM"
EndIf
;SSD
If ATAVersion>=7 And idsec\NominalMediaRotationRate = 1
di(HDDCount)\Flags\SSD = "YES"
Else
di(HDDCount)\Flags\SSD = "NO"
EndIf
;DebugMe("Reading Attributes")
If CheckSmartEnabled(CurrentDrive,SCSIPort, SCSITargetID)
ReadAttributes(CurrentDrive, SCSITargetID)
;DebugMe("Reading Thresholds")
ReadThresholds(CurrentDrive, SCSITargetID)
If di(HDDCount)\Temperature = "": di(HDDCount)\Temperature = "Not Available": EndIf
di(HDDCount)\DiskStatus = DiskStatus()
EndIf
;DebugMe("1 will be returned")
ProcedureReturn 1
Else
;DebugMe("2 will be returned")
ProcedureReturn 0
EndIf
;Else
; ;DebugMe("3 will be returned")
; ProcedureReturn 0
;EndIf
;DebugMe("10 will be returned")
EndProcedure
Re: Get detailed hard disk info [updated 28/6/10]
How [or can you] can I modify to work in unicode ... pls !!!