我想知道我是否可以使用
获取驱动器信息SP_DEVICE_INTERFACE_DETAIL_DATA的DevicePath
我的设备路径如下所示
“\ \ USB#vid_04f2&安培; pid_0111#5和; 39fe81e&安培; 0和2#{a5dcbf10-6530-11d2-901f-00c04fb951ed}”
请在winapi中告诉我他们说“要确定驱动器是否是USB型驱动器,请调用SetupDiGetDeviceRegistryProperty并指定SPDRP_REMOVAL_POLICY属性。”
我也使用下面的SetupDiGetDeviceRegistryProperty
while ( !SetupDiGetDeviceRegistryProperty( hDevInfo,&DeviceInfoData,
SPDRP_REMOVAL_POLICY,&DataT,( PBYTE )buffer,buffersize,&buffersize ))
但我不知道如何使用上面的驱动器类型..
请帮帮我
答案 0 :(得分:4)
我创建了一个带有可选掩码的GetMountedVolumes
方法,以指定搜索中应包含哪些类型的卷(可读,可写,可移除,可热插拔,可擦除)。
我完全弃用了Setup API方法,只使用了DeviceIoControl
调用的空访问卷句柄(不需要管理权限)。我将分享我的代码,这可能会帮助其他人实现确定驱动器(卷)类型的方法,而无需使用安装程序API。
enum VolumesFlags {
VolumeReadable = 1,
VolumeWriteable = 2,
VolumeEraseable = 4,
VolumeRemoveable = 8,
VolumeHotplugable = 16,
VolumeMounted = 128
};
bool GetMountedVolumes(std::vector<std::wstring> &Volumes,
unsigned int Flags = VolumeReadable | VolumeWriteable,
unsigned int Mask = VolumeReadable | VolumeWriteable) {
wchar_t Volume[MAX_PATH] = {0};
wchar_t* VolumeEndPtr = Volume;
Flags |= VolumeMounted;
Mask |= VolumeMounted;
Flags &= Mask;
HANDLE hFind = FindFirstVolume(Volume, sizeof(Volume) / sizeof(wchar_t));
if (hFind != INVALID_HANDLE_VALUE) {
do {
bool IsMatching = false;
VolumeEndPtr = &Volume[wcslen(Volume) - 1];
*VolumeEndPtr = L'\0';
HANDLE hDevice = CreateFile(Volume, 0, 0, 0, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0);
if (hDevice != INVALID_HANDLE_VALUE) {
unsigned int CurrentFlags = 0;
DWORD ReturnedSize;
STORAGE_HOTPLUG_INFO Info = {0};
if (DeviceIoControl(hDevice, IOCTL_STORAGE_GET_HOTPLUG_INFO, 0, 0, &Info, sizeof(Info), &ReturnedSize, NULL)) {
if (Info.MediaRemovable) {
CurrentFlags |= VolumeRemoveable;
}
if (Info.DeviceHotplug) {
CurrentFlags |= VolumeHotplugable;
}
}
DWORD MediaTypeSize = sizeof(GET_MEDIA_TYPES);
GET_MEDIA_TYPES* MediaType = (GET_MEDIA_TYPES*) new char[MediaTypeSize];
while (DeviceIoControl(hDevice, IOCTL_STORAGE_GET_MEDIA_TYPES_EX, 0, 0, MediaType, MediaTypeSize, &ReturnedSize, NULL) == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
delete [] (char*) MediaType;
MediaTypeSize *= 2;
MediaType = (GET_MEDIA_TYPES*) new char[MediaTypeSize];
}
if (MediaType->MediaInfoCount > 0) {
DWORD Characteristics = 0;
// Supports: Disk, CD, DVD
if (MediaType->DeviceType == FILE_DEVICE_DISK || MediaType->DeviceType == FILE_DEVICE_CD_ROM || MediaType->DeviceType == FILE_DEVICE_DVD) {
if (Info.MediaRemovable) {
Characteristics = MediaType->MediaInfo[0].DeviceSpecific.RemovableDiskInfo.MediaCharacteristics;
} else {
Characteristics = MediaType->MediaInfo[0].DeviceSpecific.DiskInfo.MediaCharacteristics;
}
if (Characteristics & MEDIA_CURRENTLY_MOUNTED) {
CurrentFlags |= VolumeMounted;
}
if (Characteristics & (MEDIA_READ_ONLY | MEDIA_READ_WRITE)) {
CurrentFlags |= VolumeReadable;
}
if (((Characteristics & MEDIA_READ_WRITE) != 0 || (Characteristics & MEDIA_WRITE_ONCE) != 0) && (Characteristics & MEDIA_WRITE_PROTECTED) == 0 && (Characteristics & MEDIA_READ_ONLY) == 0) {
CurrentFlags |= VolumeWriteable;
}
if (Characteristics & MEDIA_ERASEABLE) {
CurrentFlags |= VolumeEraseable;
}
}
}
delete [] (char*) MediaType;
CloseHandle(hDevice);
CurrentFlags &= Mask;
if (CurrentFlags == Flags) {
*VolumeEndPtr = L'\\';
wchar_t VolumePaths[MAX_PATH] = {0};
if (GetVolumePathNamesForVolumeName(Volume, VolumePaths, MAX_PATH, &ReturnedSize)) {
if (*VolumePaths) {
Volumes.push_back(VolumePaths);
}
}
}
}
} while (FindNextVolume(hFind, Volume, sizeof(Volume) / sizeof(wchar_t)));
FindVolumeClose(hFind);
}
return Volumes.size() > 0;
}
答案 1 :(得分:2)
您可能会在http://support.microsoft.com/kb/264203/en找到您所寻找的内容。另一个链接http://support.microsoft.com/kb/305184/en对你来说也很有趣。
更新:来自http://support.microsoft.com/kb/264203/en的示例向您展示了如何使用来确定USB驱动器是否可移动。您还可以在设备实例上使用SetupDiGetDeviceRegistryProperty
SPDRP_REMOVAL_POLICY
(使用SetupDiEnumDeviceInfo
,SetupDiGetDeviceInstanceId
,然后SetupDiGetDeviceRegistryProperty
)。如果返回DWORD
的值为CM_REMOVAL_POLICY_EXPECT_SURPRISE_REMOVAL
或CM_REMOVAL_POLICY_EXPECT_ORDERLY_REMOVAL
,则驱动器可以移除。
此外,代码示例显示了如何打开设备句柄,您可以使用DeviceIoControl
函数来检索您可能需要的许多有用信息。 IOCTL_STORAGE_QUERY_PROPERTY
{(http://msdn.microsoft.com/en-us/library/ff566997%28v=VS.85%29.aspx)QueryType
和PropertyId
只有一个例子。例如,您可以使用IOCTL_STORAGE_GET_DEVICE_NUMBER
来接收存储卷及其磁盘编号。
如果您有关于USB设备的完整STORAGE_DEVICE_NUMBER
信息,我们将能够以不同的方式查找有关它的所有其他信息。最简单的方法之一是:只使用QueryDosDevice枚举所有驱动器号并为每个驱动器查询STORAGE_DEVICE_NUMBER
。如果您在STORAGE_DEVICE_NUMBER
找到完整匹配,您将找到驱动器号。
答案 2 :(得分:0)
鉴于您的+=
:
Storage Device Path
CreateFile
发布DeviceIOControl
STORAGE_DEVICE_DESCRIPTOR
结构具有STORAGE_BUS_TYPE
枚举:
IOCTL_STORAGE_QUERY_PROPERTY
}
不同的存储总线类型是
示例psueudo-code
STORAGE_DEVICE_DESCRIPTOR {
DWORD Version;
DWORD Size;
BYTE DeviceType;
BYTE DeviceTypeModifier;
BOOLEAN RemovableMedia;
BOOLEAN CommandQueueing;
DWORD VendorIdOffset;
DWORD ProductIdOffset;
DWORD ProductRevisionOffset;
DWORD SerialNumberOffset;
STORAGE_BUS_TYPE BusType; //<---------------
DWORD RawPropertiesLength;
BYTE RawDeviceProperties[1];