Converting HDD Serial # VB6 code into VB.NET code

匿名 (未验证) 提交于 2019-12-03 01:18:02

问题:

I've got a cool piece of code taken from a VC++ project which gets complete information of the hard disk drive WITHOUT using WMI (since WMI has got its own problems) I ask those of you who are comfortable with API functions to try to convert this VB6 code into VB (or C#) .NET and help A LOT of people who are in great need of this utility class. I've spent lots of time and searched the entire net to find ways to get the actual model and serial number of HDD and eventually found this one, if only it were in .NET... Here is the code and sorry about its formatting problems, just paste it into VB6 IDE:

Option Explicit  ''// Antonio Giuliana, 2001-2003  ''// Costanti per l'individuazione della versione di OS Private Const VER_PLATFORM_WIN32S = 0 Private Const VER_PLATFORM_WIN32_WINDOWS = 1 Private Const VER_PLATFORM_WIN32_NT = 2  ''// Costanti per la comunicazione con il driver IDE Private Const DFP_RECEIVE_DRIVE_DATA = &H7C088  ''// Costanti per la CreateFile Private Const FILE_SHARE_READ = &H1 Private Const FILE_SHARE_WRITE = &H2 Private Const GENERIC_READ = &H80000000 Private Const GENERIC_WRITE = &H40000000 Private Const OPEN_EXISTING = 3 Private Const CREATE_NEW = 1  ''// Enumerazione dei comandi per la CmnGetHDData Private Enum HDINFO    HD_MODEL_NUMBER    HD_SERIAL_NUMBER    HD_FIRMWARE_REVISION End Enum  ''// Struttura per l'individuazione della versione di OS Private Type OSVERSIONINFO    dwOSVersionInfoSize As Long    dwMajorVersion As Long    dwMinorVersion As Long    dwBuildNumber As Long    dwPlatformId As Long    szCSDVersion As String * 128 End Type  ''// Struttura per il campo irDriveRegs della struttura SENDCMDINPARAMS Private Type IDEREGS    bFeaturesReg As Byte    bSectorCountReg As Byte    bSectorNumberReg As Byte    bCylLowReg As Byte    bCylHighReg As Byte    bDriveHeadReg As Byte    bCommandReg As Byte    bReserved As Byte End Type  ''// Struttura per l'I/O dei comandi al driver IDE Private Type SENDCMDINPARAMS     cBufferSize As Long     irDriveRegs As IDEREGS     bDriveNumber As Byte     bReserved(1 To 3) As Byte     dwReserved(1 To 4) As Long End Type  ''// Struttura per il campo DStatus della struttura SENDCMDOUTPARAMS Private Type DRIVERSTATUS     bDriveError As Byte     bIDEStatus As Byte     bReserved(1 To 2) As Byte     dwReserved(1 To 2) As Long End Type  ''// Struttura per l'I/O dei comandi al driver IDE Private Type SENDCMDOUTPARAMS     cBufferSize As Long     DStatus As DRIVERSTATUS     ''// ovvero DriverStatus     bBuffer(1 To 512) As Byte End Type  ''// Per ottenere la versione del SO Private Declare Function GetVersionEx _     Lib "kernel32" Alias "GetVersionExA" _     (lpVersionInformation As OSVERSIONINFO) As Long  ''// Per ottenere un handle al device IDE Private Declare Function CreateFile _     Lib "kernel32" Alias "CreateFileA" _     (ByVal lpFileName As String, _     ByVal dwDesiredAccess As Long, _     ByVal dwShareMode As Long, _     ByVal lpSecurityAttributes As Long, _     ByVal dwCreationDisposition As Long, _     ByVal dwFlagsAndAttributes As Long, _     ByVal hTemplateFile As Long) As Long  ''// Per chiudere l'handle del device IDE Private Declare Function CloseHandle _     Lib "kernel32" _     (ByVal hObject As Long) As Long  ''// Per comunicare con il driver IDE Private Declare Function DeviceIoControl _     Lib "kernel32" _     (ByVal hDevice As Long, _     ByVal dwIoControlCode As Long, _     lpInBuffer As Any, _     ByVal nInBufferSize As Long, _     lpOutBuffer As Any, _     ByVal nOutBufferSize As Long, _     lpBytesReturned As Long, _     ByVal lpOverlapped As Long) As Long  ''// Per azzerare buffer di scambio dati Private Declare Sub ZeroMemory _     Lib "kernel32" Alias "RtlZeroMemory" _     (dest As Any, _     ByVal numBytes As Long)  ''// Per copiare porzioni di memoria Private Declare Sub CopyMemory _     Lib "kernel32" Alias "RtlMoveMemory" _     (Destination As Any, _     Source As Any, _     ByVal Length As Long)  Private Declare Function GetLastError _     Lib "kernel32" () As Long  Private mvarCurrentDrive As Byte    ''// Drive corrente Private mvarPlatform As String      ''// Piattaforma usata  Public Property Get Copyright() As String     ''// Copyright     Copyright = "HDSN Vrs. 1.00, (C) Antonio Giuliana, 2001-2003" End Property  ''// Metodo GetModelNumber Public Function GetModelNumber() As String        ''// Ottiene il ModelNumber     GetModelNumber = CmnGetHDData(HD_MODEL_NUMBER) End Function  ''// Metodo GetSerialNumber Public Function GetSerialNumber() As String    ''// Ottiene il SerialNumber     GetSerialNumber = CmnGetHDData(HD_SERIAL_NUMBER) End Function  ''// Metodo GetFirmwareRevision Public Function GetFirmwareRevision() As String    ''// Ottiene la FirmwareRevision     GetFirmwareRevision = CmnGetHDData(HD_FIRMWARE_REVISION) End Function  ''// Proprieta' CurrentDrive Public Property Let CurrentDrive(ByVal vData As Byte)     ''// Controllo numero di drive fisico IDE     If vData  3 Then         Err.Raise 10000, , "Illegal drive number"   ''// IDE drive 0..3     End If      ''// Nuovo drive da considerare     mvarCurrentDrive = vData End Property  ''// Proprieta' CurrentDrive Public Property Get CurrentDrive() As Byte     ''// Restituisce drive fisico corrente (IDE 0..3)     CurrentDrive = mvarCurrentDrive End Property  ''// Proprieta' Platform Public Property Get Platform() As String     ''// Restituisce tipo OS     Platform = mvarPlatform End Property  Private Sub Class_Initialize()     ''// Individuazione del tipo di OS     Dim OS As OSVERSIONINFO      OS.dwOSVersionInfoSize = Len(OS)     Call GetVersionEx(OS)     mvarPlatform = "Unk"      Select Case OS.dwPlatformId         Case Is = VER_PLATFORM_WIN32S             mvarPlatform = "32S"                ''// Win32S         Case Is = VER_PLATFORM_WIN32_WINDOWS             If OS.dwMinorVersion = 0 Then                 mvarPlatform = "W95"            ''// Win 95             Else                 mvarPlatform = "W98"            ''// Win 98             End If         Case Is = VER_PLATFORM_WIN32_NT             mvarPlatform = "WNT"                ''// Win NT/2000     End Select End Sub  Private Function CmnGetHDData(hdi As HDINFO) As String      ''// Rilevazione proprieta' IDE      Dim bin As SENDCMDINPARAMS     Dim bout As SENDCMDOUTPARAMS     Dim hdh As Long     Dim br As Long     Dim ix As Long     Dim hddfr As Long     Dim hddln As Long     Dim s As String      Select Case hdi             ''// Selezione tipo caratteristica richiesta         Case HD_MODEL_NUMBER             hddfr = 55          ''// Posizione nel buffer del ModelNumber             hddln = 40          ''// Lunghezza nel buffer del ModelNumber         Case HD_SERIAL_NUMBER             hddfr = 21          ''// Posizione nel buffer del SerialNumber             hddln = 20          ''// Lunghezza nel buffer del SerialNumber         Case HD_FIRMWARE_REVISION             hddfr = 47          ''// Posizione nel buffer del FirmwareRevision             hddln = 8           ''// Lunghezza nel buffer del FirmwareRevision         Case Else             Err.Raise 10001, "Illegal HD Data type"          End Select          Select Case mvarPlatform         Case "WNT"             ''// Per Win NT/2000 apertura handle al drive fisico             hdh = CreateFile("\\.\PhysicalDrive" & mvarCurrentDrive, _                 GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ + FILE_SHARE_WRITE, _                 0, OPEN_EXISTING, 0, 0)         Case "W95", "W98"             ''// Per Win 9X apertura handle al driver SMART             ''// (in \WINDOWS\SYSTEM da spostare in \WINDOWS\SYSTEM\IOSUBSYS)             ''// che comunica con il driver IDE             hdh = CreateFile("\\.\Smartvsd", _                 0, 0, 0, CREATE_NEW, 0, 0)         Case Else             ''// Piattaforma non supportata (Win32S)             Err.Raise 10002, , "Illegal platform (only WNT, W98 or W95)"         End Select      ''// Controllo validità handle     If hdh = 0 Then         Err.Raise 10003, , "Error on CreateFile"     End If      ''// Azzeramento strutture per l'I/O da driver     ZeroMemory bin, Len(bin)     ZeroMemory bout, Len(bout)      ''// Preparazione parametri struttura di richiesta al driver     With bin         .bDriveNumber = mvarCurrentDrive         .cBufferSize = 512         With .irDriveRegs             If (mvarCurrentDrive And 1) Then                 .bDriveHeadReg = &HB0             Else                 .bDriveHeadReg = &HA0             End If             .bCommandReg = &HEC             .bSectorCountReg = 1             .bSectorNumberReg = 1         End With     End With      ''// Richiesta al driver     DeviceIoControl hdh, DFP_RECEIVE_DRIVE_DATA, _                 bin, Len(bin), bout, Len(bout), br, 0      ''// Formazione stringa di risposta     ''// da buffer di uscita     ''// L'ordine dei byte e' invertito     s = ""     For ix = hddfr To hddfr + hddln - 1 Step 2         If bout.bBuffer(ix + 1) = 0 Then Exit For         s = s & Chr(bout.bBuffer(ix + 1))         If bout.bBuffer(ix) = 0 Then Exit For         s = s & Chr(bout.bBuffer(ix))     Next ix      ''// Chiusura handle     CloseHandle hdh      ''// Restituzione informazione richiesta     CmnGetHDData = Trim(s)  End Function 

