检测exe是否从USB运行



我正在使用windows API编写一个应用程序,该应用程序需要在启动时检查是否从USB设备运行。到目前为止我取得的成就

  • 使用SetupDiEnumDeviceInfo列出设备
  • 检测哪个设备是可移动的

这是我的代码来完成以上两项任务

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驱动器的电脑上,我得到了以下输出:

Device name: Device0000031
Not Removable
Device name: Device0000070
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,但你可以在输出中看到它总是显示"不可移动">。因此,如果我能发现\Device\HarddiskVolume9属于\Device\00000070,那么这对我来说也适用,因为我可以很容易地使用卷管理功能来查找\Device\HarddiskVolume 9的驱动器号,并与可执行文件的驱动器号匹配。

我想使用C/C++Windows API,而不使用任何第三方库,也不使用.NET代码

Windows API函数GetDriveType返回以下内容:

DRIVE_UNNOWN-0-无法确定驱动器类型。

DRIVE_NO_ROOT_DIR-1-根路径无效;例如,在指定的路径上没有安装任何卷。

DRIVE_REMOVABLE-2-驱动器有可移动介质;例如,软盘驱动器、拇指驱动器或闪存卡读取器。

DRIVE_FIXED-3-驱动器有固定介质;例如硬盘驱动器或闪存驱动器。

DRIVE_ROTE-4-驱动器是远程(网络(驱动器。

DRIVE_CDROM-5-驱动器是CD-ROM驱动器。

DRIVE_RAMDISK-6-驱动器是RAM磁盘。

所以我会使用以下代码,检查返回值是否等于(2(-可移除:

#include <windows.h>
int main()
{
wchar_t basePath[1024]{ L"" }, volName[1024]{ L"" };
GetModuleFileName(NULL, basePath, 1024);
GetVolumePathName(basePath, volName, 1024);
UINT type = GetDriveType(volName);
if (type == 2)
{
MessageBox(NULL, L"You are running from a flash drive (USB)",L"",MB_OK);
}
else
{
MessageBox(NULL, L"You are NOT running from a flash drive (USB)",L"", MB_OK);
}
}

最新更新