当我在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
感谢您的帮助
答案 0 :(得分:24)
我在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的情况下编译程序(仅需要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
- 函数)的基础。
由于软盘和磁盘设备具有相同的定义类型FILE_DEVICE_DISK
,我演示了另一个带NtQueryVolumeInformationFile
参数的函数FileFsDeviceInformation
,以便为设备命名特性。特性是从其他磁盘转发软盘的最佳方法,并为设备枚举选择相应的类和接口GUID(GUID_DEVINTERFACE_FLOPPY
或GUID_DEVINTERFACE_DISK
)。我们获取了SetupDi
API枚举的所有设备的DeviceType和DeviceNumber。在我们找出哪个设备有哪个驱动器号的方式。
更重要的是设备的层次结构:父/子关系。为了演示这一点,我在代码示例中使用了CM_Get_Parent
和CM_Get_Device_ID
函数。因此,我们可以看到哪个USB设备具有哪个存储设备作为孩子。
我显示了有关找到的设备的一些信息。您可以将示例中的API与IOCTL_MOUNTMGR_QUERY_POINTS
(请参阅Using 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
,{{1}您也可以使用BusTypeSd
来询问其他信息,例如IOCTL_STORAGE_QUERY_PROPERTY
或StorageDeviceUniqueIdProperty
等。如果您想获得更多USB特定信息,我建议您{{3} },其中显示了StorageDeviceUniqueIdProperty
,IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX
和IOCTL_USB_GET_NODE_INFORMATION
的使用情况。
更新2:由于stackoverflow.com中邮件大小的限制,我将程序的扩展版本放在http://www.emmet-gray.com/Articles/USB_SerialNumbers.htm下。测试输出类似于http://www.ok-soft-gmbh.com/ForStackOverflow/EnumMassStorage.c
更新3:我发现了一个错误并更新了代码。请使用最新版本的代码并验证问题是否已解决。