回答1:

I found it! Here is the equivalent VB.NET code. It's not exactly the converted version of the VB6 code, but does the same thing. Enjoy!

Public Class HDDInfo #Region " Declatrations " Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, ByVal lpSecurityAttributes As Integer, ByVal dwCreationDisposition As Integer, ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As Integer) As Integer  _ Private Shared Function CloseHandle(ByVal hObject As Integer) As Integer End Function  _ Private Shared Function DeviceIoControl(ByVal hDevice As Integer, ByVal dwIoControlCode As Integer,  ByVal lpInBuffer As SENDCMDINPARAMS, ByVal lpInBufferSize As Integer,  ByVal lpOutBuffer As SENDCMDOUTPARAMS, ByVal lpOutBufferSize As Integer, _  ByRef lpBytesReturned As Integer, ByVal lpOverlapped As Integer) As Integer End Function Private Const FILE_SHARE_READ As Short = &H1 Private Const FILE_SHARE_WRITE As Short = &H2 Private Const GENERIC_READ As Integer = &H80000000 Private Const GENERIC_WRITE As Integer = &H40000000 Private Const OPEN_EXISTING As Short = 3 Private Const CREATE_NEW As Short = 1 Private Const VER_PLATFORM_WIN32_NT As Integer = 2 Private Const DFP_RECEIVE_DRIVE_DATA As Integer = &H7C088 Private Const INVALID_HANDLE_VALUE As Integer = -1 #End Region #Region " Classes "  _ Private Class IDEREGS     Public Features As Byte     Public SectorCount As Byte     Public SectorNumber As Byte     Public CylinderLow As Byte     Public CylinderHigh As Byte     Public DriveHead As Byte     Public Command As Byte     Public Reserved As Byte End Class  _ Private Class SENDCMDINPARAMS     Public BufferSize As Integer     Public DriveRegs As IDEREGS     Public DriveNumber As Byte      _     Public Reserved As Byte()      _     Public Reserved2 As Integer()     Public Sub New()         DriveRegs = New IDEREGS()         Reserved = New Byte(2) {}         Reserved2 = New Integer(3) {}     End Sub End Class  _ Private Class DRIVERSTATUS     Public DriveError As Byte     Public IDEStatus As Byte      _     Public Reserved As Byte()      _     Public Reserved2 As Integer()     Public Sub New()         Reserved = New Byte(1) {}         Reserved2 = New Integer(1) {}     End Sub End Class  _ Private Class IDSECTOR     Public GenConfig As Short     Public NumberCylinders As Short     Public Reserved As Short     Public NumberHeads As Short     Public BytesPerTrack As Short     Public BytesPerSector As Short     Public SectorsPerTrack As Short      _     Public VendorUnique As Short()      _     Public SerialNumber As Char()     Public BufferClass As Short     Public BufferSize As Short     Public ECCSize As Short      _     Public FirmwareRevision As Char()      _     Public ModelNumber As Char()     Public MoreVendorUnique As Short     Public DoubleWordIO As Short     Public Capabilities As Short     Public Reserved1 As Short     Public PIOTiming As Short     Public DMATiming As Short     Public BS As Short     Public NumberCurrentCyls As Short     Public NumberCurrentHeads As Short     Public NumberCurrentSectorsPerTrack As Short     Public CurrentSectorCapacity As Integer     Public MultipleSectorCapacity As Short     Public MultipleSectorStuff As Short     Public TotalAddressableSectors As Integer     Public SingleWordDMA As Short     Public MultiWordDMA As Short      _     Public Reserved2 As Byte() End Class  _ Private Class SENDCMDOUTPARAMS     Public BufferSize As Integer     Public Status As DRIVERSTATUS     Public IDS As IDSECTOR     Public Sub New()         Status = New DRIVERSTATUS()         IDS = New IDSECTOR()     End Sub End Class #End Region #Region " Methods and Functions " Private Shared Function SwapChars(ByVal chars As Char()) As String     For i As Integer = 0 To chars.Length - 2 Step 2         Dim t As Char         t = chars(i)         chars(i) = chars(i + 1)         chars(i + 1) = t     Next     Dim s As New String(chars)     Return s End Function Public Shared Function GetHDDInfoString() As String     Dim serialNumber As String = " ", model As String = " ", firmware As String = " "     Dim handle As Integer, returnSize As Integer = 0     Dim driveNumber As Integer = 0     Dim sci As New SENDCMDINPARAMS()     Dim sco As New SENDCMDOUTPARAMS()      If Environment.OSVersion.Platform = PlatformID.Win32NT Then         handle = CreateFile("\\.\PhysicalDrive" & "0", GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ + FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)     Else         handle = CreateFile("\\.\Smartvsd", 0, 0, 0, CREATE_NEW, 0, 0)     End If     If handle  INVALID_HANDLE_VALUE Then         sci.DriveNumber = CByte(driveNumber)         sci.BufferSize = Marshal.SizeOf(sco)         sci.DriveRegs.DriveHead = CByte((&HA0 Or driveNumber  0 Then             serialNumber = SwapChars(sco.IDS.SerialNumber)             model = SwapChars(sco.IDS.ModelNumber)             firmware = SwapChars(sco.IDS.FirmwareRevision)         End If         CloseHandle(handle)     End If     Return model.Trim & " " & serialNumber.Trim End Function #End Region End Class 


