WMI Hard Drive Serial Number

I have code to retrieve the serial number of a hard drive from WMI.

SelectQuery selectQuery = new SelectQuery("Win32_PhysicalMedia"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(selectQuery); foreach (ManagementObject wmi_PM in searcher.Get()) { string str = wmi_PM["SerialNumber"]; } 

At first I thought it was working and got the correct serial number. However, trying to use it in a comparison, I found out that the WMI data is not quite correct. The WMI serial number is complemented by a bunch of spaces, and characters are transposed.

The actual drive serial number printed on the label and returned by some tools (possibly using DeviceIoControl) is "3RH8B1BG", WMI, however, returns "; R38H1BGB".

Real Serial Number: 3RH8B1BG
WMI Serial #: R38H1BGB

Some tools, such as SiSoftware Sandra, return this filled and transposed number, but not the actual serial number. The WMI value is the serial number if you transfer each other item. This is normal? should i just copy it to the correct value?

I try to avoid using WMI, but it seems that any search for how to do something on the network now returns WMI examples.

The serial number of the WMI value for 2 different hard drives of different manufacturers is transferred so that it does not have one drive.



Update: Found code using DeviceIoControl

http://addressof.com/blog/archive/2004/02/14/392.aspx

Surprisingly, DeviceIoControl also returns the transposed serial number. In the CorySmith code above, it has a SwapChars function

 Private Shared Function SwapChars(ByVal chars() As Char) As String For i As Integer = 0 To chars.Length - 2 Step 2 chars.Reverse(chars, i, 2) Next Return New String(chars).Trim End Function 

The C ++ code he mentions has a flip:

  // function to decode the serial numbers of IDE hard drives // using the IOCTL_STORAGE_QUERY_PROPERTY command char * flipAndCodeBytes (const char * str, int pos, int flip, char * buf) { ... } 

Guess what the standard for DeviceIoControl and WMI is, I don’t believe that any other solutions or examples that I came across did not have this.

+6
source share
1 answer

Found a working solution for decoding real HD-series. The following link contains code for decoding even without administrator rights: Decoding source

But if you get Series from the Win32_PhysicalMedia WMI class above Vista, this may not work in all cases. Then you should use the Win32_DiskDrive class (according to this link: Jiliang Ge Answer from Tuesday, October 27, 2009 3:12 AM

I added the code (in VB, since I usually code in VB.NET). I did not want to steal someone else's code. I have included so much information and some more links to the source code in the code. Now it also includes decoding serial numbers from removable drives (in the same procedure).

Hope this helps.

  ''' <summary> ''' Decode Manufacuter Disk Serialnumbers (also for PNP USB-Drives) ''' </summary> ''' <param name="InterfaceType">InterfaceType from Win32_DiskDrive WMI-Class</param> ''' <param name="PNPDeviceID">PNPDeviceID from Win32_DiskDrive WMI-Class</param> ''' <param name="strVolumeSerial">Raw Serialnumber to be decoded</param> ''' <returns>Decoded Serialnumber</returns> ''' <remarks></remarks> Public Shared Function Decode_HD_Serial(ByVal InterfaceType As String, ByVal PNPDeviceID As String, ByVal strVolumeSerial As String) As String 'HANDLE USB PNP Devices differently (Removable USB-Sticks) 'see: http://www.experts-exchange.com/Programming/Languages/.NET/Q_24574066.html If InterfaceType = "USB" Then Dim splitDeviceId As String() = PNPDeviceID.Split("\"c) Dim arrayLen As Integer = splitDeviceId.Length - 1 Dim serialArray As String() = splitDeviceId(arrayLen).Split("&"c) Return serialArray(0) Else 'Link:https://social.msdn.microsoft.com/Forums/vstudio/en-US/8523d7b9-0dc8-4d87-be69-a482aec9ee5e/wmi-win32physicalmedia-smart-id-in-vista-and-7-permissions?forum=netfxbcl 'After digging into the [Win32_PhysicalMedia] WMI class, I find that from Vista/Longhorn the 'class has been taken over by another class called [Win32_DiskDrive]. Thus, if all machines 'in your environment are Vista and above use the second class otherwise use the first one. 'Based on my tests, the class gives the unique form of serial number when you run the 'app as an admin or as a non-admin. ' ---> IF System.Environment.OSVersion.Version.Major > 5 then its Vista or higher. USE WIN32_DiskDrive Dim strVolumeSerialDecoded As String = String.Empty 'Remove all space characters ("20"). 'Example : 20202020205635424544434553 will be 5635424544434553. strVolumeSerial.Trim.Replace("20", "") 'IF THE USER IS ADMINISTRATOR, THE strVolumeSerial STRING WILL ALREADY CONTAIN THE SERIAL NUMBER IN ASCII, AND NO CONVERSION IS REQUIRED (Microsoft bug ?), 'BUT IF THE strVolumeSerial STRING IS A HEX STRING, CONVERT IT TO ASCII : If System.Text.RegularExpressions.Regex.IsMatch(strVolumeSerial, "^[a-fA-F0-9]+$") Then 'Convert to ASCII. Example : 5635424544434553 will be converted to V5BEDCES. strVolumeSerial = HexDecode(strVolumeSerial) 'Swap pairs of characters. 'Example : V5BEDCES will be converted to 5VEBCDSE. Dim serialNumber2 As String = "" For i As Integer = 0 To strVolumeSerial.Length - 1 Step 2 strVolumeSerialDecoded &= strVolumeSerial(i + 1) strVolumeSerialDecoded &= strVolumeSerial(i) Next 'Return the serialnumber as ASCII string. Return strVolumeSerialDecoded.Trim Else 'If strVolumeSerial is ASCII, remove spaces and return the serialnumber string. Return strVolumeSerial.Trim End If End If End Function ''' <summary>Decodes a HEX-string to an ASCII string.</summary> ''' <param name="strHEX">The HEX-string to decode.</param> ''' <returns>If succeeded, the decoded String, an empty String if failed.</returns> Private Shared Function HexDecode(ByVal strHEX As String) As String Try Dim sb As StringBuilder = New StringBuilder For i As Integer = 0 To strHEX.Length - 1 Step 2 sb.Append(Convert.ToChar(Convert.ToUInt32(strHEX.Substring(i, 2), 16)).ToString) Next Return sb.ToString Catch ex As Exception Return "" End Try End Function 
+1
source

Source: https://habr.com/ru/post/917837/


All Articles