我正在使用 Windows API 编写一个应用程序,该应用程序需要在启动时检查它是从 USB 设备运行的。到目前为止我所取得的成就
这是我执行上述 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驱动器上
我现在想要实现的是
或者
找出此设备下的所有卷(我可以说是子设备)。例如,如果我将 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 代码。
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);
    }
}