我正在编写一个处理USB驱动器的程序,以获取有关连接新设备的信息,我注册了一个窗口消息WM_DEVICECHANGE。但是,我当然不会收到有关在我的程序启动之前连接的设备的消息。为了处理这样的设备,我写了一个搜索功能,但是我得到了一个奇怪的结果。它找到了我的闪存驱动器,但无法识别它是可移动的。为什么? 功能
bool FindConnectedRemovableUsbstorDevices(std::list<std::wstring>& UsbList)
{
std::wstring ClassGuidString(L"{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}");
GUID ClassGuid;
BYTE buf[1024];
PSP_DEVICE_INTERFACE_DETAIL_DATA_W pspdidd = reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA_W>(buf);
SP_DEVICE_INTERFACE_DATA spdid;
SP_DEVINFO_DATA spdd;
DWORD size;
SP_DEVINFO_DATA dev_data;
DWORD properties;
if(NOERROR != CLSIDFromString(ClassGuidString.c_str(), &ClassGuid))
return false;
HDEVINFO dev_info = INVALID_HANDLE_VALUE;
dev_info = SetupDiGetClassDevs(&ClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (dev_info == INVALID_HANDLE_VALUE)
return false;
DWORD index = 0;
BOOL ret = FALSE;
spdid.cbSize = sizeof(spdid);
while (true)
{
ret = SetupDiEnumDeviceInterfaces(dev_info, NULL, &ClassGuid, index, &spdid);
if (!ret)
break;
size = 0;
SetupDiGetDeviceInterfaceDetail(dev_info, &spdid, NULL, 0, &size, NULL);
//Get required size
if (size == 0 || size >= sizeof(buf))
continue;
//prepare structs
ZeroMemory(reinterpret_cast<PVOID>(pspdidd), 1024);
pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!
ZeroMemory(reinterpret_cast<PVOID>(&spdd), sizeof(spdd));
spdd.cbSize = sizeof(spdd);
BOOL res = SetupDiGetDeviceInterfaceDetail(dev_info, &spdid, pspdidd, size, &size, &spdd);
//Get info
if (!res)
continue;
HANDLE drive = CreateFileW(pspdidd->DevicePath, FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);//open device
if (drive == INVALID_HANDLE_VALUE)
continue;
printf("\n%S\r\n", pspdidd->DevicePath);
DWORD bytes_returned = 0;
BOOL b = DeviceIoControl(drive, IOCTL_STORAGE_CHECK_VERIFY2, NULL, 0, NULL, 0, &bytes_returned, NULL);
if (!b) //check is card reader?
{
printf("IOCTL_STORAGE_CHECK_VERIFY2 error = %d\r\n", GetLastError());
goto stop_process_device;
}
bytes_returned = 0;
STORAGE_DEVICE_NUMBER sdn;
//Get Drive number
b = DeviceIoControl(drive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &bytes_returned, NULL);
if (!b)
goto stop_process_device;
RtlZeroMemory(&dev_data, sizeof(SP_DEVINFO_DATA));
dev_data.cbSize = sizeof(dev_data);
if (SetupDiEnumDeviceInfo(dev_info, sdn.DeviceNumber, &dev_data))
{
//check property
b = SetupDiGetDeviceRegistryProperty(dev_info, &dev_data, SPDRP_REMOVAL_POLICY, NULL,
reinterpret_cast<PBYTE>(&properties), sizeof(properties), NULL);
if (b && properties != CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL)
{
UsbList.push_back(pspdidd->DevicePath);
printf("REMOVAL\r\n");
}
}
stop_process_device:
CloseHandle(drive);
index++;
}
SetupDiDestroyDeviceInfoList(dev_info);
return true;
}
输出
\\?\usbstor#disk&ven_generic-&prod_ms#ms-pro#hg&rev_1.00#20090703819900000&1#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
IOCTL_STORAGE_CHECK_VERIFY2 error = 21
\\?\ide#diskst3500418as_____________________________cc38____#5&5c6cfd6&0&1.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
REMOVAL
\\?\usbstor#disk&ven_generic-&prod_sd#mmc&rev_1.00#20090703819900000&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
IOCTL_STORAGE_CHECK_VERIFY2 error = 21
\\?\scsi#disk&ven_ocz&prod_revodrive3_x2#5&19ad1f72&0&000000#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
\\?\ide#diskst1000lm014-1ej164______________________sm30____#5&2ea7e938&0&0.1.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
\\?\usbstor#disk&ven_sandisk&prod_extreme&rev_0001#aa010823150434152862&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
\\?\ide#diskwdc_wd1002fbys-02a6b0___________________03.00c06#5&2ea7e938&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
REMOVAL
错误21是空读卡器。 Sandisk是我的闪光灯。在Debug中我看到SetupDiGetDeviceRegistryProperty返回属性CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL,但我真的不知道为什么......
答案 0 :(得分:0)
如果您只想查找已连接的可移动设备,可以使用GetLogicalDriveStrings()和GetDriveType()更简单的方法:
#define MAX_DRIVES 256
bool FindConnectedRemovableUsbstorDevices(std::list<std::wstring>& UsbList)
{
wchar_t drives[MAX_DRIVES];
wchar_t* temp = drives;
if (GetLogicalDriveStringsW(MAX_DRIVES, drives) == 0)
return false;
while (*temp != NULL)
{
if (GetDriveTypeW(temp) == 2 /* DRIVE_REMOVABLE */)
UsbList.push_back(temp);
// Go to the next drive
temp += lstrlenW(temp) + 1;
}
return true;
}
答案 1 :(得分:0)
我不知道为什么我的fisrt检测可移动媒体的方法如此奇怪,但RbMm的方法效果很好。我将IOCTL查询发送到IOCTL_STORAGE_QUERY_PROPERTY
StorageDeviceProperty
STORAGE_DEVICE_DESCRIPTOR.RemovableMedia
的每个找到的设备,并查找def obj(x):
Budget = ((df['CPP TA 30'] / 30 * df['TVC']) * x).sum()
x = (x - min_train_x) / (max_train_x-min_train_x)
x = np.array([x])
return (0.05 * model.predict(x) - (1.7 * (Budget / 10**10)))[0][0]
x0 = np.random.uniform(size = 23)
x0 = (x0 / np.sum(x0)) * 1800
from scipy.optimize import minimize
res = minimize(obj, x0)
字段。我的所有设备都成功识别并且正确。