【问题标题】:Get information about disk drives result on windows7 - 32 bit system获取有关 Windows 7 - 32 位系统上的磁盘驱动器结果的信息
【发布时间】:2010-06-23 03:13:48
【问题描述】:

当我在 windows XP - 32 上运行以下代码时,我得到以下结果。

我只插入了一个 USB 笔式驱动器

On Windows XP - 32 Bit
-----------------------

Drive C:
    ProductId: ST3160215AS
    ProductRevision: 3.AAD
    DeviceType: 7, DeviceNumber: 0, PartitionNumber: 1
    DevicePath: \\?\ide#diskst3160215as_____________________________3.aad___#5&2
7db0ed4&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: IDE\DiskST3160215AS_____________________________3.AAD___
    Friendly Name: ST3160215AS
    Physical Device Object Name: \Device\Ide\IdeDeviceP2T0L0-5
    Device Description: Disk drive
    Parent Device Instance ID: PCIIDE\IDECHANNEL\4&1C1E8A11&0&0
    Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_72671462&R
EV_01\3&11583659&0&FA
    DeviceInstanceId: IDE\DISKST3160215AS_____________________________3.AAD___\5
&27DB0ED4&0&0.0.0
Drive D:
    ProductId: ST3160215AS
    ProductRevision: 3.AAD
    DeviceType: 7, DeviceNumber: 0, PartitionNumber: 2
    DevicePath: \\?\ide#diskst3160215as_____________________________3.aad___#5&2
7db0ed4&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: IDE\DiskST3160215AS_____________________________3.AAD___
    Friendly Name: ST3160215AS
    Physical Device Object Name: \Device\Ide\IdeDeviceP2T0L0-5
    Device Description: Disk drive
    Parent Device Instance ID: PCIIDE\IDECHANNEL\4&1C1E8A11&0&0
    Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_72671462&R
EV_01\3&11583659&0&FA
    DeviceInstanceId: IDE\DISKST3160215AS_____________________________3.AAD___\5
&27DB0ED4&0&0.0.0
Drive E:
    ProductId: ST3160215AS
    ProductRevision: 3.AAD
    DeviceType: 7, DeviceNumber: 0, PartitionNumber: 3
    DevicePath: \\?\ide#diskst3160215as_____________________________3.aad___#5&2
7db0ed4&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: IDE\DiskST3160215AS_____________________________3.AAD___
    Friendly Name: ST3160215AS
    Physical Device Object Name: \Device\Ide\IdeDeviceP2T0L0-5
    Device Description: Disk drive
    Parent Device Instance ID: PCIIDE\IDECHANNEL\4&1C1E8A11&0&0
    Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_72671462&R
EV_01\3&11583659&0&FA
    DeviceInstanceId: IDE\DISKST3160215AS_____________________________3.AAD___\5
&27DB0ED4&0&0.0.0
Drive F:
    ProductId: ST3160215AS
    ProductRevision: 3.AAD
    DeviceType: 7, DeviceNumber: 0, PartitionNumber: 4
    DevicePath: \\?\ide#diskst3160215as_____________________________3.aad___#5&2
7db0ed4&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: IDE\DiskST3160215AS_____________________________3.AAD___
    Friendly Name: ST3160215AS
    Physical Device Object Name: \Device\Ide\IdeDeviceP2T0L0-5
    Device Description: Disk drive
    Parent Device Instance ID: PCIIDE\IDECHANNEL\4&1C1E8A11&0&0
    Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_72671462&R
EV_01\3&11583659&0&FA
    DeviceInstanceId: IDE\DISKST3160215AS_____________________________3.AAD___\5
&27DB0ED4&0&0.0.0
Drive G:
    VendorId: JetFlash
    ProductId: Transcend 2GB
    ProductRevision: 8.07
    DeviceType: 7, DeviceNumber: 1, PartitionNumber: 1
    DevicePath: \\?\usbstor#disk&ven_jetflash&prod_transcend_2gb&rev_8.07#e3o29u
13&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: USBSTOR\DiskJetFlashTranscend_2GB___8.07
    Friendly Name: JetFlash Transcend 2GB USB Device
    Physical Device Object Name: \Device\00000080
    Device Description: Disk drive
    Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13
    Parent of Parent Device Instance ID: USB\ROOT_HUB20\4&2B6971CE&0
    DeviceInstanceId: USBSTOR\DISK&VEN_JETFLASH&PROD_TRANSCEND_2GB&REV_8.07\E3O2
9U13&0
    Drive G: is removeable
Drive X:

When i run the below code on windows7 - 32 , i get the below result

i have plugged the same usb pen drive which is used on windows xp - 32 bit...

On Windows 7 - 32 Bit
-----------------------

Drive C:
    ProductId: Hitachi HDS721616PLA380
    ProductRevision: P22OAB3A
    DeviceType: 7, DeviceNumber: 0, PartitionNumber: 2
    DevicePath: \\?\ide#diskhitachi_hds721616pla380_________________p22oab3a#5&4
be38f&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: USBSTOR\DiskJetFlashTranscend_2GB___8.07
    Friendly Name: JetFlash Transcend 2GB USB Device
    Physical Device Object Name: \Device\0000006f
    Device Description: Disk drive
    Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13
    Parent of Parent Device Instance ID: USB\ROOT_HUB20\4&4E31217&0
    DeviceInstanceId: USBSTOR\DISK&VEN_JETFLASH&PROD_TRANSCEND_2GB&REV_8.07\E3O2
9U13&0
    Drive C: is removeable
Drive D:
    ProductId: Hitachi HDS721616PLA380
    ProductRevision: P22OAB3A
    DeviceType: 7, DeviceNumber: 0, PartitionNumber: 3
    DevicePath: \\?\ide#diskhitachi_hds721616pla380_________________p22oab3a#5&4
