windows 在 windows7 - 32 位系统上获取有关磁盘驱动器结果的信息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3098696/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 14:42:44  来源:igfitidea点击:

Get information about disk drives result on windows7 - 32 bit system

windowswinapimsdn

提问by user198725878

When i run the below code on windows XP - 32 , i get the below result.

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

i have plugged only one usb pen drive

我只插入了一个 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&1C1E8A11&0&0
    Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_72671462&R
EV_01&11583659&0&FA
    DeviceInstanceId: IDE\DISKST3160215AS_____________________________3.AAD___
&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&1C1E8A11&0&0
    Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_72671462&R
EV_01&11583659&0&FA
    DeviceInstanceId: IDE\DISKST3160215AS_____________________________3.AAD___
&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&1C1E8A11&0&0
    Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_72671462&R
EV_01&11583659&0&FA
    DeviceInstanceId: IDE\DISKST3160215AS_____________________________3.AAD___
&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&1C1E8A11&0&0
    Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_72671462&R
EV_01&11583659&0&FA
    DeviceInstanceId: IDE\DISKST3160215AS_____________________________3.AAD___
&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
---------------------------------------------------------------------------------
000080 Device Description: Disk drive Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13 Parent of Parent Device Instance ID: USB\ROOT_HUB20&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
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&35CD87E&0&0
    Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_27C08086&R
EV_01&2411E6FE&1&FA
    DeviceInstanceId: IDE\DISKHITACHI_HDS721616PLA380_________________P22OAB3A
&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
#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('
....
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##代码##000096"
    Device Description: "CD-ROM Drive"
    Parent Device Instance ID: USB\VID_152E&PID_1640##代码##10101640008B615
        vid: "152E"
        pid: "1640"
    Parent of Parent Device Instance ID: USB\ROOT_HUB20&29A1BD9B&0
    DeviceInstanceId: USBSTOR\CDROM&VEN_HL-DT-ST&PROD_DVDRAM_GE20LU11&REV_CL01##代码##10101640008B615&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##代码##0000aa"
    Device Description: "Disk drive"
    Parent Device Instance ID: USB\VID_0781&PID_540640030578903736
        vid: "0781"
        pid: "5406"
    Parent of Parent Device Instance ID: USB\ROOT_HUB20&128079C2&0
    DeviceInstanceId: USBSTOR\DISK&VEN_SANDISK&PROD_CRUZER&REV_8.0140030578903736&0
    Drive N: is removeable
'); 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('##代码##'); __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('##代码##') && 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('##代码##'); 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('##代码##'); _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; }
000080 Device Description: Disk drive Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13 Parent of Parent Device Instance ID: USB\ROOT_HUB20&2B6971CE&0 DeviceInstanceId: USBSTOR\DISK&VEN_JETFLASH&PROD_TRANSCEND_2GB&REV_8.07\E3O2 9U13&0 Drive G: is removeable
00006f Device Description: Disk drive Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13 Parent of Parent Device Instance ID: USB\ROOT_HUB20&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##代码##00006f Device Description: Disk drive Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13 Parent of Parent Device Instance ID: USB\ROOT_HUB20&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##代码##00006f Device Description: Disk drive Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13 Parent of Parent Device Instance ID: USB\ROOT_HUB20&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##代码##00006f Device Description: Disk drive Parent Device Instance ID: USB\VID_058F&PID_6387\E3O29U13 Parent of Parent Device Instance ID: USB\ROOT_HUB20&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&35CD87E&0&0 Parent of Parent Device Instance ID: PCI\VEN_8086&DEV_27C0&SUBSYS_27C08086&R EV_01&2411E6FE&1&FA DeviceInstanceId: IDE\DISKHITACHI_HDS721616PLA380_________________P22OAB3A &4BE38F&0&0.0.0 Drive G: is removeable Drive Z:

Blockquote

块引用

##代码##

Kindly look at the both the results...

请看看这两个结果......

I have plugged a same usb device on both the systems ( xp and windows7 ) but the results varies...

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

please check the Drive G: results on the both the Os...

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

##代码##

Thank you for any help

感谢您的任何帮助

回答by Oleg

I wrote a program in C which demonstrate how to receive the information which you need

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

##代码##

The program can be compiled without Windows DDK installed (only Windows SDK, which installed for example together with Visual Studio is required). The program produces output like following:

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

