Page 1 of 2

retrieve disk`s model,serial,type

Posted: Tue Feb 27, 2007 1:04 pm
by Rings
according to this tip (i posted in mid 2003 ),
http://www.purebasic.fr/english/viewtop ... 99&start=0 ,
here is another method to find more infos about your devices(Disk's).
Works only Win2k, XP and Vista , also in Usermode (no admin rights).

Code: Select all

Structure STORAGE_PROPERTY_QUERY
    PropertyId.l;STORAGE_PROPERTY_ID
    QueryType.l;STORAGE_QUERY_TYPE
    AdditionalParameters.l
EndStructure

Structure STORAGE_DEVICE_DESCRIPTOR
    Version.l
    Size.l;                                    As Long
    DeviceType.b;                              As Byte
    DeviceTypeModifier.b;                      As Byte
    RemovableMedia.b;                          As Byte
    CommandQueueing.b;                         As Byte
    VendorIdOffset.l;                          As Long
    ProductIdOffset.l;                         As Long
    ProductRevisionOffset.l;                   As Long
    SerialNumberOffset.l;                      As Long
    BusType.w;                                 As Integer
    RawPropertiesLength.l;                     As Long
    RawDeviceProperties.b;                     As Byte
    Reserved.b[1024]
EndStructure

    #BusTypeUnknown = 0
    #BusTypeScsi=1
    #BusTypeAtapi=2
    #BusTypeAta=3
    #BusType1394=4
    #BusTypeSsa=5
    #BusTypeFibre=6
    #BusTypeUsb=7
    #BusTypeRAID=8
    #BusTypeMaxReserved = $7F
    
#IOCTL_STORAGE_QUERY_PROPERTY  = $2D1400



Procedure.l Hex2Dec(h$)
  h$=UCase(h$)
  For r=1 To Len(h$)
    d<<4 : a$=Mid(h$,r,1)
    If Asc(a$)>60
      d+Asc(a$)-55
    Else
      d+Asc(a$)-48
    EndIf
  Next
  ProcedureReturn d
EndProcedure 

OpenConsole()
 PrintN("Enumerate devices")

 For Drives=1 To 26
 
  strDrive.s="\\.\" + Chr(64+Drives) + ":"
  
  hDrive = CreateFile_(strDrive, 0,#FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0)
  If hDrive<>-1
  
   PrintN("--------------------------------------------------")

   udtQuery.STORAGE_PROPERTY_QUERY
   udtOut.STORAGE_DEVICE_DESCRIPTOR
   ;clear advanced Info....
   For p=0 To 1023
    udtOut\Reserved[p]=0
   Next p 
   lngResult = DeviceIoControl_(hDrive, #IOCTL_STORAGE_QUERY_PROPERTY, udtQuery,SizeOf(udtQuery), @udtOut, SizeOf(udtout), @dwOutBytes, 0)
   If lngResult 
    PrintN("Drive " + Chr(64+Drives) + ": is a ")
    Select(udtOut\Bustype) 
     Case     #BusTypeUnknown 
     Case #BusTypeScsi
      PrintN(" SCSI Device")
     Case #BusTypeAtapi
      PrintN(" Atapi Device")
     Case #BusTypeAta
      PrintN(" Ata Device")
     Case #BusType1394
     Case #BusTypeSsa
     Case #BusTypeFibre
     Case #BusTypeUsb
      PrintN(" USB Device")
     Case #BusTypeRAID
     Case #BusTypeMaxReserved 
     Default
     PrintN("Bustype=" + Str(udtOut\BusType))
    EndSelect

    If udtout\RemovableMedia
     PrintN("Device is Removable Media")
    EndIf

    If udtOut\ProductIdOffset > 0
     PrintN("ProductID=" + PeekS(@udtOut + udtOut\ProductIdOffset))
    EndIf

    If udtOut\ProductRevisionOffset > 0
     PrintN("ProductRevision=" + PeekS(@udtOut +  udtOut\ProductRevisionOffset))
    EndIf

    If udtOut\VendorIdOffset  > 0
     PrintN("VendorID=" + PeekS(@udtOut +  udtOut\VendorIdOffset ))
    EndIf

    If udtOut\SerialNumberOffset  > 0
     SerialNumber.s=PeekS(@udtOut +  udtOut\SerialNumberOffset )
     ;Now convert into readable format, coz its encrypted in HEX-Ascii
     sdummy.s=""
     For t=1 To Len(SerialNumber) Step 2
        sdummy + Chr(Hex2Dec(Mid(SerialNumber,t,2)))
     Next t 
     PrintN("SerialNumber=" + sdummy)
    EndIf
     
   Else
    PrintN("No Device-IO info available.. for "+Chr(64+Drives) + ":")

   EndIf
  EndIf
  CloseHandle_(hDrive)


 Next Drives
 
wait.s=Input()
CloseConsole()

Posted: Tue Feb 27, 2007 1:18 pm
by gnozal
Windows NT4 sp 6 :

Code: Select all

Enumerate devices
--------------------------------------------------
No Device-IO info available.. for A:
--------------------------------------------------
No Device-IO info available.. for C:
--------------------------------------------------
No Device-IO info available.. for D:
--------------------------------------------------
No Device-IO info available.. for E:
Windows 98 :

Code: Select all

Enumerate devices
Windows XP

Code: Select all

Enumerate devices
--------------------------------------------------
Drive C: is a
 Ata Device
ProductID=SAMSUNG HD080HJ/P
ProductRevision=ZH100-34
SerialNumber=
--------------------------------------------------
Drive D: is a
 Ata Device
ProductID=SAMSUNG HD080HJ/P
ProductRevision=ZH100-34
SerialNumber=
--------------------------------------------------
Drive E: is a
 Atapi Device
Device is Removable Media
ProductID=HL-DT-ST CDRW/DVD GCCH10N
ProductRevision=C101
SerialNumber=

Re: retrieve disk`s model,serial,type

