【问题标题】:Detect if exe is running from a USB检测 exe 是否从 USB 运行
【发布时间】: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/… 在我在第一条评论中给出的链接中也有提及

标签: c++ c windows


【解决方案1】:

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

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

DRIVE_NO_ROOT_DIR - 1 - 根路径无效;例如,指定路径上没有挂载卷。

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

DRIVE_FIXED - 3 - 驱动器有固定媒体;例如,硬盘驱动器或闪存驱动器。

DRIVE_REMOTE - 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);

    }
}

【讨论】:

  • 谢谢...这个功能我已经尝试过了,但我正在使用我的外部 USB 硬盘驱动器进行测试,Windows 将其返回为 DRIVE_FIXED ...。在您回答之后,我尝试使用我的 USB 闪存驱动器和它为此返回了 DRIVE_REMOVABLE……该死的,我花了这么多小时……非常感谢
  • argv[0] 未定义。这里可以是任何。需要使用GetModuleFileNameW 例如,如果需要exe的路径
  • 你的代码也是错误的。 GetDriveTypewait for 尾部反斜杠。您没有将其添加到路径
  • @RbMm - 我将代码更改为使用 GetModuleFileName,现在我在驱动器号中包含尾随反斜杠以进行检查。
  • basePath[3] = L'\0'; 应该是对GetVolumePathName 的调用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
  • 2014-12-20
  • 2015-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多