2012-06-12 28 views
6

Tôi có một số mã để tìm nạp số sêri ổ cứng từ WMI.Số sê-ri WMI HDD Transposed

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

Lúc đầu, tôi nghĩ rằng nó đang hoạt động và truy xuất đúng số sê-ri. Sau khi cố gắng sử dụng nó với một so sánh mặc dù, tôi phát hiện ra số lượng các báo cáo WMI là không chính xác chính xác. Số sê-ri WMI được đệm với một loạt các khoảng trống cũng như các ký tự được chuyển đổi.

Các ổ đĩa thực tế số serial in trên nhãn dán và trả về bởi một số công cụ (có thể sử dụng DeviceIoControl) là "3RH8B1BG", WMI tuy nhiên trả về "                                R38H1BGB" .

Bất Serial #: 3RH8B1BG
WMI Serial #: R38H1BGB

Một số công cụ như SiSoftware Sandra, trở về con số này đệm và hoán, số serial không thực tế của nó mặc dù. Giá trị WMI là số sê-ri nếu bạn chuyển đổi mọi vị trí khác. Điều này có bình thường không? Tôi có nên viết mã để chuyển nó đến đúng giá trị không?

Tôi cố gắng tránh sử dụng WMI nhưng có vẻ như bất kỳ tìm kiếm nào về cách thực hiện điều gì đó trên mạng hiện nay đều mang lại các ví dụ WMI.

Số sê-ri giá trị WMI cho 2 ổ cứng khác nhau của các nhà sản xuất khác nhau đều được chuyển đổi sao cho nó không phải là một đĩa đơn.



Cập nhật: tìm thấy một số mã sử dụng DeviceIoControl

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

Đáng ngạc nhiên, DeviceIoControl trả về một số sê-ri hoán là tốt. Trong mã bằng cách CorySmith trên nó có một SwapChars hoạt

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 

Các mã C++ ông đề cập đến có lật tới:

// 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) 
{ 
    ... 
} 

đoán đó là tiêu chuẩn cho DeviceIoControl và WMI, không thể tin bất kỳ khác giải pháp hoặc ví dụ tôi chạy qua không có điều này.

+2

Ồ, có vẻ như bạn đang chạy trên [PDP-11] (http://en.wikipedia.org/wiki/Endianness#Middle-endian)! – sarnold

+3

Thực ra anh ta đang chạy trên một máy tính có cùng thứ tự byte nhỏ như PDP-11. Vì vậy, tôi và nếu bạn đang chạy Windows (không phải Windows CE và không phải Windows Phone), bạn cũng vậy. Giải pháp làm việc duy nhất là gọi DeviceIoControl và tự lật các byte, như áp phích ban đầu được tìm thấy. Nếu bạn gọi WMI thì bạn không biết liệu WMI có bật các byte cho bạn hay không. –

Trả lời

1

Tìm ra giải pháp làm việc để giải mã HD-Serials thực. Liên kết sau chứa mã để giải mã ngay cả khi không có quyền quản trị: Decoding Source

Nhưng nếu bạn nhận được các Serials từ lớp Win32_PhysicalMedia WMI trên Vista, nó có thể không hoạt động trong mọi trường hợp. Sau đó, bạn phải sử dụng lớp Win32_DiskDrive (theo liên kết này: Jiliang Ge's Answer from Tuesday, October 27, 2009 3:12 AM

Tôi đã thêm mã (trong VB, vì tôi thường mã trong VB.NET) .Tôi không muốn ăn cắp mã của người khác. càng nhiều Infos và vẫn còn một số liên kết đến bộ mã nguồn gốc trong mã, nó cũng bao gồm giải mã Serialnumbers từ Removable Drives (trong cùng một thường trình).

Hy vọng điều đó sẽ hữu ích.

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

Chỉ cần đăng liên kết không làm bất cứ ai tốt. Bạn cần bao gồm thông tin liên quan trong câu trả lời của mình. –

+0

Xin lỗi vì điều đó. Tôi chỉ không muốn ăn cắp mã từ người khác. – dragonfly

Các vấn đề liên quan