【发布时间】:2014-07-03 10:41:59
【问题描述】:
我的目标是编写一个 c-dll(用 MinGW 编译),它能够搜索连接到计算机的特定型号的 U 盘,并提供序列号、供应商 ID、产品 ID 和驱动器号。 我在互联网上搜索了几个小时知道但找不到适合我的方法。
我正在使用 Setup Api 获取所有已连接 USB 设备的列表。对于每个 USB 设备,我得到一个如下所示的路径:
\?\usb#vid_048d&pid_1172#00000020370220#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
从该字符串中,我可以获得供应商 ID、产品 ID 和我正在寻找的序列号。
我现在的问题是确定与此设备路径相关的 USB 驱动器的驱动器号。
在我的互联网研究中,我多次发现以下方法(例如这里http://oroboro.com/usb-serial-number/):
找到设备路径后,USB 驱动器必须由CreateFile 打开。该函数返回的句柄可用于通过函数DeviceIOControl 和IOCTL_STORAGE_GET_DEVICE_NUMBER 获取设备号。
之后,CreateFile 函数可用于打开每个驱动器号(从 a: 开始)并尝试以与上述相同的方式获取设备号。一旦再次找到相同的设备号,就建立了设备路径和驱动器号之间的关系。
我的问题是IOCTL_STORAGE_GET_DEVICE_NUMBER 呼叫不起作用。 DeviceIOControl 函数返回错误代码 50,表示“不支持请求”。
我无法在 U 盘的设备路径和驱动器号之间创建链接。我尝试了几次IOCTL_STORAGE and IOCTL_VOLUME 电话,但没有一个适用于我尝试过的 USB 记忆棒。
我还在另一个论坛上看到人们对DeviceIOControl 函数的结果有疑问。它在某些 PC 上返回了预期的结果,而在其他 PC 上却遇到了麻烦。
还有其他方法可以实现我的目标吗?
我已经查看了注册表,我还可以在其中找到所需的数据。但是我再次遇到了在设备路径和驱动器号之间创建连接的问题。 我不想使用 WMI。我读过 MinGW 仍然没有真正支持它。 我有一个用 C# 实现所有这些的实现,它很容易获得所需的信息,但现在我还需要一个用非托管代码创建的,可用于替换也包含在 Delphi 项目中的 c-dll。
如果有任何解决我的问题的建议,我将不胜感激。
最好的问候, 弗洛里安
如果有人感兴趣,这里是代码。带有此评论的位置“//这里是我想获取设备编号的地方!!!”是设备号的请求,如果它可以工作的话。
typedef struct ty_TUSB_Device
{
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetailData;
char devicePath[300];
}TUSB_Device;
int
GetUSBDevices (TUSB_Device *devList[], int size)
{
HANDLE hHCDev;
HDEVINFO deviceInfo;
SP_DEVICE_INTERFACE_DATA deviceInfoData;
ULONG index;
ULONG requiredLength;
int devCount = 0;
//SP_DEVINFO_DATA DevInfoData;
// Now iterate over host controllers using the new GUID based interface
//
deviceInfo = SetupDiGetClassDevs((LPGUID)&GUID_DEVINTERFACE_USB_DEVICE,
NULL,
NULL,
(DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
if (deviceInfo != INVALID_HANDLE_VALUE)
{
deviceInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for (index=0;
SetupDiEnumDeviceInterfaces(deviceInfo,
0,
(LPGUID)&GUID_DEVINTERFACE_USB_DEVICE,
index,
&deviceInfoData);
index++)
{
SetupDiGetDeviceInterfaceDetail(deviceInfo,
&deviceInfoData,
NULL,
0,
&requiredLength,
NULL);
//allocate memory for pointer to TUSB_Device structure
devList[devCount] = malloc(sizeof(TUSB_Device));
devList[devCount]->deviceDetailData = GlobalAlloc(GPTR, requiredLength);
devList[devCount]->deviceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetail(deviceInfo,
&deviceInfoData,
devList[devCount]->deviceDetailData,
requiredLength,
&requiredLength,
NULL);
//open the usb device
hHCDev = CreateFile(devList[devCount]->deviceDetailData->DevicePath,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
// If the handle is valid, then we've successfully found a usb device
//
if (hHCDev != INVALID_HANDLE_VALUE)
{
strncpy(devList[devCount]->devicePath, devList[devCount]->deviceDetailData->DevicePath, sizeof(devList[devCount]->devicePath));
//HERE IS WHERE I WOULD LIKE TO GET THE DEVICE NUMBER!!!
CloseHandle(hHCDev);
devCount++;
}
//GlobalFree(devList[devCount]->deviceDetailData);
}
SetupDiDestroyDeviceInfoList(deviceInfo);
}
return devCount;
}
【问题讨论】:
标签: ioctl