be38f&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: USBSTOR\DiskJetFlashTranscend_2GB___8.07
    Friendly Name: JetFlash Transcend 2GB USB Device
    Physical Device Object Name: \Device\0000006f
    Device Description: Disk drive
    Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13
    Parent of Parent Device Instance ID: USB\ROOT_HUB20\4&4E31217&0
    DeviceInstanceId: USBSTOR\DISK&VEN_JETFLASH&PROD_TRANSCEND_2GB&REV_8.07\E3O2
9U13&0
    Drive D: is removeable
Drive E:
    ProductId: Hitachi HDS721616PLA380
    ProductRevision: P22OAB3A
    DeviceType: 7, DeviceNumber: 0, PartitionNumber: 4
    DevicePath: \\?\ide#diskhitachi_hds721616pla380_________________p22oab3a#5&4
be38f&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: USBSTOR\DiskJetFlashTranscend_2GB___8.07
    Friendly Name: JetFlash Transcend 2GB USB Device
    Physical Device Object Name: \Device\0000006f
    Device Description: Disk drive
    Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13
    Parent of Parent Device Instance ID: USB\ROOT_HUB20\4&4E31217&0
    DeviceInstanceId: USBSTOR\DISK&VEN_JETFLASH&PROD_TRANSCEND_2GB&REV_8.07\E3O2
9U13&0
    Drive E: is removeable
Drive F:
    ProductId: Hitachi HDS721616PLA380
    ProductRevision: P22OAB3A
    DeviceType: 7, DeviceNumber: 0, PartitionNumber: 5
    DevicePath: \\?\ide#diskhitachi_hds721616pla380_________________p22oab3a#5&4
be38f&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: USBSTOR\DiskJetFlashTranscend_2GB___8.07
    Friendly Name: JetFlash Transcend 2GB USB Device
    Physical Device Object Name: \Device\0000006f
    Device Description: Disk drive
    Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13
    Parent of Parent Device Instance ID: USB\ROOT_HUB20\4&4E31217&0
    DeviceInstanceId: USBSTOR\DISK&VEN_JETFLASH&PROD_TRANSCEND_2GB&REV_8.07\E3O2
9U13&0
    Drive F: is removeable
Drive G:
    VendorId: JetFlash
    ProductId: Transcend 2GB
    ProductRevision: 8.07
    DeviceType: 7, DeviceNumber: 1, PartitionNumber: 1
    DevicePath: \\?\usbstor#disk&ven_jetflash&prod_transcend_2gb&rev_8.07#e3o29u
13&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: IDE\DiskHitachi_HDS721616PLA380_________________P22OAB3A
    Friendly Name: Hitachi HDS721616PLA380 ATA Device
    Physical Device Object Name: \Device\Ide\IdeDeviceP1T0L0-1
    Device Description: Disk drive
    Parent Device Instance ID: PCIIDE\IDECHANNEL\4&35CD87E&0&0
    Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_27C08086&R
EV_01\3&2411E6FE&1&FA
    DeviceInstanceId: IDE\DISKHITACHI_HDS721616PLA380_________________P22OAB3A\5
&4BE38F&0&0.0.0
    Drive G: is removeable
Drive Z:

块引用

---------------------------------------------------------------------------------

请看两个结果...

我在两个系统(xp 和 windows7)上都插入了相同的 USB 设备,但结果各不相同...

请检查驱动器 G:两个操作系统上的结果...

Drive G: ( On Windows 7 - 32 bit )
-----------------------------------

VendorId: JetFlash
    ProductId: Transcend 2GB
    ProductRevision: 8.07
    DeviceType: 7, DeviceNumber: 1, PartitionNumber: 1
    DevicePath: \\?\usbstor#disk&ven_jetflash&prod_transcend_2gb&rev_8.07#e3o29u
13&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: IDE\DiskHitachi_HDS721616PLA380_________________P22OAB3A
    Friendly Name: Hitachi HDS721616PLA380 ATA Device
    Physical Device Object Name: \Device\Ide\IdeDeviceP1T0L0-1
    Device Description: Disk drive
    Parent Device Instance ID: PCIIDE\IDECHANNEL\4&35CD87E&0&0
    Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_27C08086&R
EV_01\3&2411E6FE&1&FA
    DeviceInstanceId: IDE\DISKHITACHI_HDS721616PLA380_________________P22OAB3A\5
&4BE38F&0&0.0.0
    Drive G: is removeable

Drive G: ( On Windows XP - 32 bit )
-----------------------------------
VendorId: JetFlash
    ProductId: Transcend 2GB
    ProductRevision: 8.07
    DeviceType: 7, DeviceNumber: 1, PartitionNumber: 1
    DevicePath: \\?\usbstor#disk&ven_jetflash&prod_transcend_2gb&rev_8.07#e3o29u
13&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
    Class: DiskDrive
    Hardware ID: USBSTOR\DiskJetFlashTranscend_2GB___8.07
    Friendly Name: JetFlash Transcend 2GB USB Device
    Physical Device Object Name: \Device\00000080
    Device Description: Disk drive
    Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13
    Parent of Parent Device Instance ID: USB\ROOT_HUB20\4&2B6971CE&0
    DeviceInstanceId: USBSTOR\DISK&VEN_JETFLASH&PROD_TRANSCEND_2GB&REV_8.07\E3O2
9U13&0
    Drive G: is removeable

感谢您的帮助