Posted: Tue Feb 27, 2007 1:23 pm
by Derek
Tested under xp and it found all my drives and also all the usb readers as well.

Posted: Tue Feb 27, 2007 5:52 pm
by Rook Zimbabwe
@Gnozal: Did you dlete the serial numbers or it just no find them?

Posted: Wed Feb 28, 2007 8:53 am
by gnozal
Rook Zimbabwe wrote:@Gnozal: Did you dlete the serial numbers or it just no find them?
It's a PC at work, I did not delete anything.

Posted: Wed Feb 28, 2007 9:15 am
by Rings
thx for testing, i updated the description below.

Posted: Wed May 02, 2007 9:09 pm
by Straker
Thanks for the code Rings - it works great! Except that the serial number is a little jumbled.

Your code returns my Western Digital HD serial number as:

DWW-AMC85220371

But the real serial number is:

WD-WMA8C2502731

The code is transposing every other character. I tested this on XP and W2K using both PB 3.94 and PB 4.0 with the same results.

I was too lazy to find the issue in the code, so I just wrote a function to fix the returned serial number:

Code: Select all

Procedure.s FixSn(pSn.s)
  lRetVal.s = ""
  lHold2.s = ""
  lLen.l = Len(pSn.s)
  If ( lLen.l > 0 )
    For lLoop.l = 1 To lLen.l Step 2
      lHold2.s = Mid(pSn.s,lLoop.l,2)
      lRetVal.s = lRetVal.s + Mid(lHold2.s,2,1) + Mid(lHold2,1,1)
    Next
  EndIf
  ProcedureReturn lRetVal.s
EndProcedure
BTW - this also seems to return the correct 15-char serial number instead of the 14-char problem mentioned in this thread.

Has anyone tested this on Vista using a restricted rights user?

Posted: Wed May 02, 2007 9:23 pm
by SFSxOI
works fine here on Vista. Finds all drives including DVD R/W drive and external USB drive. Thank You :)

Posted: Tue Dec 11, 2007 12:36 pm
by Thunder93
Hi,

Nice coding, it's a shame there's some kinks existing in that though..

- Doesn't seem to extract serial on all types of drives, or at least locate serial on SAMSUNG drives... gnozal, does DiskId32 show the drive serial?

- The problem Straker mentions, I too experience the same anomaly. I see the serial is already transposed when just having created the SerialNumber variable.

- Is this method of extracting drive serials problematic for all drives/drive types? I noticed Ring code didn't include any counter measures for this anomaly, am I wrong to think Ring didn't experience this anomaly?

Posted: Tue Dec 11, 2007 1:56 pm
by gnozal
Thunder93 wrote:... gnozal, does DiskId32 show the drive serial?
If you are talking about this
DiskId32 (freeware)
...
Warning! This utility may lock up your PC!
I did not try ...

Posted: Tue Dec 11, 2007 2:40 pm
by Thunder93
Hi gnozal,

Yes, DiskId32 freeware utility from - http://www.winsim.com/diskid32/diskid32.html .

I suppose DiskId32 probably retrieve properly the drive serial..

Posted: Tue Dec 11, 2007 4:46 pm
by gnozal
Thunder93 wrote: Yes, DiskId32 freeware utility from - http://www.winsim.com/diskid32/diskid32.html .
Yes, that's the one ...
Warning! This utility may lock up your PC!
I was just testing Rings's code, I don't need any serial.

Posted: Fri Dec 14, 2007 3:52 am
by Thunder93
Hi,


For those using SATA/RAID Controllers, the serial information isn't extracted, nothings returned. Anything that could be done to retrieve the HDD serial information when using SATA/RAID Controllers?

Re: retrieve disk`s model,serial,type

Posted: Sun Feb 17, 2019 12:43 pm
by Little John
Rings wrote:

Code: Select all

Structure STORAGE_PROPERTY_QUERY
    PropertyId.l;STORAGE_PROPERTY_ID
    QueryType.l;STORAGE_QUERY_TYPE
    AdditionalParameters.l
EndStructure
Sorry for digging up this old thread. :-)
What I found on MSDN didn't answer my question.

Can PropertyId.l, QueryType.l, and AdditionalParameters.l be used in both 32 bit and 64 bit programs, or should .i be used here in 64 bit programs?

Re: retrieve disk`s model,serial,type

Posted: Mon Feb 18, 2019 11:50 am
by Josh
Little John wrote:Can PropertyId.l, QueryType.l, and AdditionalParameters.l be used in both 32 bit and 64 bit programs, or should .i be used here in 64 bit programs?

Code: Select all

typedef struct _STORAGE_PROPERTY_QUERY1 {
  STORAGE_PROPERTY_ID PropertyId;                          -> 4 Byte
  STORAGE_QUERY_TYPE  QueryType;                           -> 4 Byte
  BYTE                AdditionalParameters[1];             -> 1 Byte
} STORAGE_PROPERTY_QUERY1, *PSTORAGE_PROPERTY_QUERY1;
Tested with VS2013. Same results with x32 and x64