如何通过可移动设备盘符获取设备路径或GUID

diclover 2009-08-12 04:34:18
如题,我通过SetupDiGetDeviceInterfaceDetail函数枚举到了可移动设备的路径,但是想要将这些路径映射到设备盘符上(非管理员下HID复合设备),请问该如何做。
...全文
632 点赞 收藏 6
写回复
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
diclover 2009-08-13
我把我的代码帖出来,请各位帮下忙
//Open the desired device,return the handle of desired device
HANDLE CNzHidUsbDisk::OpenHidDevice(TCHAR cLetter)
{
int nMemberIndex = 0; //device member indexs
long lResult = 0; //call result
int nDeviceNum = 0; //the number of desired device
BOOL bLastDevice = FALSE; //whether it is last device
BOOL bRet = FALSE; //return value
TCHAR cVolMountPoint[4] = {_T("C:\\")}; //volume mount information
TCHAR cVol[1024] = {_T('\0')}; //device volume



//set the Drive Letter as mount volume
cVolMountPoint[0] = cLetter;

/*========================================================================
API function: HidD_GetHidGuid
Get the GUID for all system HIDs.
Returns: the GUID in HidGuid.
========================================================================*/
HidD_GetHidGuid(&m_HidGuid);

/*========================================================================
API function: SetupDiGetClassDevs
Returns: a handle to a device information set for all installed devices.
Requires: the GUID returned by GetHidGuid.
========================================================================*/
m_hDevInfo = SetupDiGetClassDevs
(&m_HidGuid,
NULL,
NULL,
DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);


m_devInfoData.cbSize = sizeof(m_devInfoData);

//Step through the all available devices looking for the one we want.
while(FALSE == bLastDevice)
{
/*========================================================================
API function: SetupDiEnumDeviceInterfaces
On return, MyDeviceInterfaceData contains the handle to a
SP_DEVICE_INTERFACE_DATA structure for a detected device.
Requires:
The DeviceInfoSet returned in SetupDiGetClassDevs.
The HidGuid returned in GetHidGuid.
An index to specify a device.
========================================================================*/
lResult = SetupDiEnumDeviceInterfaces
(m_hDevInfo,
0,
&m_HidGuid,
nMemberIndex,
&m_devInfoData);

if (lResult)
{
//A device has been detected, so get more information about it.

/*========================================================================
API function: SetupDiGetDeviceInterfaceDetail
Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
containing information about a device.
To retrieve the information, call this function twice.
The first time returns the size of the structure in Length.
The second time returns a pointer to the data in DeviceInfoSet.
Requires:
A DeviceInfoSet returned by SetupDiGetClassDevs
The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.

The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
This application doesn't retrieve or use the structure.
If retrieving the structure, set
MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
and pass the structure's address.

This call it to get the Length value.
The call will return with a "buffer too small" error which can be ignored.
========================================================================*/
lResult = SetupDiGetDeviceInterfaceDetail
(m_hDevInfo,
&m_devInfoData,
NULL,
0,
&m_dwLength,
NULL);

//Allocate memory for the hDevInfo structure, using the returned Length.
m_detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) new BYTE[m_dwLength * sizeof(BYTE)];

//Set cbSize in the detailData structure.
m_detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

//Call the function again, this time passing it the returned buffer size.
lResult = SetupDiGetDeviceInterfaceDetail
(m_hDevInfo,
&m_devInfoData,
m_detailData,
m_dwLength,
&m_dwRequired,
NULL);


//Initialize the handle
m_hDevice = INVALID_HANDLE_VALUE;

/*========================================================================
API function: CreateFile
Returns: a handle that enables reading and writing to the device.
Requires:
The DevicePath in the detailData structure
returned by SetupDiGetDeviceInterfaceDetail.
========================================================================*/
m_hDevice = CreateFile
(m_detailData->DevicePath,
0,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,
NULL);


//Set the Size to the number of unsigned chars in the structure.
m_Attributes.Size = sizeof(m_Attributes);

/*========================================================================
API function: HidD_GetAttributes
Requests information from the device.
Requires: the handle returned by CreateFile.
Returns: a HIDD_ATTRIBUTES structure containing
the Vendor ID, Product ID, and Product Version Number.
Use this information to decide if the detected device is
the one we're looking for.
========================================================================*/
lResult = HidD_GetAttributes
(m_hDevice[nDeviceNum],
&m_Attributes);



//Get the device's capablities.
GetDeviceCapabilities();

//get the volume name by volume mount information
GetVolumeNameForVolumeMountPoint(cVolMountPoint,cVol,1024);

//is it the assigned device
//what can i do??
if()
{
CloseHandle(m_hDevice);
continue;
}

//Is it the desired device?
bRet = IsMyDevice();
if(!bRet)
{
CloseHandle(m_hDevice);
return INVALID_HANDLE_VALUE;
}
//Free the memory used by the detailData structure (no longer needed).
delete[] m_detailData;
} //end if(Result != 0)
else
{
//SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check.
bLastDevice = TRUE;
}
//If we haven't found the device yet, and haven't tried every available device,
//try the next one.
nMemberIndex++;
} //end while
//Free the memory reserved for hDevInfo by SetupDiClassDevs.
SetupDiDestroyDeviceInfoList(m_hDevInfo);
return m_hDevice;
}
回复
diclover 2009-08-13
使用2L类似的方法获得的hidGUID为:4d1e55b2-f16f-11cf-88cb-001111000030
设备1(盘符G)DevicePath为:\\?\hid#vid_1234&pid_5678mi_01#781839659e8c&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
设备2(盘符H)DevicePath为:\\?\hid#vid_1234&pid_5678mi_01#781c781416c&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
而通过盘符G获取的设备卷为:\\?\volume{4ddeeb92-8543-11de-afc2-001a660da68}
而通过盘符H获取的设备卷为:\\?\volume{dcdd6e5a-7ff6-11de-afc3-001a660da68}
这些都没有什么关联性,无法区分啊
回复
diclover 2009-08-13
可能我没有说明白,我已经有用2楼类似的方法枚举到了设备句柄,但是如果有2个设备,我将获取到两个句柄,现在我想分别操作这两个设备,但是对用户来说,可见的只能是盘符('C'、'D'那种),如何知道哪个句柄对应的是哪个盘符呢?我的思路是通过盘符获取到这个设备路径,然后与2楼枚举到的设备路径进行对比(我操作的是HID设备,设备路径中没有任何盘符的信息)。至于1楼的方法行不通,非管理员权限下无法操作注册表。这个问题困惑了我好久。现在我通过函数GetVolumeNameForVolumeMountPoint获取到了这个设备卷,那么是否可以通过2楼的方法或得同样的设备卷?如果可以,那么问题就解决了。请各位给个思路。
回复
zpba 2009-08-13
up
回复
MoXiaoRab 2009-08-12