【问题讨论】:

    标签: windows winapi msdn


    【解决方案1】:

    我用 C 语言编写了一个程序,演示如何接收您需要的信息

    #include <windows.h>
    #include <devguid.h>    // for GUID_DEVCLASS_CDROM etc
    #include <setupapi.h>
    #include <cfgmgr32.h>   // for MAX_DEVICE_ID_LEN, CM_Get_Parent and CM_Get_Device_ID
    #include <tchar.h>
    #include <stdio.h>
    
    #define ARRAY_SIZE(arr)     (sizeof(arr)/sizeof(arr[0]))
    
    #pragma comment (lib, "setupapi.lib")
    
    //
    // Define the various device characteristics flags (defined in wdm.h)
    //
    #define FILE_REMOVABLE_MEDIA                    0x00000001
    #define FILE_READ_ONLY_DEVICE                   0x00000002
    #define FILE_FLOPPY_DISKETTE                    0x00000004
    #define FILE_WRITE_ONCE_MEDIA                   0x00000008
    #define FILE_REMOTE_DEVICE                      0x00000010
    #define FILE_DEVICE_IS_MOUNTED                  0x00000020
    #define FILE_VIRTUAL_VOLUME                     0x00000040
    #define FILE_AUTOGENERATED_DEVICE_NAME          0x00000080
    #define FILE_DEVICE_SECURE_OPEN                 0x00000100
    #define FILE_CHARACTERISTIC_PNP_DEVICE          0x00000800
    #define FILE_CHARACTERISTIC_TS_DEVICE           0x00001000
    #define FILE_CHARACTERISTIC_WEBDAV_DEVICE       0x00002000
    
    #pragma warning (disable: 4201)
    typedef struct _IO_STATUS_BLOCK {
        union {
            NTSTATUS Status;
            PVOID Pointer;
        } DUMMYUNIONNAME;
    
        ULONG_PTR Information;
    } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
    #pragma warning (default: 4201)
    
    typedef enum _FSINFOCLASS {
        FileFsVolumeInformation       = 1,
        FileFsLabelInformation,      // 2
        FileFsSizeInformation,       // 3
        FileFsDeviceInformation,     // 4
        FileFsAttributeInformation,  // 5
        FileFsControlInformation,    // 6
        FileFsFullSizeInformation,   // 7
        FileFsObjectIdInformation,   // 8
        FileFsDriverPathInformation, // 9
        FileFsVolumeFlagsInformation,// 10
        FileFsMaximumInformation
    } FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
    
    typedef struct _FILE_FS_DEVICE_INFORMATION {
        DEVICE_TYPE DeviceType;
        ULONG Characteristics;
    } FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
    
    typedef NTSTATUS (NTAPI *LPFN_NT_QUERY_VOLUME_INFORMATION_FILE) (HANDLE FileHandle,
                                                                     PIO_STATUS_BLOCK IoStatusBlock,
                                                                     PVOID FsInformation, ULONG Length,
                                                                     FS_INFORMATION_CLASS FsInformationClass);
    
    BOOL GetDriveTypeAndCharacteristics (HANDLE hDevice, DEVICE_TYPE *pDeviceType, ULONG *pCharacteristics)
    {
        HMODULE hNtDll;
        LPFN_NT_QUERY_VOLUME_INFORMATION_FILE lpfnNtQueryVolumeInformationFile;
        NTSTATUS ntStatus;
        IO_STATUS_BLOCK IoStatusBlock;
        FILE_FS_DEVICE_INFORMATION FileFsDeviceInfo;
        BOOL bSuccess = FALSE;
    
        hNtDll = GetModuleHandle (TEXT("ntdll.dll"));
        if (hNtDll == NULL)
            return FALSE;
    
        lpfnNtQueryVolumeInformationFile = (LPFN_NT_QUERY_VOLUME_INFORMATION_FILE)GetProcAddress (hNtDll, "NtQueryVolumeInformationFile");
        if (lpfnNtQueryVolumeInformationFile == NULL)
            return FALSE;
    
        ntStatus = lpfnNtQueryVolumeInformationFile (hDevice, &IoStatusBlock,
                                                     &FileFsDeviceInfo, sizeof(FileFsDeviceInfo),
                                                     FileFsDeviceInformation);
        if (ntStatus == NO_ERROR) {
            bSuccess = TRUE;
            *pDeviceType = FileFsDeviceInfo.DeviceType;
            *pCharacteristics = FileFsDeviceInfo.Characteristics;
        }
    
        return bSuccess;
    }
    
    void FildVolumeName (LPCTSTR pszDeviceName)
    {
        TCHAR szVolumeName[MAX_PATH] = TEXT("");
        TCHAR szDeviceName[MAX_PATH] = TEXT("");
        HANDLE hFind = INVALID_HANDLE_VALUE;
        DWORD dwCharCount;
        BOOL bSuccess;
    
        hFind = FindFirstVolume (szVolumeName, ARRAYSIZE(szVolumeName));
        if (hFind == INVALID_HANDLE_VALUE) return;
    
        while(TRUE) {
            //  Skip the \\?\ prefix and remove the trailing backslash.
            size_t Index = lstrlen(szVolumeName) - 1;
            if (szVolumeName[0]     != TEXT('\\') ||
                szVolumeName[1]     != TEXT('\\') ||
                szVolumeName[2]     != TEXT('?')  ||
                szVolumeName[3]     != TEXT('\\') ||
                szVolumeName[Index] != TEXT('\\')) return; // error
    
            //  QueryDosDeviceW doesn't allow a trailing backslash,
            //  so temporarily remove it.
            szVolumeName[Index] = TEXT('\0');
            dwCharCount = QueryDosDevice (&szVolumeName[4], szDeviceName, ARRAYSIZE(szDeviceName));
            szVolumeName[Index] = TEXT('\\');
            if (dwCharCount == 0) return; // error
    
            if (lstrcmp (pszDeviceName, szDeviceName) == 0) {
                _tprintf (TEXT("    Volume Device Name: %s\n"), szVolumeName);
                return;
            }
    
            bSuccess = FindNextVolume (hFind, szVolumeName, ARRAYSIZE(szVolumeName));
            if (!bSuccess) {
                DWORD dwErrorCode = GetLastError();
                if (dwErrorCode == ERROR_NO_MORE_ITEMS)
                    break;
                else 
                    break;  // ERROR!!!
            }
        }
    }
    
    void DumpVidPidMi (LPCTSTR pszDeviceInstanceId)
    {
        TCHAR szDeviceInstanceId[MAX_DEVICE_ID_LEN];
        const static LPCTSTR arPrefix[3] = {TEXT("VID_"), TEXT("PID_"), TEXT("MI_")};
        LPTSTR pszToken, pszNextToken;
        int j;
    
        lstrcpy (szDeviceInstanceId, pszDeviceInstanceId);
    
        pszToken = _tcstok_s (szDeviceInstanceId , TEXT("\\#&"), &pszNextToken);
        while(pszToken != NULL) {
            for (j = 0; j < 3; j++) {
                if (_tcsncmp(pszToken, arPrefix[j], lstrlen(arPrefix[j])) == 0) {
                    switch(j) {
                        case 0:
                            _tprintf (TEXT("        vid: \"%s\"\n"), pszToken + lstrlen(arPrefix[j]));
                            break;
                        case 1:
                            _tprintf (TEXT("        pid: \"%s\"\n"), pszToken + lstrlen(arPrefix[j]));
                            break;
                        case 2:
                            _tprintf (TEXT("        mi: \"%s\"\n"), pszToken + lstrlen(arPrefix[j]));
                            break;
                        default:
                            break;
                    }
                }
            }
            pszToken = _tcstok_s (NULL, TEXT("\\#&"), &pszNextToken);
        }
    }
    
    BOOL FindDiInfos (LPCGUID pGuidInferface, LPCGUID pGuidClass, LPCTSTR pszEnumerator,
                      DEVICE_TYPE DeviceType, DWORD DeviceNumber,
                      DWORD dwDeviceInstanceIdSize,     // MAX_DEVICE_ID_LEN
                      OUT LPTSTR pszDeviceInstanceId,
                      OUT PDWORD pdwRemovalPolicy)
    //#define CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL             1
    //#define CM_REMOVAL_POLICY_EXPECT_ORDERLY_REMOVAL        2
    //#define CM_REMOVAL_POLICY_EXPECT_SURPRISE_REMOVAL       3
    {
        HDEVINFO hIntDevInfo = NULL;
        DWORD dwIndex;
        BOOL bFound = FALSE; 
        HANDLE hDev = INVALID_HANDLE_VALUE;
        PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL;
    
        // set defaults
        *pdwRemovalPolicy = 0;
        pszDeviceInstanceId[0] = TEXT('\0');
    
        __try {
            hIntDevInfo = SetupDiGetClassDevs (pGuidInferface, pszEnumerator, NULL,
                                               pGuidInferface != NULL? DIGCF_PRESENT | DIGCF_DEVICEINTERFACE:
                                                                       DIGCF_ALLCLASSES | DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
            if (hIntDevInfo == INVALID_HANDLE_VALUE)
                __leave;
    
            for (dwIndex = 0; ;dwIndex ++) {
                SP_DEVICE_INTERFACE_DATA interfaceData;
                SP_DEVINFO_DATA deviceInfoData;
                DWORD dwDataType, dwRequiredSize;
                BOOL bSuccess;
    
                ZeroMemory (&interfaceData, sizeof(interfaceData));
                interfaceData.cbSize = sizeof(interfaceData);
                bSuccess = SetupDiEnumDeviceInterfaces (hIntDevInfo, NULL, pGuidInferface, dwIndex, &interfaceData);
                if (!bSuccess) {
                    DWORD dwErrorCode = GetLastError();
                    if (dwErrorCode == ERROR_NO_MORE_ITEMS)
                        break;
                    else 
                        break;  // ERROR!!!
                }
    
                dwRequiredSize = 0;
                bSuccess = SetupDiGetDeviceInterfaceDetail (hIntDevInfo, &interfaceData, NULL, 0, &dwRequiredSize, NULL);
                if ((!bSuccess && GetLastError() != ERROR_INSUFFICIENT_BUFFER) || dwRequiredSize == 0)
                    continue;  // ERROR!!!
    
                if (pInterfaceDetailData)
                    pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalFree (pInterfaceDetailData);
    
                pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalAlloc (LPTR, dwRequiredSize);
                pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
                ZeroMemory (&deviceInfoData, sizeof(deviceInfoData));
                deviceInfoData.cbSize = sizeof(deviceInfoData);
                bSuccess = SetupDiGetDeviceInterfaceDetail (hIntDevInfo, &interfaceData,
                                                            pInterfaceDetailData, dwRequiredSize, &dwRequiredSize, &deviceInfoData);
                if (!bSuccess)
                    continue;
    
                hDev = CreateFile (pInterfaceDetailData->DevicePath, 
                                   0,                                   // no access to the drive
                                   FILE_SHARE_READ | FILE_SHARE_WRITE,  // share mode
                                   NULL,                                // default security attributes
                                   OPEN_EXISTING,                       // disposition
                                   0,                                   // file attributes
                                   NULL);                               // do not copy file attributes
                if (hDev != INVALID_HANDLE_VALUE) {
                    STORAGE_DEVICE_NUMBER sdn;
                    DWORD cbBytesReturned;
                    bSuccess = DeviceIoControl (hDev,                           // device to be queried
                                                IOCTL_STORAGE_GET_DEVICE_NUMBER, 
                                                NULL, 0,                        // no input buffer
                                                (LPVOID)&sdn, sizeof(sdn),      // output buffer
                                                &cbBytesReturned,               // # bytes returned
                                                (LPOVERLAPPED) NULL);           // synchronous I/O
                    if (bSuccess) {
                        if (sdn.DeviceType == DeviceType &&
                            sdn.DeviceNumber == DeviceNumber) {
    
                            DEVINST dnDevInstParent, dnDevInstParentParent;
                            CONFIGRET ret;
                            // device found !!!
                            TCHAR szBuffer[4096];
    
                            _tprintf (TEXT("    DevicePath: %s\n"), pInterfaceDetailData->DevicePath);
    
                            bSuccess = SetupDiGetDeviceInstanceId (hIntDevInfo, &deviceInfoData, pszDeviceInstanceId,
                                                                   dwDeviceInstanceIdSize, &dwRequiredSize);
                            if (dwRequiredSize > MAX_DEVICE_ID_LEN)
                                continue;
    
                            bSuccess = SetupDiGetDeviceRegistryProperty (hIntDevInfo, &deviceInfoData, SPDRP_REMOVAL_POLICY, &dwDataType,
                                                                         (PBYTE)pdwRemovalPolicy, sizeof(DWORD), &dwRequiredSize);
                            // SPDRP_CHARACTERISTICS - Device characteristics
                            //         FILE_FLOPPY_DISKETTE, FILE_REMOVABLE_MEDIA, and FILE_WRITE_ONCE_MEDIA characteristics 
                            //         FILE_READ_ONLY_DEVICE
                            bSuccess = SetupDiGetDeviceRegistryProperty (hIntDevInfo, &deviceInfoData, SPDRP_CLASS, &dwDataType,
                                                                         (PBYTE)szBuffer, sizeof(szBuffer), &dwRequiredSize);
                            if (bSuccess)
                                _tprintf (TEXT("    Class: \"%s\"\n"), szBuffer);
                            bSuccess = SetupDiGetDeviceRegistryProperty (hIntDevInfo, &deviceInfoData, SPDRP_HARDWAREID, &dwDataType,
                                                                         (PBYTE)szBuffer, sizeof(szBuffer), &dwRequiredSize);
                            if (bSuccess) {
                                LPCTSTR pszId;
                                _tprintf (TEXT("    Hardware IDs:\n"));
                                for (pszId=szBuffer;
                                     *pszId != TEXT('\0') && pszId + dwRequiredSize/sizeof(TCHAR) <= szBuffer + ARRAYSIZE(szBuffer);
                                     pszId += lstrlen(pszId)+1) {
    
                                    _tprintf (TEXT("        \"%s\"\n"), pszId);
                                }
                            }
                            bSuccess = SetupDiGetDeviceRegistryProperty (hIntDevInfo, &deviceInfoData, SPDRP_FRIENDLYNAME, &dwDataType,
                                                                         (PBYTE)szBuffer, sizeof(szBuffer), &dwRequiredSize);
                            if (bSuccess)
                                _tprintf (TEXT("    Friendly Name: \"%s\"\n"), szBuffer);
    
                            bSuccess = SetupDiGetDeviceRegistryProperty (hIntDevInfo, &deviceInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, &dwDataType,
                                                                         (PBYTE)szBuffer, sizeof(szBuffer), &dwRequiredSize);
                            if (bSuccess)
                                _tprintf (TEXT("    Physical Device Object Name: \"%s\"\n"), szBuffer);
    
                            bSuccess = SetupDiGetDeviceRegistryProperty (hIntDevInfo, &deviceInfoData, SPDRP_DEVICEDESC, &dwDataType,
                                                                         (PBYTE)szBuffer, sizeof(szBuffer), &dwRequiredSize);
                            if (bSuccess)
                                _tprintf (TEXT("    Device Description: \"%s\"\n"), szBuffer);
                            bFound = TRUE;
    
                            ret = CM_Get_Parent (&dnDevInstParent, deviceInfoData.DevInst, 0);
                            if (ret == CR_SUCCESS) {
                                TCHAR szDeviceInstanceID[MAX_DEVICE_ID_LEN];
                                ret = CM_Get_Device_ID (dnDevInstParent, szDeviceInstanceID, ARRAY_SIZE(szDeviceInstanceID), 0);
                                if (ret == CR_SUCCESS) {
                                    _tprintf (TEXT("    Parent Device Instance ID: %s\n"), szDeviceInstanceID);
                                    DumpVidPidMi (szDeviceInstanceID);
                                    ret = CM_Get_Parent (&dnDevInstParentParent, dnDevInstParent, 0);
                                    if (ret == CR_SUCCESS) {
                                        ret = CM_Get_Device_ID (dnDevInstParentParent, szDeviceInstanceID, ARRAY_SIZE(szDeviceInstanceID), 0);
                                        if (ret == CR_SUCCESS)
                                            _tprintf (TEXT("    Parent of Parent Device Instance ID: %s\n"), szDeviceInstanceID);
                                    }
                                }
                            }
                            break;
                        }
                    }
    
                    CloseHandle (hDev);
                    hDev = INVALID_HANDLE_VALUE;
                }
            }
        }
        __finally {
            if (pInterfaceDetailData)
                pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalFree (pInterfaceDetailData);
    
            if (hDev != INVALID_HANDLE_VALUE)
                CloseHandle (hDev);
    
            if (hIntDevInfo)
                SetupDiDestroyDeviceInfoList (hIntDevInfo);
        }
    
        return bFound;
    }
    
    LPCTSTR DumpBusTypeAsString (STORAGE_BUS_TYPE type)
    {
        const static LPCTSTR arStorageBusTypeNames[] = {
            TEXT("Unknown"),                    // BusTypeUnknown = 0
            TEXT("SCSI"),                       // BusTypeScsi = 1
            TEXT("ATAPI"),                      // BusTypeAtapi = 2
            TEXT("ATA"),                        // BusTypeAta = 3
            TEXT("IEEE-1394"),                  // BusType1394 = 4
            TEXT("SSA"),                        // BusTypeSsa = 5
            TEXT("Fibre Channel"),              // BusTypeFibre = 6
            TEXT("USB"),                        // BusTypeUsb = 7
            TEXT("RAID"),                       // BusTypeRAID = 8
            TEXT("iSCSI"),                      // BusTypeiScsi = 9
            TEXT("Serial Attached SCSI (SAS)"), // BusTypeSas = 10
            TEXT("SATA"),                       // BusTypeSata = 11
            TEXT("SD"),                         // BusTypeSd = 12
            TEXT("MMC"),                        // BusTypeMmc = 13
            TEXT("Virtual"),                    // BusTypeVirtual = 14
            TEXT("FileBackedVirtual")           // BusTypeFileBackedVirtual = 15
        };
    
        if (type <= BusTypeFileBackedVirtual)
            return arStorageBusTypeNames[type];
        else
            return NULL;
    }
    
    int main()
    {
        HANDLE hDevice; 
        DWORD cbBytesReturned;
        STORAGE_DEVICE_NUMBER sdn;
        BOOL bSuccess;
        LPTSTR pszLogicalDrives, pszDriveRoot;
        TCHAR szDeviceInstanceId[MAX_DEVICE_ID_LEN];
        GUID *pGuidInferface = NULL, *pGuidClass = NULL;
        LPCTSTR pszEnumerator = NULL;
        TCHAR szVolumeName[MAX_PATH+1], szFileSystemName[MAX_PATH+1], szNtDeviceName[MAX_PATH+1];
        //TCHAR szVolumeSerialNumber[1024];
        DWORD dwVolumeSerialNumber, dwMaximumComponentLength, dwFileSystemFlags;
        //HMODULE hm = LoadLibrary (TEXT("C:\\Program Files\\Microsoft Office\\Office14\\OUTLOOK.EXE"));
    
        __try {
            //pszEnumerator = TEXT("USB");
    
            cbBytesReturned = GetLogicalDriveStrings (0, NULL);
            pszLogicalDrives = (LPTSTR) LocalAlloc (LMEM_ZEROINIT,
                                                    cbBytesReturned*sizeof(TCHAR));
            cbBytesReturned = GetLogicalDriveStrings (cbBytesReturned,
                                                      pszLogicalDrives);
            for (pszDriveRoot = pszLogicalDrives; *pszDriveRoot != TEXT('\0');
                 pszDriveRoot += lstrlen(pszDriveRoot) + 1) {
    
                TCHAR szDeviceName[7] = TEXT("\\\\.\\");
                BOOL bIsRemoveable = FALSE;
                DWORD dwRemovalPolicy;
                STORAGE_PROPERTY_QUERY spq;
                BYTE byBuffer[4096];
                //ULONG ulOutBuffer;
    
                szDeviceName[4] = pszDriveRoot[0];
                szDeviceName[5] = TEXT(':');
                szDeviceName[6] = TEXT('\0');
                _tprintf (TEXT("Drive %c:\n"), pszDriveRoot[0]);
    
                // see http://msdn.microsoft.com/en-us/library/cc542456.aspx
                // how to find Volume name: \\?\Volume{4c1b02c1-d990-11dc-99ae-806e6f6e6963}\
                // for the Paths:  C:\
                // or device name like \Device\HarddiskVolume2 or \Device\CdRom0
                cbBytesReturned = QueryDosDevice (&szDeviceName[4], szNtDeviceName, ARRAYSIZE(szNtDeviceName));
                if (cbBytesReturned) {
                    _tprintf (TEXT("    Dos Device Name: %s\n"), szNtDeviceName);
                    FildVolumeName(szNtDeviceName);
                }
    
                bSuccess = GetVolumeInformation (pszDriveRoot, szVolumeName, ARRAYSIZE(szVolumeName),
                    &dwVolumeSerialNumber, &dwMaximumComponentLength, &dwFileSystemFlags,
                    szFileSystemName, ARRAYSIZE(szFileSystemName));
                if (bSuccess) {
                    _tprintf (TEXT("    Volume Name: \"%s\"\n"), szVolumeName);
                }
    
                hDevice = CreateFile (szDeviceName,
                                      //FILE_READ_DATA, //0 - no access to the drive, for IOCTL_STORAGE_CHECK_VERIFY is FILE_READ_DATA needed
                                      FILE_READ_ATTRIBUTES, // for IOCTL_STORAGE_CHECK_VERIFY2
                                      FILE_SHARE_READ | FILE_SHARE_WRITE,   // share mode
                                      NULL, OPEN_EXISTING, 0, NULL);
                if (hDevice == INVALID_HANDLE_VALUE)
                    __leave;
    
                bIsRemoveable = FALSE;
    
                spq.PropertyId = StorageDeviceProperty;
                spq.QueryType = PropertyStandardQuery;
                spq.AdditionalParameters[0] = 0;
                bSuccess = DeviceIoControl (hDevice,                         // device to be queried
                                            IOCTL_STORAGE_QUERY_PROPERTY,    // operation to perform
                                            &spq, sizeof(spq),               // input buffer
                                            &byBuffer, sizeof(byBuffer),     // output buffer
                                            &cbBytesReturned,                // # bytes returned
                                            (LPOVERLAPPED) NULL);            // synchronous I/O
                if (bSuccess) {
                    STORAGE_DEVICE_DESCRIPTOR *psdp = (STORAGE_DEVICE_DESCRIPTOR *)byBuffer;
                    LPCTSTR pszBusType = DumpBusTypeAsString(psdp->BusType);
                    if (pszBusType)
                        _tprintf (TEXT("    Bus Type: %s\n"), pszBusType);
                    else
                        _tprintf (TEXT("    Bus Type: Unknown (%d)\n"), psdp->BusType);
                    if (psdp->VendorIdOffset)
                        _tprintf (TEXT("    VendorId: \"%hs\"\n"), (LPCSTR)((PBYTE)psdp + psdp->VendorIdOffset));
                    if (psdp->ProductIdOffset)
                        _tprintf (TEXT("    ProductId: \"%hs\"\n"), (LPCSTR)((PBYTE)psdp + psdp->ProductIdOffset));
                    if (psdp->ProductRevisionOffset)
                        _tprintf (TEXT("    ProductRevision: \"%hs\"\n"), (LPCSTR)((PBYTE)psdp + psdp->ProductRevisionOffset));
    
                    if (psdp->RemovableMedia)
                        bIsRemoveable = TRUE;
                }
    
                cbBytesReturned = 0;
                bSuccess = DeviceIoControl (hDevice,                     // device to be queried
                                            IOCTL_STORAGE_CHECK_VERIFY2,
                                            NULL, 0,                     // no input buffer
                                            NULL, 0,                     // no output buffer
                                            &cbBytesReturned,            // # bytes returned
                                            (LPOVERLAPPED) NULL);        // synchronous I/O
                if (bSuccess)
                    _tprintf (TEXT("    the device media are accessible\n"));
                else if (GetLastError() == ERROR_NOT_READY)
                    _tprintf (TEXT("    the device media are not accessible\n"));
    
                bSuccess = DeviceIoControl (hDevice,                         // device to be queried
                                            IOCTL_STORAGE_GET_DEVICE_NUMBER, 
                                            NULL, 0,                         // no input buffer
                                            (LPVOID)&sdn, sizeof(sdn),       // output buffer
                                            &cbBytesReturned,                // # bytes returned
                                            (LPOVERLAPPED) NULL);            // synchronous I/O
                // GetLastError of ERROR_MORE_DATA indicates to the caller that the buffer was not large enough to accommodate the data requested
                if (!bSuccess) __leave;
                _tprintf (TEXT("    DeviceType: %d, DeviceNumber: %d, PartitionNumber: %d\n"), sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber);
    
                pGuidInferface = NULL;
                pGuidClass = NULL;
                if (sdn.DeviceType == FILE_DEVICE_CD_ROM || sdn.DeviceType == FILE_DEVICE_DVD) {
                    pGuidInferface = (GUID*)&GUID_DEVINTERFACE_CDROM;
                    pGuidClass = (GUID*)&GUID_DEVCLASS_CDROM;
                }
                else if (sdn.DeviceType == FILE_DEVICE_DISK) {
                    DEVICE_TYPE DeviceType;
                    ULONG ulCharacteristics;
                    bSuccess = GetDriveTypeAndCharacteristics (hDevice, &DeviceType, &ulCharacteristics);
                    if (bSuccess) {
                        if ((ulCharacteristics & FILE_FLOPPY_DISKETTE) == FILE_FLOPPY_DISKETTE) {
                            pGuidInferface = (GUID*)&GUID_DEVINTERFACE_FLOPPY;
                            pGuidClass = (GUID*)&GUID_DEVCLASS_FLOPPYDISK;
                        }
                        else {
                            pGuidInferface = (GUID*)&GUID_DEVINTERFACE_DISK;
                            pGuidClass = (GUID*)&GUID_DEVCLASS_DISKDRIVE;
                        }
    
                        if ((ulCharacteristics & FILE_REMOVABLE_MEDIA) == FILE_REMOVABLE_MEDIA)
                            bIsRemoveable = TRUE;
                    }
                }
                // GUID_DEVCLASS_MEDIUM_CHANGER
    
                if (CloseHandle (hDevice))
                    hDevice = INVALID_HANDLE_VALUE;
    
                bSuccess = FindDiInfos (pGuidInferface, pGuidClass, pszEnumerator, sdn.DeviceType, sdn.DeviceNumber,
                                        ARRAY_SIZE(szDeviceInstanceId),     // MAX_DEVICE_ID_LEN
                                        szDeviceInstanceId,
                                        &dwRemovalPolicy);
                if (bSuccess) {
                    if (dwRemovalPolicy == CM_REMOVAL_POLICY_EXPECT_SURPRISE_REMOVAL ||
                        dwRemovalPolicy == CM_REMOVAL_POLICY_EXPECT_ORDERLY_REMOVAL)
                        bIsRemoveable = TRUE;
                    _tprintf (TEXT("    DeviceInstanceId: %s\n"), szDeviceInstanceId);
                    if (bIsRemoveable)
                        _tprintf (TEXT("    Drive %c: is removeable\n"), pszDriveRoot[0]);
                }
            }
        }
        __finally {
            if (pszLogicalDrives)
                pszLogicalDrives = (LPTSTR) LocalFree (pszLogicalDrives);
            if (hDevice != INVALID_HANDLE_VALUE)
                bSuccess = CloseHandle (hDevice);
        }
    
        return 0;
    }
    

    该程序可以在不安装 Windows DDK 的情况下编译(仅需要与 Visual Studio 一起安装的 Windows SDK)。该程序产生如下输出:

    ....
    Drive L:
        Dos Device Name: \Device\CdRom2
        Volume Device Name: \\?\Volume{2c5f6a93-2b50-11df-aa6a-005056c00008}\
        Volume Name: "SONYPICTUTIL"
        Bus Type: USB
        VendorId: "HL-DT-ST"
        ProductId: "DVDRAM GE20LU11 "
        ProductRevision: "CL01"
        the device media are accessible
        DeviceType: 2, DeviceNumber: 2, PartitionNumber: -1
        DevicePath: \\?\usbstor#cdrom&ven_hl-dt-st&prod_dvdram_ge20lu11&rev_cl01#0010101640008b615&0#{53f56308-b6bf-11d0-94f2-00a0c91efb8b}
        Class: "CDROM"
        Hardware IDs:
            "USBSTOR\CdRomHL-DT-STDVDRAM_GE20LU11_CL01"
            "USBSTOR\CdRomHL-DT-STDVDRAM_GE20LU11_"
            "USBSTOR\CdRomHL-DT-ST"
            "USBSTOR\HL-DT-STDVDRAM_GE20LU11_C"
            "HL-DT-STDVDRAM_GE20LU11_C"
            "USBSTOR\GenCdRom"
            "GenCdRom"
        Friendly Name: "HL-DT-ST DVDRAM GE20LU11 USB Device"
        Physical Device Object Name: "\Device\00000096"
        Device Description: "CD-ROM Drive"
        Parent Device Instance ID: USB\VID_152E&PID_1640\0010101640008B615
            vid: "152E"
            pid: "1640"
        Parent of Parent Device Instance ID: USB\ROOT_HUB20\4&29A1BD9B&0
        DeviceInstanceId: USBSTOR\CDROM&VEN_HL-DT-ST&PROD_DVDRAM_GE20LU11&REV_CL01\0010101640008B615&0
        Drive L: is removeable
    Drive N:
        Dos Device Name: \Device\HarddiskVolume8
        Volume Device Name: \\?\Volume{ae08a3c8-71cf-11de-bc1d-005056c00008}\
        Volume Name: ""
        Bus Type: USB
        VendorId: "SanDisk "
        ProductId: "Cruzer          "
        ProductRevision: "8.01"
        the device media are accessible
        DeviceType: 7, DeviceNumber: 5, PartitionNumber: 1
        DevicePath: \\?\usbstor#disk&ven_sandisk&prod_cruzer&rev_8.01#1740030578903736&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
        Class: "DiskDrive"
        Hardware IDs:
            "USBSTOR\DiskSanDisk_Cruzer__________8.01"
            "USBSTOR\DiskSanDisk_Cruzer__________"
            "USBSTOR\DiskSanDisk_"
            "USBSTOR\SanDisk_Cruzer__________8"
            "SanDisk_Cruzer__________8"
            "USBSTOR\GenDisk"
            "GenDisk"
        Friendly Name: "SanDisk Cruzer USB Device"
        Physical Device Object Name: "\Device\000000aa"
        Device Description: "Disk drive"
        Parent Device Instance ID: USB\VID_0781&PID_5406\1740030578903736
            vid: "0781"
            pid: "5406"
        Parent of Parent Device Instance ID: USB\ROOT_HUB20\4&128079C2&0
        DeviceInstanceId: USBSTOR\DISK&VEN_SANDISK&PROD_CRUZER&REV_8.01\1740030578903736&0
        Drive N: is removeable
    

    因为我们只对可通过驱动器号访问的设备感兴趣,所以程序从枚举系统中与GetLogicalDriveStrings 函数相关的所有逻辑驱动器开始。对于每个驱动器,我们可以使用IOCTL_STORAGE_QUERY_PROPERTY 获取VendorIdProductIdProductRevision 等信息。 IOCTL_STORAGE_GET_DEVICE_NUMBER 的使用允许我们获取驱动器类型(如 CD/DVD 或磁盘/软盘)。此外,两个数字:DeviceTypeDeviceNumber 在系统中是唯一的,我们可以以此为基础来为驱动器优化设备实例(使用SetupDi- 函数)。

    因为软盘和磁盘设备具有相同的设备类型FILE_DEVICE_DISK,我演示了另一个函数NtQueryVolumeInformationFileFileFsDeviceInformation 参数来为设备获得如此命名的特性。该特性是从其他磁盘中指定软盘并为设备枚举(GUID_DEVINTERFACE_FLOPPYGUID_DEVINTERFACE_DISK)选择相应的类和接口 GUID 的最佳方式。我们获得了关于SetupDi API 枚举的所有设备的 DeviceType 和 DeviceNumber。以这种方式我们找出哪个设备具有哪个驱动器号。

    更重要的一点是设备的层次结构:父/子关系。为了演示这一点,我在代码示例中使用了CM_Get_ParentCM_Get_Device_ID 函数。所以我们可以看到哪个 USB 设备有哪个存储设备作为子设备。

    我显示了一些关于找到的设备的信息。如果需要,您可以将示例中的 API 与 IOCTL_MOUNTMGR_QUERY_POINTS(参见 Using IOCTL_MOUNTMGR_QUERY_POINTS)或 FindFirstVolumeWFindNextVolumeWGetVolumePathNamesForVolumeNameW(参见 http://msdn.microsoft.com/en-us/library/cc542456(VS.85).aspx)结合起来以接收更详细的信息。

    更新:顺便说一句,IOCTL_STORAGE_QUERY_PROPERTY 返回的缓冲区还有 STORAGE_BUS_TYPE BusTypeBusTypeUsbBusTypeFibreBusTypeSd 等)等其他字段。您也可以使用IOCTL_STORAGE_QUERY_PROPERTY 询问其他信息,如StorageDeviceUniqueIdPropertyStorageDeviceUniqueIdProperty 等。如果您想了解更多USB 特定信息,我推荐您http://www.emmet-gray.com/Articles/USB_SerialNumbers.htm,其中显示了IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EXIOCTL_USB_GET_NODE_INFORMATIONIOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 的用法。

    更新 2: 由于 stackoverflow.com 中消息大小的限制,我将程序的扩展版本放在 http://www.ok-soft-gmbh.com/ForStackOverflow/EnumMassStorage.c 下。测试输出如下http://www.ok-soft-gmbh.com/ForStackOverflow/EnumMassStorage.txt

    更新 3: 我发现了一个错误并更新了代码。请使用最新版本的代码并验证您的问题是否已解决。

    【讨论】:

    • 对不起,我不明白你的问题。你指的是什么结构?顺便看看代码的扩展版本和测试输出(见我的回答的 UPDATED 2 部分)
    • 此代码在 Windows 7 32 位和 Windows 7 64 位上进行了测试。您收到哪种错误?您使用哪个版本的 Visual Studio?
    • 您能解释一下哪部分信息是错误的吗?您没有通过 USB 连接所有驱动器吗?顺便说一句,我建议您也使用显示更详细信息的版本ok-soft-gmbh.com/ForStackOverflow/EnumMassStorage.c
    • 请看上面的帖子...我已经在上面的帖子中粘贴了系统(XP和Windows 7)的结果...我运行相同的代码但我得到不同的输出..对于同一设备...
    • 尝试使用固定版本。我希望现在程序可以正常工作。
    猜你喜欢
    • 2012-08-07
    • 2012-05-18
    • 1970-01-01
    • 2013-12-15
    • 1970-01-01
    • 1970-01-01
    • 2013-08-24
    • 2021-04-21
    • 1970-01-01
    相关资源
    最近更新 更多