2008-11-10 2 views
5

У меня классный кусок кода, взятый из проекта VC++, который получает полную информацию о жестком диске БЕЗ использования WMI (поскольку WMI имеет свои проблемы) Я прошу тех из вас, кто устраивает функции API, попытаться преобразовать этот код VB6 в VB (или C#) .NET и помочь МНОГО людей, которым очень нужен этот класс утилиты. Я потратил много времени и искал всю сеть, чтобы найти способы получить фактическую модель и серийный номер жесткого диска и в итоге нашел это, если бы он был только в .NET ... Вот код и жаль его проблемы форматирования, просто вставьте его в VB6 IDE:Преобразование жесткого диска Последовательный # VB6 код в код VB.NET

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 < 0 Or 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 
+0

Что не так с использованием WMI? – StingyJack

+0

Возможно, refactormycode.com может помочь больше –

+0

исправил форматирование кода - форматирование по умолчанию не очень хорошо справляется с vb. –

ответ

0

это много кода, чтобы вброд через кого-то, кто не понимает разговорный язык, используемый в комментариях.

Я буду говорит, что это: Нигде в этом коде вы видите Type ключевое слово вы, вероятно, хотите использовать Structure вместо этого, синтаксис, используемый для свойств в .Net немного отличается, вызовы функций требуют круглых скобок, и VB.Net Безразлично» t имеет тип «Любой» (возможно, System.IntPtr вместо этого не уверен).

Большая часть остального синтаксиса в VB.Net такая же, и поэтому вам может быть повезло с исправлениями, которые я уже упомянул, а затем адресовать каждую ошибку (или тип ошибки), возникающую при создании в результате код по отдельности.

0

Да, я знаю VB6, но проблема связана с объявлениями API-функций и атрибутами, необходимыми для передачи им этих структур (типов). Вот где у меня нет времени потратить! Если у вас есть автоматический инструмент VB6 для VB.NET и сам VB6, сохраните код в качестве проекта VB6 и преобразуйте его. У меня нет моего VB6.

+0

Кто жаловался на vb6? Вызов внешнего api из .Net работает почти так же, и я дал вам основные синтаксические различия, которые вам нужно будет обновить. Сделайте это, а затем опубликуйте, какие ошибки вы оставили в полученном коде. –

+0

Многие эквивалентные структуры, соответствующие типам, определенным в этом коде, не существуют в pInvoke.net. Где я могу их найти? –

1

Извините, у меня нет времени преобразовать его для вас, но если никто не придумает код, вы можете сделать хуже, чем взглянуть на http://www.pinvoke.net. Ваш код VB6 должен вызывать функции Windows API для выполнения работы, а код VB.NET должен делать то же самое. Он будет вызывать одни и те же функции API.

Например, here является страницей DeviceIoControl.

Но если вы достаточно долго ждать, кто-то может просто код, чтобы передать :-)

-1

Вы можете получить эти данные из WMI. Позвольте привезти вам пример

+0

Просто, чтобы уточнить ... из моего тестирования, WMI - это наименее надежная часть, созданная Microsoft (или кем бы то ни было). – newman

1
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 
+0

Вы видите это повсюду в Интернете. Но во многих ситуациях это не сработает и во многих случаях возвращает Null. Бьюсь об заклад, что сообщение «Ошибка произошло, когда ...» будет показано довольно часто!Это не то, что я хочу, и именно поэтому я искал дальнейший поиск того, что действительно выполняет свою работу. –

5

Я нашел его! Вот эквивалентный код VB.NET. Это не совсем конвертированная версия кода VB6, но делает то же самое. Наслаждайтесь!

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 
<System.Runtime.InteropServices.DllImport("kernel32.dll")> _ 
Private Shared Function CloseHandle(ByVal hObject As Integer) As Integer 
End Function 
<System.Runtime.InteropServices.DllImport("kernel32.dll")> _ 
Private Shared Function DeviceIoControl(ByVal hDevice As Integer, ByVal dwIoControlCode As Integer, <[In](), Out()> ByVal lpInBuffer As SENDCMDINPARAMS, ByVal lpInBufferSize As Integer, <[In](), Out()> 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 " 
<StructLayout(LayoutKind.Sequential, Size:=8)> _ 
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 
<StructLayout(LayoutKind.Sequential, Size:=32)> _ 
Private Class SENDCMDINPARAMS 
    Public BufferSize As Integer 
    Public DriveRegs As IDEREGS 
    Public DriveNumber As Byte 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> _ 
    Public Reserved As Byte() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _ 
    Public Reserved2 As Integer() 
    Public Sub New() 
     DriveRegs = New IDEREGS() 
     Reserved = New Byte(2) {} 
     Reserved2 = New Integer(3) {} 
    End Sub 
End Class 
<StructLayout(LayoutKind.Sequential, Size:=12)> _ 
Private Class DRIVERSTATUS 
    Public DriveError As Byte 
    Public IDEStatus As Byte 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _ 
    Public Reserved As Byte() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _ 
    Public Reserved2 As Integer() 
    Public Sub New() 
     Reserved = New Byte(1) {} 
     Reserved2 = New Integer(1) {} 
    End Sub 
End Class 
<StructLayout(LayoutKind.Sequential)> _ 
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 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> _ 
    Public VendorUnique As Short() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)> _ 
    Public SerialNumber As Char() 
    Public BufferClass As Short 
    Public BufferSize As Short 
    Public ECCSize As Short 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> _ 
    Public FirmwareRevision As Char() 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=40)> _ 
    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 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=382)> _ 
    Public Reserved2 As Byte() 
End Class 
<StructLayout(LayoutKind.Sequential)> _ 
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 << 4)) 
     sci.DriveRegs.Command = &HEC 
     sci.DriveRegs.SectorCount = 1 
     sci.DriveRegs.SectorNumber = 1 
     If DeviceIoControl(handle, DFP_RECEIVE_DRIVE_DATA, sci, Marshal.SizeOf(sci), sco, Marshal.SizeOf(sco), _ 
     returnSize, 0) <> 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 
+1

Кто-нибудь получил этот код, переведенный на C#? – newman

Смежные вопросы