HidD_GetHidGuid (&hidGUID);

DeviceInfoSet = SetupDiGetClassDevs (&hidGUID, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

if(DeviceInfoSet == INVALID_HANDLE_VALUE)
printf("DeviceInfoSet is INVALID_HANDLE_VALUE\n");

result = SetupDiEnumDeviceInterfaces (DeviceInfoSet, NULL, &hidGUID, Index, &deviceInterfaceData);
if (result == FALSE)
SetupDiDestroyDeviceInfoList (DeviceInfoSet);


SetupDiGetDeviceInterfaceDetail (DeviceInfoSet, &deviceInterfaceData, NULL, 0, &requiredSize, 0);
deviceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(requiredSize);
deviceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
if(deviceDetail == NULL)
printf("There is no enough memory space available for deviceDetail\n");

if (!SetupDiGetDeviceInterfaceDetail (DeviceInfoSet, &deviceInterfaceData, deviceDetail, requiredSize, &requiredSize, NULL))
{
printf("SetupDiGetDeviceInterfaceDetail failed\n");
SetupDiDestroyDeviceInfoList (DeviceInfoSet);
free (deviceDetail);
return INVALID_HANDLE_VALUE;
}

printf("path: %s\n", deviceDetail->DevicePath);
deviceHandle = CreateFile (deviceDetail->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
//盘符号有了吧?
if(deviceHandle == INVALID_HANDLE_VALUE);
printf("CreateFile open failed (%d)\n", GetLastError());

SetupDiDestroyDeviceInfoList (DeviceInfoSet);
free (deviceDetail);

回复
bohut 2009-08-12
通过查询[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Disk\Enum]下面的键值获得。键名就是存储物理设备号
回复
发动态
发帖子
硬件/系统
创建于2007-09-28

2590

社区成员

VC/MFC 硬件/系统
申请成为版主
社区公告
暂无公告