2012-08-08 91 views
-1

我发现了一种在vb6中获得硬盘序列号的方法。但需要选择如何获得当前的HDD类型?

  • 的主要主
  • 主要从
  • 副主
  • 次从属

一个选项,但我要自动选择一个选项。自动选择逻辑是,

假设我有4个硬盘与上述4种类型。逻辑将选择当前系统加载的硬盘类型。

我真的不知道如何检测当前系统是在哪种硬盘类型。请帮忙。

这里是我用来选择硬盘序列号的类。 HDSN CLASS

回答

1

下面的代码应该有所帮助:

Option Explicit 

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 IOCTL_VOLUME_BASE  As Long = 86 ' Asc("V") 
Private Const METHOD_BUFFERED  As Long = 0 
Private Const FILE_READ_ACCESS  As Long = 1 
Private Const FILE_ANY_ACCESS  As Long = 0 

'DEFINE IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS) 
Private Const IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = (((IOCTL_VOLUME_BASE) * (2&^16&)) Or ((FILE_ANY_ACCESS) * (2&^14&)) Or ((0&) * (2&^2&)) Or (METHOD_BUFFERED)) 

Private Type DISK_EXTENT 
    DiskNumber   As Long 
    StartingOffset  As Currency 
    ExtentLength  As Currency 
End Type 

Private Type VOLUME_DISK_EXTENTS 
    NumberOfDiskExtents As Currency 
    Extents(1 To 4)  As DISK_EXTENT 
End Type 

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 

Private Declare Function CloseHandle _ 
    Lib "kernel32" _ 
    (ByVal hObject As Long) As Long 

Private Declare Function GetWindowsDirectory Lib "Kernel32.dll" Alias "GetWindowsDirectoryW" (_ 
    ByVal lpBuffer As Long, _ 
    ByVal uSize As Long _ 
) As Long 

Private Declare Function DeviceIoControlNoInput _ 
    Lib "kernel32" Alias "DeviceIoControl" _ 
    (ByVal hDevice As Long, _ 
    ByVal dwIoControlCode As Long, _ 
    ByVal lpInBuffer As Long, _ 
    ByVal nInBufferSize As Long, _ 
    ByRef lpOutBuffer As Any, _ 
    ByVal nOutBufferSize As Long, _ 
    ByRef lpBytesReturned As Long, _ 
    ByVal lpOverlapped As Long) As Long 

' Return the index of the physical drive from which we've booted into Windows. 
Public Function GetBootPhysicalDrive() As Long 

    Dim sWindowsPath  As String 
    Dim nRet    As Long 
    Dim sDevicePath   As String 
    Dim hLogicalBootDrive As Long 
    Dim sVolumeDevice  As String 
    Dim uVolumeDiskExtents As VOLUME_DISK_EXTENTS 
    Dim nBytesReturned  As Long 

    ' Allocate space and retrieve the windows directory. 
    sWindowsPath = Space$(64) 
    nRet = GetWindowsDirectory(StrPtr(sWindowsPath), 64) 

    ' This gives us the volume that Windows is on. Open it. 
    sVolumeDevice = "\\.\" & Left$(sWindowsPath, 2) 
    hLogicalBootDrive = CreateFile(sVolumeDevice, GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ + FILE_SHARE_WRITE, 0&, OPEN_EXISTING, 0&, 0&) 

    ' Find out information about this volume. 
    nRet = DeviceIoControlNoInput(hLogicalBootDrive, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, 0&, 0&, uVolumeDiskExtents, LenB(uVolumeDiskExtents), nBytesReturned, 0&) 

    If nRet = 0 Then 
    ' Something went wrong. Return error value. 
     GetBootPhysicalDrive = -1 
    Else 
    ' This is the physical disk number. 
     GetBootPhysicalDrive = uVolumeDiskExtents.Extents(1).DiskNumber 
    End If 

    ' Close volume. 
    CloseHandle hLogicalBootDrive 

End Function 
+0

你能解释一下如何使用这段代码吗? – 2012-08-09 03:30:57

+0

干草我明白了。 '公共功能GetDiskSerialNumber()作为字符串 昏暗WmiObject可以作为对象 昏暗OBJ作为对象 集WmiObject可以= GetObject的( “WinMgmts:”) 对于每个物镜在wmiObject.InstancesOf( “Win32_PhysicalMedia”) 如果obj.Tag =“ \\。PHYSICALDRIVE“+ CStr(GetBootPhysicalDrive)Then GetDiskSerialNumber = obj.SerialNumber Next obj End Function' – 2012-08-10 20:10:24

