当我在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
感谢您的任何帮助
我用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 = GetmoduleeHandle (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的情况下进行编译(只需要安装Windows SDK,例如与Visual Studio一起安装)。 该程序产生如下输出:
.... 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
来获取VendorId
, ProductId
和ProductRevision
。 使用IOCTL_STORAGE_GET_DEVICE_NUMBER
允许我们获得驱动器类型(如CD / DVD或磁盘/软盘)。 此外,两个数字: DeviceType
和DeviceNumber
在系统中是唯一的,我们可以使用这些数据作为驱动器的设备实例(使用SetupDi
– 函数)的基础。
由于软盘和磁盘设备具有相同的defice类型FILE_DEVICE_DISK
我演示另一个函数NtQueryVolumeInformationFile
与FileFsDeviceInformation
参数来获取设备的这样命名的特性 。 该特性是从其他磁盘中退出软盘的最佳方法,并为设备枚举( GUID_DEVINTERFACE_FLOPPY
或GUID_DEVINTERFACE_DISK
)选择相应的类和接口GUID。 我们获得了与SetupDi
API枚举的所有设备的DeviceType和DeviceNumber。 我们找出哪个设备有哪个驱动器号。
更重要的是设备的层次结构:父母/子女关系。 为了演示这个,我在代码示例中使用了CM_Get_Parent
和CM_Get_Device_ID
函数。 所以我们可以看到哪个USB设备有哪个存储设备。
我显示了一些有关找到的设备的信息。 您可以将示例中的API与IOCTL_MOUNTMGR_QUERY_POINTS
(请参阅使用IOCTL_MOUNTMGR_QUERY_POINTS )或FindFirstVolumeW
, FindNextVolumeW
和GetVolumePathNamesForVolumeNameW
(请参阅http://msdn.microsoft.com/en-us/library/cc542456(VS.85).aspx )组合以获得更多详细信息如果需要。
更新 :顺便说一句IOCTL_STORAGE_QUERY_PROPERTY
返回的缓冲区具有像STORAGE_BUS_TYPE BusType
( BusTypeUsb
, BusTypeFibre
, BusTypeSd
等)等另外的字段。您还可以使用IOCTL_STORAGE_QUERY_PROPERTY
要求另一个信息,如StorageDeviceUniqueIdProperty
或StorageDeviceUniqueIdProperty
等如果你想有更多的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
的使用情况。
更新2:由于在stackoverflow.com中的邮件大小限制,我在http://www.ok-soft-gmbh.com/ForStackOverflow/EnumMassStorage.c中放置了程序的扩展版本。 测试输出看起来像下面http://www.ok-soft-gmbh.com/ForStackOverflow/EnumMassStorage.txt
更新3:我发现了一个错误,并更新了代码。 请使用最新版本的代码,并确认您的问题已解决。