Jump to content

Get Home DiskDrive SerialNumber


Go to solution Solved by Andreik,

Recommended Posts

hi

I am using wmic to get the serial of the hard drive that windows is installed on
But I want to do this through a method other than using wmic

Is it possible to do this using DllStructCreate and DllStructGetPtr and DllCall?

 

#include <MsgBoxConstants.au3>

MsgBox($MB_ICONINFORMATION, "", _Home_DiskDrive_SerialNumber() & @CRLF)

Func _Home_DiskDrive_SerialNumber()
        $Get_DiskDrive_SerialNumber = ""
        $obj_WMIService = ObjGet("winmgmts:\\" & "localhost" & "\root\cimv2")
            If Not IsObj($obj_WMIService) Then Return "Error 1"
                $colDiskDrives = $obj_WMIService.ExecQuery("SELECT * FROM Win32_DiskDrive")
                    If Not IsObj($colDiskDrives) Then Return "Error 2"
        For $objDrive In $colDiskDrives
            $strDeviceID = StringReplace($objDrive.DeviceID, "\", "\\")
            $colPartitions = $obj_WMIService.ExecQuery _
                ("ASSOCIATORS OF {Win32_DiskDrive.DeviceID=""" & _
                    $strDeviceID & """} WHERE AssocClass = " & _
                        "Win32_DiskDriveToDiskPartition")

            For $objPartition In $colPartitions
                $colLogicalDisks = $obj_WMIService.ExecQuery _
                    ("ASSOCIATORS OF {Win32_DiskPartition.DeviceID=""" & _
                        $objPartition.DeviceID & """} WHERE AssocClass = " & _
                            "Win32_LogicalDiskToPartition")

                For $objLogicalDisk In $colLogicalDisks
                    If ($objLogicalDisk.DeviceID = @HomeDrive) Then
                        $Get_DiskDrive_SerialNumber = $objDrive.SerialNumber
                        ExitLoop 3
                    EndIf
                Next
            Next
        Next
        
        IF ($Get_DiskDrive_SerialNumber) Then
            Return $Get_DiskDrive_SerialNumber
        Else
            Return "Error 3"
        EndIF
EndFunc

 

Link to comment
Share on other sites

WinAPI provides this:

#include <WinAPIFiles.au3>

Local $aData = _WinAPI_GetVolumeInformation()   ; you can parse a root dir (as string, with trailing backslash) here
ConsoleWrite('Serial number: ' & $aData[1] & @CRLF)

 

Edited by RTFC
Link to comment
Share on other sites

Thank you friends

But the two suggested ways do not display the hardware serial of the hard drive

They only display the Volume Serial Number, I know that the volume serial number changes every time when the drive is formatted or partitioned But The presented method displays the serial written on the label on the hard Disk.

But I don't want to get it using wmic and I need another way other than this method

 

Edit:

It is better to include the name of the hardware in the topic name 🙏

Edited by r2du-soft
Link to comment
Share on other sites

Try this:

$WMIObj = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2")
If @error Then
    MsgBox ( 4096 , @ScriptName , "Error getting wmi : " & Hex(@error, 8))
Else
    $WMIObjItems = $WMIObj.ExecQuery("select * FROM Win32_DiskDrive" )
    If IsObj($WMIObjItems) Then
        For $oItem In $WMIObjItems
            $sSerialNumber  = $oItem.SerialNumber
        Next
    EndIf
EndIf

MsgBox ( 4096 , @ScriptName , $sSerialNumber )

 

Link to comment
Share on other sites

...still. Say you'll RMA a drive. You'll need the serial number of the device that you can read off the label but the question is: how can I ask the OS for it. Storage Space knows it, so how can I get it too ? ( that is the OP question )

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

52 minutes ago, Andreik said:

 You can get the serial using DeviceIoControl to get access to STORAGE_DEVICE_DESCRIPTOR and

That "you can get" is not so. I can not either. Can you cook some code for us him. I'm clueless busy right now. So very busy :lol:

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

  • Solution

The promised code:

#RequireAdmin
#include <WinAPIFiles.au3>
#include <WinAPIHObj.au3>

MsgBox(0, 'Serial', 'Disk serial: ' & GetDiskSerial(@HomeDrive))

Func GetDiskSerial($sDriveLetter)
    Local Const $IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400
    Local $tagSTORAGE_PROPERTY_QUERY = 'int PropertyId; int QueryType; byte AdditionalParameters[1];'
    Local $tagSTORAGE_DESCRIPTOR_HEADER = 'dword Version;dword Size;'
    Local $tagSTORAGE_DEVICE_DESCRIPTOR = 'dword Version;dword Size; byte DeviceType;byte DeviceTypeModifier; boolean RemovableMedia;' & _
    'boolean CommandQueueing;dword VendorIdOffset;dword ProductIdOffset;dword ProductRevisionOffset;dword SerialNumberOffset;int BusType;' & _
    'dword RawPropertiesLength;byte RawDeviceProperties[1];'
    Local $aDevice = _WinAPI_GetDriveNumber ($sDriveLetter)
    If @error Then Return SetError(1, @error, Null)
    Local $hDevice = _WinAPI_CreateFile('\\.\PhysicalDrive' & $aDevice[1], 2, 2, 6)
    If @error Then Return SetError(2, @error, Null)
    Local $tSTORAGE_PROPERTY_QUERY = DllStructCreate($tagSTORAGE_PROPERTY_QUERY)
    $tSTORAGE_PROPERTY_QUERY.PropertyId = 0         ; StorageDeviceProperty
    $tSTORAGE_PROPERTY_QUERY.QueryType = 0          ; PropertyStandardQuery
    Local $tSTORAGE_DESCRIPTOR_HEADER = DllStructCreate($tagSTORAGE_DESCRIPTOR_HEADER)
    If Not _WinAPI_DeviceIoControl($hDevice, $IOCTL_STORAGE_QUERY_PROPERTY, _
            DllStructGetPtr($tSTORAGE_PROPERTY_QUERY), DllStructGetSize($tSTORAGE_PROPERTY_QUERY), _
            DllStructGetPtr($tSTORAGE_DESCRIPTOR_HEADER), DllStructGetSize($tSTORAGE_DESCRIPTOR_HEADER)) _
        Then
            _WinAPI_CloseHandle($hDevice)
            Return SetError(3, 0, Null)
    EndIf
    Local $tBuffer = DllStructCreate('byte[' & $tSTORAGE_DESCRIPTOR_HEADER.Size & ']')
    If Not _WinAPI_DeviceIoControl($hDevice, $IOCTL_STORAGE_QUERY_PROPERTY, _
            DllStructGetPtr($tSTORAGE_PROPERTY_QUERY), DllStructGetSize($tSTORAGE_PROPERTY_QUERY), _
            DllStructGetPtr($tBuffer), DllStructGetSize($tBuffer)) _
        Then
            _WinAPI_CloseHandle($hDevice)
            Return SetError(4, 0, Null)
    EndIf
    Local $tSTORAGE_DEVICE_DESCRIPTOR = DllStructCreate($tagSTORAGE_DEVICE_DESCRIPTOR, DllStructGetPtr($tBuffer))
    If $tSTORAGE_DEVICE_DESCRIPTOR.SerialNumberOffset = 0 Then
        _WinAPI_CloseHandle($hDevice)
        Return SetError(5, 0, Null)
    EndIf
    Local $tSerial = DllStructCreate('char Serial[32]', DllStructGetPtr($tBuffer) + $tSTORAGE_DEVICE_DESCRIPTOR.SerialNumberOffset)
    _WinAPI_CloseHandle($hDevice)
    Return $tSerial.Serial
EndFunc

 

Edited by Andreik
Link to comment
Share on other sites

I was looking for something more like:

Hard Disk Model ID:       Samsung SSD 980 PRO 2TB
Firmware Revision:        5B2QGXA7
Hard Disk Serial Number:  S6B0NU0W123456P

but I get something like 0025_3957_0240_ED41

Is there a way to get something like that ?, not the firmware revision or drive name but the actual hardware serial number ?

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Well, there are all kinds of serials and product IDs but the above it's certainly the serial number of the disk. For example if I use ProductIdOffset member to obtain the vendor product ID for my disk I get something like this KINGSTON RBUSNS8180DS3256GJ. There is also a SerialNumber member in STORAGE_ADAPTER_SERIAL_NUMBER structure so pick what serial you need. :D

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...