回答2:

Sorry I don't have time to convert it for you, but if nobody else comes up with the code, you could do worse than take a look at http://www.pinvoke.net. Your VB6 code has to call Windows API functions to do the work, and VB.NET code has to do the same. It will call the same API functions.

For example, here is the page for DeviceIoControl.

But if you wait long enough, somebody else might just have the code to hand :-)



回答3:

Try Dim Searcher_P As New ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_PhysicalMedia") For Each queryObj As ManagementObject In Searcher_P.Get() If queryObj("SerialNumber").ToString.Trim = "Y2S0RKFE" Then Me.Cursor = Cursors.Default Return True End If Next Catch ex As Exception MessageBox.Show("An error occurred while querying for WMI data: Win32_PhysicalMedia " & ex.Message) End Try  Try Dim Searcher_L As New ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_LogicalDisk WHERE DeviceID = 'C:'") For Each queryObj As ManagementObject In Searcher_L.Get() If queryObj("VolumeSerialNumber").ToString.Trim = "226C1A0B" Then Me.Cursor = Cursors.Default Return True End If Next Catch ex As Exception MessageBox.Show("An error occurred while querying for WMI data: VolumeSerialNumber " & ex.Message) Return False End Try 


回答4:

Yeah, I know VB6 but the problem is with the API function declarations and the attributes required to pass those structures (types) to them. That's where I don't have the time to spend! If you have an automated VB6 to VB.NET tool and VB6 itself, please save the code as a VB6 project and do convert the code. I don't have my VB6 around.



回答5:

That's a lot of code to wade through for someone who doesn't understand the spoken language used in the comments.

I will says this: Anywhere in that code you see the Type keyword you probably want to use Structure instead, the syntax used for Properties in .Net is a little different, function calls require parentheses, and VB.Net doesn't have an 'Any' type (maybe System.IntPtr instead? not sure).

Most of the rest of the syntax in VB.Net is the same, and so you might have better luck making the fixes I've already mentioned and then addressing each error (or type of error) you get when building the resulting code individually.



回答6:

You can get this data of WMI. Let me get you an example



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!