Jump to content

...


Recommended Posts

1. Volume serial

2. CMD returns a formatted Hex value whereas AutoIt returns the decimal value.

3. It changes after formatting but I'm not sure how unique it is.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

@jackit Here is a small test for you.

$aDrives = DriveGetDrive("Fixed")
For $i = 1 To Ubound($aDrives)-1
   $iSer = DriveGetSerial($aDrives[$i])
   $hVal = Hex($iSer)
   $hVal = StringLeft($hVal, 4) & "-" & StringRight($hVal, 4)
   MsgBox(0, "Result", "The serial of Drive " & StringUpper($aDrives[$i]) & " is" & _
   @CRLF & @CRLF & $iSer & "  decimal" & @CRLF & @CRLF & $hVal & "  hex")
Next

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

I had a rather strange return myself with Drive D: (ATA) and Drive E: (SATA) returning the same hex value (7FFF-FFFF) and I'm not sure why. I'm not too concerned about finding out why though. The Decimal values were different. That was just to show why DriveGetSerial() and CMD differed.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

I hate to ask the same thing when a few threads regarding the same thing has been asked but yeah, here goes...

1. Is the value returned by the DriveGetSerial function unique? Does it show the actual Drive ID or does it return the Volume Serial Number? It also returns 2 different serials on 2 different partitions.

2. If it is indeed the Volume Serial Number, why do I get '12345678' but CMD says '7G1D-B168'?

3. Does the serial number change after the HDD is reformated? Even if it does, is it unique on each computer, irregardless if it is from the same brand and model?

I hope someone can help me clarify this, thank you! :o

The command line (DIR) reports volume serial number, which is for the partition, not the physical disk.

The problem is that "actual Drive" is a fuzzy term. The OS doesn't know, for instance, if it's running in a VM and looking at a virtual drive, or a logical disk in a hardware RAID set, or SAN LUN, etc.

If the driver for a given hard disk provides the interface to get the serial number, you might be able to query it with WMI or a DLL call, but there are many layers of abstraction between terms like "disk", "volume", "drive", etc. It can be frustrating to drill down to what you really want.

I have seen posts related to getting SMART data, which should access disk stuff at a low level.

What do you really need it for? Are you just trying to assemble a GUID for the machine?

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

You can actually get the physical drive serial number (set by manufacturer) with WMI and if I recall it is in Win32_PhysicalMedia.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

Yup, it's showed in Microsoft's site but do you have an example on how to apply it?

You can run the sample VBS provided by Scriptomatic for Win32_PhysicalMedia, but you may be disappointed. On my current PC with one SATA drive and two LUNs on a FibreChannel HBA, I get null for the SATA drive serial number, and the same global serial number of the SAN disk array for both LUNs (which are actually RAID sets, of course).

Microsoft claims that FSO drives have a .SerialNumber property that is "Serial number assigned to the drive by the manufacturer." But that is clearly bogus:

Global $oCOMError = ObjEvent("AutoIt.Error", "_COMError")

Global $sMsg

Global $objFSO = ObjCreate("Scripting.FileSystemObject")
Global $colDrives = $objFSO.Drives
For $objDrive In $colDrives
    $sMsg = "FSO Drive:" & @CRLF
    $sMsg &= "Available space: " & $objDrive.AvailableSpace & @CRLF
    $sMsg &= "Drive letter: " & $objDrive.DriveLetter & @CRLF
    $sMsg &= "Drive type: " & $objDrive.DriveType & @CRLF
    $sMsg &= "File system: " & $objDrive.FileSystem & @CRLF
    $sMsg &= "Is ready: " & $objDrive.IsReady & @CRLF
    $sMsg &= "Path: " & $objDrive.Path & @CRLF
    $sMsg &= "Root folder: " & $objDrive.RootFolder & @CRLF
    $sMsg &= "Serial number: " & $objDrive.SerialNumber & @CRLF
    $sMsg &= "Share name: " & $objDrive.ShareName & @CRLF
    $sMsg &= "Total size: " & $objDrive.TotalSize & @CRLF
    $sMsg &= "Volume name: " & $objDrive.VolumeName & @CRLF
    $sMsg &= "DriveGetSerial = " & DriveGetSerial($objDrive.DriveLetter & ":") & @CRLF
    MsgBox(64, "Results", $sMsg)
Next

Func _COMError()
    $sMsg &= "<COM Error>" & @CRLF
EndFunc

I get a negative integer back for some drives and different SNs for two partitions on the same drive.

:D

Edit: Updated demo to include the value returned by DriveGetSerial(). It matches the $objDrive.SerialNumber in most cases, but gives a long integer string instead of a negative integer for the drives that get that from the FSO reference.

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

This works for me but YMMV

$colItems = ""
$strComputer = "localhost"
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT SerialNumber FROM Win32_PhysicalMedia")

