【发布时间】:2020-11-26 18:01:45
【问题描述】:
我正在使用 Windows API 编写一个应用程序,该应用程序需要在启动时检查它是否从 USB 设备运行。 到目前为止我取得的成就
- 使用 SetupDiEnumDeviceInfo 列出设备
- 检测哪个设备是可移动的
这是我完成上述 2 个任务的代码
HDEVINFO hdevinfo = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE,NULL, NULL, DIGCF_PRESENT);
if (hdevinfo == INVALID_HANDLE_VALUE) {
WriteLog(L"hdevinfo is INVALID_HANDLE_VALUE");
return USB_PROT_ERROR;
}
DWORD MemberIndex = 0;
SP_DEVINFO_DATA sp_devinfo_data;
ZeroMemory(&sp_devinfo_data, sizeof(sp_devinfo_data));
sp_devinfo_data.cbSize = sizeof(sp_devinfo_data);
while (SetupDiEnumDeviceInfo(hdevinfo, MemberIndex, &sp_devinfo_data)) {
DWORD PropertyRegDataType;
DWORD RequiredSize;
TCHAR PropertyBuffer[500];
//get the name of this device
if (SetupDiGetDeviceRegistryProperty(hdevinfo, &sp_devinfo_data, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, &PropertyRegDataType, (PBYTE)&PropertyBuffer, sizeof(PropertyBuffer), &RequiredSize)) {
WriteLog(L"Device name: %s", PropertyBuffer);
DWORD PropertyValue;
//get removal policy for this device
if (SetupDiGetDeviceRegistryProperty(hdevinfo, &sp_devinfo_data, SPDRP_REMOVAL_POLICY, &PropertyRegDataType, (PBYTE)&PropertyValue, sizeof(PropertyValue), &RequiredSize)) {
if (PropertyValue == CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL) {
//not removable
WriteLog(L"Not Removable");
}
else {
//removable
WriteLog("Removable");
}
}
}
}
在我连接了 1 个硬盘和 1 个 USB 驱动器的 PC 上,我得到以下输出:
Device name: \Device\00000031
Not Removable
Device name: \Device\00000070
Removable
从输出中可以清楚地看出 \Device\00000070 是我的 USB 设备。从我的电脑我可以看到我的 USB 设备安装在 H 驱动器
我现在想要实现的是
- 找出可移动设备(在我的情况下是 \Device\00000070)安装在哪个驱动器号(在我的情况下是 H:)上。
或
-
找出此设备下的所有卷(我可以说是子设备)。例如,如果我将 GUID_DEVCLASS_VOLUME GUID 传递给 SetupDiGetClassDevs 函数,那么我的输出如下所示:
设备名称:\Device\HarddiskVolume2 不可移除
设备名称:\Device\HarddiskVolume4 不可移除
设备名称:\Device\HarddiskVolume9 不可移除
设备名称:\Device\HarddiskVolume5 不可移除
经过一些调试,我发现 \Device\HarddiskVolume9 是我的 USB,但您可以在输出中看到它始终显示 "Not Removable"强>。因此,如果我能发现 \Device\HarddiskVolume9 属于 \Device\00000070 那么这也对我有用,因为我可以轻松使用卷管理功能查找 \Device\HarddiskVolume9 的驱动器号并与可执行文件的驱动器号匹配。
我想使用 C/C++ Windows API 执行此操作,而不使用任何 3rd 方库和 .NET 代码。
【问题讨论】:
-
@armagedescu ...谢谢...但我使用了这个函数,它返回以下 \Device\HarddiskVolume9\PROJECTS\UsbProtector\Debug\Protector.exe 其中是正确的,因为 \Device\HarddiskVolume9 是我的 USB。但问题是我在我的问题中提到的 \Device\HarddiskVolume9 总是说“不可移动”,这意味着我不知道它是否是 USB。谢谢
-
@RameezUsmani 这就是你需要的stackoverflow.com/a/36456067/5878272
-
我假设您首先找出运行的 exe 是从哪个路径(例如 e:\\mysoftware.exe),然后您想知道 e:\ 是否是 USB 设备?跨度>
-
@RameezUsmani 必须存在另一个函数,也许docs.microsoft.com/en-us/windows/win32/api/winbase/… 在我在第一条评论中给出的链接中也有提及