##代码##

Because we are interesting for only devices which are accessible through drive letters the program start with enumerating of all logical drives in the system with respect of GetLogicalDriveStringsfunction. For every drive we can use IOCTL_STORAGE_QUERY_PROPERTYto get information like VendorId, ProductIdand ProductRevision. The usage of IOCTL_STORAGE_GET_DEVICE_NUMBERallow us to get the drive type (like CD/DVD or Disk/Floppy). Moreover two numbers: DeviceTypeand DeviceNumberare unique in the system and we can use these as the basis to fine the device instance (using SetupDi- functions) for the drive.

因为我们只对可通过驱动器号访问的设备感兴趣,所以程序开始时会根据功能枚举系统中的所有逻辑驱动器GetLogicalDriveStrings。对于我们可以IOCTL_STORAGE_QUERY_PROPERTY用来获取诸如VendorId,ProductId和 之类的信息的每个驱动器ProductRevision。的用法IOCTL_STORAGE_GET_DEVICE_NUMBER允许我们获取驱动器类型(如 CD/DVD 或磁盘/软盘)。此外还有两个数字:DeviceTypeDeviceNumber在系统中是唯一的,我们可以使用这些作为基础来优化SetupDi驱动器的设备实例(使用- 函数)。

Because Floppy and Disk devices has the same defice type FILE_DEVICE_DISKI demonstrate another function NtQueryVolumeInformationFilewith FileFsDeviceInformationparameter to get so named Characteristicsfor the device. The characteristic is the best way to destinguisch floppy from other disks and choose the corresponding class and interface GUID for the device enumeration (GUID_DEVINTERFACE_FLOPPYor GUID_DEVINTERFACE_DISK). We get the DeviceType and DeviceNumber for all devices enumerated with respect of SetupDiAPI. In the way we find out which device has which drive letter.

因为软盘和磁盘设备具有相同的缺陷类型,FILE_DEVICE_DISK所以我演示了另一个NtQueryVolumeInformationFile带有FileFsDeviceInformation参数的函数,以获得设备的命名特征。该特性是从其他磁盘中删除软​​盘并为设备枚举(GUID_DEVINTERFACE_FLOPPYGUID_DEVINTERFACE_DISK)选择相应的类和接口 GUID 的最佳方式。我们获得了关于SetupDiAPI枚举的所有设备的 DeviceType 和 DeviceNumber 。通过我们找出哪个设备具有哪个驱动器号的方式。

One more important thing is the hierarchy of devices: parent/child relationship. To demonstrate this I use CM_Get_Parentand CM_Get_Device_IDfunctions in the code example. So we can see which USB device has which storage divice as the child.

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

I displayed some information about the found devices. You can combine API from the example with IOCTL_MOUNTMGR_QUERY_POINTS(see Using IOCTL_MOUNTMGR_QUERY_POINTS) or FindFirstVolumeW, FindNextVolumeWand GetVolumePathNamesForVolumeNameW(see http://msdn.microsoft.com/en-us/library/cc542456(VS.85).aspx) to receive more detailed information if needed.

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

UPDATED: By the way the buffer returned by IOCTL_STORAGE_QUERY_PROPERTYhas another fields like STORAGE_BUS_TYPE BusType(BusTypeUsb, BusTypeFibre, BusTypeSdetc.) etc. You can also use IOCTL_STORAGE_QUERY_PROPERTYto ask another information like StorageDeviceUniqueIdPropertyor StorageDeviceUniqueIdPropertyetc. If you want to have more USB specific information, I recommend you http://www.emmet-gray.com/Articles/USB_SerialNumbers.htmwhich shows the usage of IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, IOCTL_USB_GET_NODE_INFORMATIONand IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION.

已更新:顺便说一下返回的缓冲区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_EX,IOCTL_USB_GET_NODE_INFORMATION和的用法IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION

UPDATED 2:I placed the extended version of program under http://www.ok-soft-gmbh.com/ForStackOverflow/EnumMassStorage.cbecause of restriction with the message size in stackoverflow.com. The test output looks like folowing http://www.ok-soft-gmbh.com/ForStackOverflow/EnumMassStorage.txt

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

UPDATED 3:I found a bug and updated the code. Please use the latest version of the code and verify that your problem is solved.

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