If IsObj($colItems) then
   For $objItem In $colItems
      MsgBox(0, "Serial", StringStripWS($objItem.SerialNumber, 3))
   Next
EndIf

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

You can run the sample VBS provided by Scriptomatic for Win32_PhysicalMedia, but you may be disappointed. On my current PC with one SATA drive and two LUNs on a FibreChannel HBA, I get null for the SATA drive serial number, and the same global serial number of the SAN disk array for both LUNs (which are actually RAID sets, of course).

Microsoft claims that FSO drives have a .SerialNumber property that is "Serial number assigned to the drive by the manufacturer." But that is clearly bogus:

Global $oCOMError = ObjEvent("AutoIt.Error", "_COMError")

Global $sMsg

Global $objFSO = ObjCreate("Scripting.FileSystemObject")
Global $colDrives = $objFSO.Drives
For $objDrive In $colDrives
    $sMsg = "FSO Drive:" & @CRLF
    $sMsg &= "Available space: " & $objDrive.AvailableSpace & @CRLF
    $sMsg &= "Drive letter: " & $objDrive.DriveLetter & @CRLF
    $sMsg &= "Drive type: " & $objDrive.DriveType & @CRLF
    $sMsg &= "File system: " & $objDrive.FileSystem & @CRLF
    $sMsg &= "Is ready: " & $objDrive.IsReady & @CRLF
    $sMsg &= "Path: " & $objDrive.Path & @CRLF
    $sMsg &= "Root folder: " & $objDrive.RootFolder & @CRLF
    $sMsg &= "Serial number: " & $objDrive.SerialNumber & @CRLF
    $sMsg &= "Share name: " & $objDrive.ShareName & @CRLF
    $sMsg &= "Total size: " & $objDrive.TotalSize & @CRLF
    $sMsg &= "Volume name: " & $objDrive.VolumeName & @CRLF
    MsgBox(64, "Results", $sMsg)
Next

Func _COMError()
    $sMsg &= "<COM Error>" & @CRLF
EndFunc

I get a negative integer back for some drives and different SNs for two partitions on the same drive.

:D

I think that's ok. I will (try) to show you what's causing negative values. Will update this post in a minute or two with some code.

edit:

Reference

Thing is that VolumeSerialNumber for NTFS is in form of LONGLONG. To have backward compability serial numbers for NTFS are read as long and the rest of the full value is just ignored (in case of your example filled with 0xFFFFFFFF).

You can test it with this code:

Global  $sDriveLettern = "C"