0

用标志Bertenshaw的Above解决方案我写了一个模块在下面,只是叫GetDiskSerialNumber函数来获得硬盘的序列从当前系统引导。这里是我的模块代码:

Option Explicit 

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 IOCTL_VOLUME_BASE  As Long = 86 ' Asc("V") 
Private Const METHOD_BUFFERED  As Long = 0 
Private Const FILE_READ_ACCESS  As Long = 1 
Private Const FILE_ANY_ACCESS  As Long = 0 

'DEFINE IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS) 
Private Const IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = (((IOCTL_VOLUME_BASE) * (2&^16&)) Or ((FILE_ANY_ACCESS) * (2&^14&)) Or ((0&) * (2&^2&)) Or (METHOD_BUFFERED)) 

Private Type DISK_EXTENT 
    DiskNumber   As Long 
    StartingOffset  As Currency 
    ExtentLength  As Currency 
End Type 

Private Type VOLUME_DISK_EXTENTS 
    NumberOfDiskExtents As Currency 
    Extents(1 To 4)  As DISK_EXTENT 
End Type 

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 

Private Declare Function CloseHandle _ 
    Lib "kernel32" _ 
    (ByVal hObject As Long) As Long 

Private Declare Function GetWindowsDirectory Lib "Kernel32.dll" Alias "GetWindowsDirectoryW" (_ 
    ByVal lpBuffer As Long, _ 
    ByVal uSize As Long _ 
) As Long 

Private Declare Function DeviceIoControlNoInput _ 
    Lib "kernel32" Alias "DeviceIoControl" _ 
    (ByVal hDevice As Long, _ 
    ByVal dwIoControlCode As Long, _ 
    ByVal lpInBuffer As Long, _ 
    ByVal nInBufferSize As Long, _ 
    ByRef lpOutBuffer As Any, _ 
    ByVal nOutBufferSize As Long, _ 
    ByRef lpBytesReturned As Long, _ 
    ByVal lpOverlapped As Long) As Long 

' Return the index of the physical drive from which we've booted into Windows. 
Public Function GetBootPhysicalDrive() As Long 

    Dim sWindowsPath  As String 
    Dim nRet    As Long 
    Dim sDevicePath   As String 
    Dim hLogicalBootDrive As Long 
    Dim sVolumeDevice  As String 
    Dim uVolumeDiskExtents As VOLUME_DISK_EXTENTS 
    Dim nBytesReturned  As Long 

    ' Allocate space and retrieve the windows directory. 
    sWindowsPath = Space$(64) 
    nRet = GetWindowsDirectory(StrPtr(sWindowsPath), 64) 

    ' This gives us the volume that Windows is on. Open it. 
    sVolumeDevice = "\\.\" & Left$(sWindowsPath, 2) 
    hLogicalBootDrive = CreateFile(sVolumeDevice, GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ + FILE_SHARE_WRITE, 0&, OPEN_EXISTING, 0&, 0&) 

    ' Find out information about this volume. 
    nRet = DeviceIoControlNoInput(hLogicalBootDrive, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, 0&, 0&, uVolumeDiskExtents, LenB(uVolumeDiskExtents), nBytesReturned, 0&) 

    If nRet = 0 Then 
    ' Something went wrong. Return error value. 
     GetBootPhysicalDrive = -1 
    Else 
    ' This is the physical disk number. 
     GetBootPhysicalDrive = uVolumeDiskExtents.Extents(1).DiskNumber 
    End If 

    ' Close volume. 
    CloseHandle hLogicalBootDrive 

End Function 

Public Function GetDiskSerialNumber() As String 
    Dim wmiObject As Object 
    Dim obj As Object 

    Set wmiObject = GetObject("WinMgmts:") 
    For Each obj In wmiObject.InstancesOf("Win32_PhysicalMedia") 
     If obj.Tag = "\\.\PHYSICALDRIVE" + CStr(GetBootPhysicalDrive) Then GetDiskSerialNumber = obj.Tag + " : " + obj.SerialNumber 
    Next obj 
End Function 

非常感谢Mark Bertenshaw