Global $hComIn = FileOpen("\\.\" & $sDriveLetter & ":", 16)
Global $bRaw = FileRead($hComIn, 84); 84 bytes is enough

ConsoleWrite(_HexEncode($bRaw) & @CRLF)

FileClose($hComIn)

Global $tRaw = DllStructCreate("byte [" & BinaryLen($bRaw) & "]")
DllStructSetData($tRaw, 1, $bRaw)

Local $tBootSectorSections = DllStructCreate("align 1;byte Jump[3];" & _
        "char SystemName[8];" & _
        "ushort BytesPerSector;" & _
        "ubyte SectorsPerCluster;" & _
        "ushort ReservedSectors;" & _
        "ubyte[3];" & _
        "ushort;" & _
        "ubyte MediaDescriptor;" & _
        "ushort;" & _
        "ushort SectorsPerTrack;" & _
        "ushort NumberOfHeads;" & _
        "dword HiddenSectors;" & _
        "dword;" & _
        "dword;" & _
        "int64 TotalSectors;" & _
        "int64 LogicalClusterNumberforthefileMFT;" & _
        "int64 LogicalClusterNumberforthefileMFTMirr;" & _
        "dword ClustersPerFileRecordSegment;" & _
        "dword ClustersPerIndexBlock;" & _
        "int64 NTFSVolumeSerialNumber;" & _
        "dword Checksum", _
        DllStructGetPtr($tRaw))


ConsoleWrite("Jump:  " & DllStructGetData($tBootSectorSections, "Jump") & @CRLF)
ConsoleWrite("SystemName:  " & DllStructGetData($tBootSectorSections, "SystemName") & @CRLF)
ConsoleWrite("BytesPerSector:  " & DllStructGetData($tBootSectorSections, "BytesPerSector") & @CRLF)
ConsoleWrite("SectorsPerCluster:  " & DllStructGetData($tBootSectorSections, "SectorsPerCluster") & @CRLF)
ConsoleWrite("ReservedSectors:  " & DllStructGetData($tBootSectorSections, "ReservedSectors") & @CRLF)
;ConsoleWrite("6:  " & DllStructGetData($tBootSectorSections, 6) & @CRLF)
;ConsoleWrite("7:  " & DllStructGetData($tBootSectorSections, 7) & @CRLF)
ConsoleWrite("MediaDescriptor:  " & DllStructGetData($tBootSectorSections, "MediaDescriptor") & @CRLF)
;ConsoleWrite("9:  " & DllStructGetData($tBootSectorSections, 9) & @CRLF)
ConsoleWrite("SectorsPerTrack:  " & DllStructGetData($tBootSectorSections, "SectorsPerTrack") & @CRLF)
ConsoleWrite("NumberOfHeads:  " & DllStructGetData($tBootSectorSections, "NumberOfHeads") & @CRLF)
ConsoleWrite("HiddenSectors:  " & DllStructGetData($tBootSectorSections, "HiddenSectors") & @CRLF)
;ConsoleWrite("13:  " & DllStructGetData($tBootSectorSections, 13) & @CRLF)
;ConsoleWrite("14:  " & DllStructGetData($tBootSectorSections, 14) & @CRLF)
ConsoleWrite("TotalSectors:  " & DllStructGetData($tBootSectorSections, "TotalSectors") & @CRLF)
ConsoleWrite("LogicalClusterNumberforthefileMFT:  " & DllStructGetData($tBootSectorSections, "LogicalClusterNumberforthefileMFT") & @CRLF)
ConsoleWrite("LogicalClusterNumberforthefileMFTMirr:  " & DllStructGetData($tBootSectorSections, "LogicalClusterNumberforthefileMFTMirr") & @CRLF)
ConsoleWrite("ClustersPerFileRecordSegment:  " & DllStructGetData($tBootSectorSections, "ClustersPerFileRecordSegment") & @CRLF)
ConsoleWrite("ClustersPerIndexBlock:  " & DllStructGetData($tBootSectorSections, "ClustersPerIndexBlock") & @CRLF)
ConsoleWrite("VolumeSerialNumber:  " & Ptr(DllStructGetData($tBootSectorSections, "NTFSVolumeSerialNumber")) & @CRLF)
ConsoleWrite("NTFSVolumeSerialNumber:  " & DllStructGetData($tBootSectorSections, "NTFSVolumeSerialNumber") & @CRLF)
ConsoleWrite("Checksum:  " & DllStructGetData($tBootSectorSections, "Checksum") & @CRLF)



Func _HexEncode($bInput)

    Local $tInput = DllStructCreate("byte[" & BinaryLen($bInput) & "]")

    DllStructSetData($tInput, 1, $bInput)

    Local $a_iCall = DllCall("crypt32.dll", "int", "CryptBinaryToString", _
            "ptr", DllStructGetPtr($tInput), _
            "dword", DllStructGetSize($tInput), _
            "dword", 11, _
            "ptr", 0, _
            "dword*", 0)

    If @error Or Not $a_iCall[0] Then
        Return SetError(1, 0, "")
    EndIf

    Local $iSize = $a_iCall[5]
    Local $tOut = DllStructCreate("char[" & $iSize & "]")

    $a_iCall = DllCall("crypt32.dll", "int", "CryptBinaryToString", _
            "ptr", DllStructGetPtr($tInput), _
            "dword", DllStructGetSize($tInput), _
            "dword", 11, _
            "ptr", DllStructGetPtr($tOut), _
            "dword*", $iSize)

    If @error Or Not $a_iCall[0] Then
        Return SetError(2, 0, "")
    EndIf

    Return SetError(0, 0, DllStructGetData($tOut, 1))

EndFunc  ;==>_HexEncode

With your code I get this:

FSO Drive:
Available space: 6498537472
Drive letter: C
Drive type: 2
File system: NTFS
Is ready: -1
Path: C:
Root folder: 
Serial number: -793799782; 0xFFFFFFFFD0AF939A <- this!!!
Share name: 0
Total size: 32160808960
Volume name: Windows XP

And with one in this post:

Jump:  0xEB5290
SystemName:  NTFS   
BytesPerSector:  512
SectorsPerCluster:  8
ReservedSectors:  0
MediaDescriptor:  248
SectorsPerTrack:  63
NumberOfHeads:  255
HiddenSectors:  63
TotalSectors:  62814086
LogicalClusterNumberforthefileMFT:  786432
LogicalClusterNumberforthefileMFTMirr:  2621603
ClustersPerFileRecordSegment:  246
ClustersPerIndexBlock:  1
VolumeSerialNumber:  0xD0AF939A
NTFSVolumeSerialNumber:  2941043803637650330
Checksum:  0

Just to verify:

$sDriveLetter = "C"

$aCall = DllCall("kernel32.dll", "int", "GetVolumeInformation", _
        "str", $sDriveLetter & ":\", _
        "str", "", _
        "dword", 256, _
        "ptr*", 0, _
        "dword*", 0, _
        "dword*", 0, _
        "str", "", _
        "dword", 256)

ConsoleWrite("RootPathName: " & $aCall[1] & @CRLF)
ConsoleWrite("VolumeName: " & $aCall[2] & @CRLF)
ConsoleWrite("VolumeSerialNumber: " & $aCall[4] & @CRLF)
ConsoleWrite("MaximumComponentLength: " & $aCall[5] & @CRLF)
ConsoleWrite("FileSystemFlags: " & $aCall[6] & @CRLF)
ConsoleWrite("FileSystemName: " & $aCall[7] & @CRLF)
Edited by trancexx
Link to comment
Share on other sites

This works for me but YMMV

$colItems = ""
$strComputer = "localhost"
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT SerialNumber FROM Win32_PhysicalMedia")

If IsObj($colItems) then
   For $objItem In $colItems
      MsgBox(0, "Serial", StringStripWS($objItem.SerialNumber, 3))
   Next
EndIf
My mileage did vary: I got the null string for my SATA drive.

The FSO and DriveGetSerial() both return a long number, which is suspicious, because the serial numbers on the actual drive labels are strings with letters and dashes, etc. So I think that is really Volume serial.

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

For The DLL call the answer to the what is being returned is right in front of you

DllCall("kernel32.dll", "int", "GetVolumeInformation",

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

For The DLL call the answer to the what is being returned is right in front of you

DllCall("kernel32.dll", "int", "GetVolumeInformation",

And the Microsoft text says of that OEM ID field:

...the 8-byte OEM ID, a string of characters that identifies the name and version number of the operating system that formatted the volume.

So that is NOT the hardware serial number of the physical disk. I would assume that if the driver exposes the physical drive's serial number, firmware rev, etc., that you could read it just as easily off a disk with no disk signature or only an EXT3 (Linux) partition on it. Because the it only needs to talk to the drive electronics, not anything written to the disk surface.

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

I've gathered a few HDD serials in the university computer lab and it seems the ones I used had the same volume serial numbers! They were Dell computer with probably the same hardware and configuration. So I'm guessing computer with the same setup will usually give the same HDD volume serial number and not a unique one?

Volume serial number is by definition a random serial number created when formatting a disk (partition).

What tool Dell uses to format discs is up to them. Why that tool is not randomizing serial numbers is up to them too.

I guess the author of it didn't find that needed, maybe because he/she was told it's gonna be only one partition to deal with.

Link to comment
Share on other sites

Volume serial number is by definition a random serial number created when formatting a disk (partition).

If that's true and the serials on different computers are the same... I would guess the computers were set-up with a Clone tool :D...

Link to comment
Share on other sites

If you're looking for a unique ID I remember a discussion about that ... (search, search)... here it is

#131508

Contains several good starting points, maybe a combination of some of the queries will do. Though I would not use the ones utilizing WMI, as it is not installed on all machines by default. Look more into the provided kernel calls etc...

Edited by KaFu
Link to comment
Share on other sites

Test the vbs script:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_DiskDrive where InterfaceType = 'USB'")

For Each objItem in colItems
    Wscript.Echo "PNPID: " & objItem.PNPDeviceID
Next
WSCript.Quit

Output:

USBSTOR\DISK&VEN_SONY&PROD_STORAGE_MEDIA&REV_0100\2A08112518943&0

The 2A08112518943&0 is a unique ID. Test it on 3 Computer on more the one Slots. Everytime it is 2A08112518943&0

Edit:

Works with Fix and Remove able drives. Not with CD Rom or Network drives

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_DiskDrive")

For Each objItem in colItems
    Wscript.Echo "PNPID: " & objItem.PNPDeviceID
Next
WSCript.Quit
Edited by Tec
Link to comment
Share on other sites

$objWMIService = ObjGet("winmgmts:{impersonationLevel=Impersonate}!\\.\root\cimv2")
If Not IsObj($objWMIService) Then Exit 

$colDevice = $objWMIService.ExecQuery("SELECT * from Win32_DiskDrive")
For $objItem in $colDevice
    $var = StringTrimLeft($objItem.PNPDeviceID,StringInstr($objItem.PNPDeviceID,"\",0,-1))
    MsgBox( 64, "PNPDEviceID", $var)
Next

Try this ;-)

Edited by Tec
Link to comment
Share on other sites

  • 3 months later...

This works for me but YMMV

$colItems = ""
$strComputer = "localhost"
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT SerialNumber FROM Win32_PhysicalMedia")

If IsObj($colItems) then
   For $objItem In $colItems
      MsgBox(0, "Serial", StringStripWS($objItem.SerialNumber, 3))
   Next
EndIf

This worked for me (at least for my lone fixed drive), but I need a way to get the drive serial by specifying which drive, preferably by letter (i.e., C:\, F:\). Does anyone know how to do this?

The code returned empty or null for my USB drives though.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...