#include "windows.h"
#include "PlkUsbIo.h"
#include <malloc.h>
#define NUM_HCS_TO_CHECK 10
/******************************************************************/
bool EnumUsbDevice();
PCHAR GetDriverKeyName(HANDLE Hub, ULONG ConnectionIndex);
PCHAR GetHCDDriverKeyName(HANDLE HCD);
PCHAR GetRootHubName(HANDLE HostController);
PCHAR WideStrToMultiStr(PWCHAR WideStr);
bool GetStringDescriptor (
HANDLE hHubDevice,
ULONG ConnectionIndex,
UCHAR DescriptorIndex ,
CHAR * outBuff);
/******************************************************************/
int main(int argc, char* argv[])
{
EnumUsbDevice();
return 0;
}
bool EnumUsbDevice()
{
char HCName[16];
int HCNum;
HANDLE hHCDev;
PCHAR rootHubName;
ULONG index;
BOOL success;
PUSB_NODE_CONNECTION_INFORMATION connectionInfo;
HANDLE hHubDevice;
for (HCNum = 0; HCNum < NUM_HCS_TO_CHECK; HCNum++)
{
wsprintf(HCName, ".//HCD%d", HCNum);
hHCDev = CreateFile(HCName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hHCDev == INVALID_HANDLE_VALUE)
break;
PCHAR driverKeyName, deviceDesc;
driverKeyName = GetHCDDriverKeyName(hHCDev);
if(driverKeyName == NULL)
goto end;
ULONG nBytes;
rootHubName =(char*) GetRootHubName(hHCDev);
if(rootHubName==NULL)
goto end;
PUSB_NODE_INFORMATION HubInfo;
HubInfo = (PUSB_NODE_INFORMATION)malloc(sizeof(USB_NODE_INFORMATION));
PCHAR deviceName;
deviceName = (PCHAR)malloc(strlen(rootHubName) + sizeof(".//"));
if (rootHubName != NULL)
{
strcpy(deviceName, ".//");
strcpy(deviceName + sizeof(".//") - 1, rootHubName);
hHubDevice = CreateFile(deviceName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
free(deviceName);
if (hHubDevice == INVALID_HANDLE_VALUE)
goto end;
success = DeviceIoControl(hHubDevice,
IOCTL_USB_GET_NODE_INFORMATION,
HubInfo,
sizeof(USB_NODE_INFORMATION),
HubInfo,
sizeof(USB_NODE_INFORMATION),
&nBytes,
NULL);
if (!success)
goto end;
}
int port;
port=HubInfo->u.HubInformation.HubDescriptor.bNumberOfPorts;
for (index=1; index <= port; index++)
{
ULONG nBytes;
nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION) +
sizeof(USB_PIPE_INFO) * 30;
connectionInfo = (PUSB_NODE_CONNECTION_INFORMATION)malloc(nBytes);
if (connectionInfo == NULL)
goto end;
connectionInfo->ConnectionIndex = index;
success = DeviceIoControl(hHubDevice,
IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,
connectionInfo,
nBytes,
connectionInfo,
nBytes,
&nBytes,
NULL);
if (!success)
{
free(connectionInfo);
goto end;
}
deviceDesc = NULL;
if (connectionInfo->ConnectionStatus != NoDeviceConnected)
{
driverKeyName = GetDriverKeyName(hHubDevice,
index);
if (driverKeyName)
{
free(driverKeyName);
}
}
if (connectionInfo->ConnectionStatus == DeviceConnected)
{
//取出序列号索引
UCHAR nSerialno = connectionInfo->DeviceDescriptor.iSerialNumber;
CHAR OutBuff[20] = {0};
GetStringDescriptor(hHubDevice,connectionInfo->ConnectionIndex,nSerialno,OutBuff);
//判断序列号是否有效
if(序列号是否有效)
{
CloseHandle(hHubDevice);
CloseHandle(hHCDev);
return true;
}
}
}
end:;
}
CloseHandle(hHubDevice);
CloseHandle(hHCDev);
return false;
}
PCHAR GetDriverKeyName(HANDLE Hub, ULONG ConnectionIndex)
{
BOOL success;
ULONG nBytes;
USB_NODE_CONNECTION_DRIVERKEY_NAME driverKeyName;
PUSB_NODE_CONNECTION_DRIVERKEY_NAME driverKeyNameW;
PCHAR driverKeyNameA;
driverKeyNameW = NULL;
driverKeyNameA = NULL;
driverKeyName.ConnectionIndex = ConnectionIndex;
success = DeviceIoControl(Hub,
IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
&driverKeyName,
sizeof(driverKeyName),
&driverKeyName,
sizeof(driverKeyName),
&nBytes,
NULL);
if (!success)
{
goto GetDriverKeyNameError;
}
nBytes = driverKeyName.ActualLength;
if (nBytes <= sizeof(driverKeyName))
{
goto GetDriverKeyNameError;
}
driverKeyNameW = (PUSB_NODE_CONNECTION_DRIVERKEY_NAME)malloc(nBytes);
if (driverKeyNameW == NULL)
{
goto GetDriverKeyNameError;
}
driverKeyNameW->ConnectionIndex = ConnectionIndex;
success = DeviceIoControl(Hub,
IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
driverKeyNameW,
nBytes,
driverKeyNameW,
nBytes,
&nBytes,
NULL);
if (!success)
{
goto GetDriverKeyNameError;
}
driverKeyNameA = WideStrToMultiStr(driverKeyNameW->DriverKeyName);
free(driverKeyNameW);
return driverKeyNameA;
GetDriverKeyNameError:
if (driverKeyNameW != NULL)
{
free(driverKeyNameW);
driverKeyNameW = NULL;
}
return NULL;
}
PCHAR GetRootHubName(HANDLE HostController)
{
BOOL success;
ULONG nBytes;
USB_ROOT_HUB_NAME rootHubName;
PUSB_ROOT_HUB_NAME rootHubNameW;
PCHAR rootHubNameA;
rootHubNameW = NULL;
rootHubNameA = NULL;
success = DeviceIoControl(HostController,
IOCTL_USB_GET_ROOT_HUB_NAME,
0,
0,
&rootHubName,
sizeof(rootHubName),
&nBytes,
NULL);
if (!success)
{
goto GetRootHubNameError;
}
nBytes = rootHubName.ActualLength;
rootHubNameW =(PUSB_ROOT_HUB_NAME) malloc(nBytes);
if (rootHubNameW == NULL)
{
goto GetRootHubNameError;
}
success = DeviceIoControl(HostController,
IOCTL_USB_GET_ROOT_HUB_NAME,
NULL,
0,
rootHubNameW,
nBytes,
&nBytes,
NULL);
if (!success)
{
goto GetRootHubNameError;
}
rootHubNameA = WideStrToMultiStr(rootHubNameW->RootHubName);
free(rootHubNameW);
return rootHubNameA;
GetRootHubNameError:
if (rootHubNameW != NULL)
{
free(rootHubNameW);
rootHubNameW = NULL;
}
return NULL;
}
PCHAR GetHCDDriverKeyName(HANDLE HCD)
{
BOOL success;
ULONG nBytes;
USB_HCD_DRIVERKEY_NAME driverKeyName;
PUSB_HCD_DRIVERKEY_NAME driverKeyNameW;
PCHAR driverKeyNameA;
driverKeyNameW = NULL;
driverKeyNameA = NULL;
success = DeviceIoControl(HCD,
IOCTL_GET_HCD_DRIVERKEY_NAME,
&driverKeyName,
sizeof(driverKeyName),
&driverKeyName,
sizeof(driverKeyName),
&nBytes,
NULL);
if (!success)
{
goto GetHCDDriverKeyNameError;
}
nBytes = driverKeyName.ActualLength;
if (nBytes <= sizeof(driverKeyName))
{
goto GetHCDDriverKeyNameError;
}
driverKeyNameW =(PUSB_HCD_DRIVERKEY_NAME) malloc(nBytes);
if (driverKeyNameW == NULL)
{
goto GetHCDDriverKeyNameError;
}
success = DeviceIoControl(HCD,
IOCTL_GET_HCD_DRIVERKEY_NAME,
driverKeyNameW,
nBytes,
driverKeyNameW,
nBytes,
&nBytes,
NULL);
if (!success)
{
goto GetHCDDriverKeyNameError;
}
driverKeyNameA = WideStrToMultiStr(driverKeyNameW->DriverKeyName);
free(driverKeyNameW);
return driverKeyNameA;
GetHCDDriverKeyNameError:
if (driverKeyNameW != NULL)
{
free(driverKeyNameW);
driverKeyNameW = NULL;
}
return NULL;
}
PCHAR WideStrToMultiStr(PWCHAR WideStr)
{
ULONG nBytes;
PCHAR MultiStr;
nBytes = WideCharToMultiByte(
CP_ACP,
0,
WideStr,
-1,
NULL,
0,
NULL,
NULL);
if (nBytes == 0)
{
return NULL;
}
MultiStr =(PCHAR) malloc(nBytes);
if (MultiStr == NULL)
{
return NULL;
}
nBytes = WideCharToMultiByte(
CP_ACP,
0,
WideStr,
-1,
MultiStr,
nBytes,
NULL,
NULL);
if (nBytes == 0)
{
free(MultiStr);
return NULL;
}
return MultiStr;
}
bool GetStringDescriptor (
HANDLE hHubDevice,
ULONG ConnectionIndex,
UCHAR DescriptorIndex ,
CHAR * outBuff
)
{
BOOL success;
ULONG nBytes;
ULONG nBytesReturned;
UCHAR stringDescReqBuf[sizeof(USB_DESCRIPTOR_REQUEST) + MAXIMUM_USB_STRING_LENGTH];
PUSB_DESCRIPTOR_REQUEST stringDescReq;
PUSB_STRING_DESCRIPTOR stringDesc;
nBytes = sizeof(stringDescReqBuf);
stringDescReq = (PUSB_DESCRIPTOR_REQUEST)stringDescReqBuf;
stringDesc = (PUSB_STRING_DESCRIPTOR)(stringDescReq+1);
::ZeroMemory(stringDescReq,nBytes);
stringDescReq->ConnectionIndex = ConnectionIndex;
stringDescReq->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) | DescriptorIndex;
stringDescReq->SetupPacket.wIndex = GetSystemDefaultLangID();
stringDescReq->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST));
success = DeviceIoControl(hHubDevice,IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
stringDescReq,nBytes,
stringDescReq,nBytes,
&nBytesReturned,NULL);
if (!success || nBytesReturned < 2)
return false;
if (stringDesc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE)
return false;
if (stringDesc->bLength != nBytesReturned - sizeof(USB_DESCRIPTOR_REQUEST))
return false;
if (stringDesc->bLength % 2 != 0)
return false;
WCHAR * wChar = new WCHAR[stringDesc->bLength + 1];
memcpy(wChar,stringDesc->bString,stringDesc->bLength);
char *szTemp = WideStrToMultiStr(wChar);
lstrcpy(outBuff, szTemp);
if(szTemp)
delete []szTemp;
if(wChar)
delete []wChar;
return true;
}
分析:
1)首先假定有10个usb接口
#define NUM_HCS_TO_CHECK 10
2)循环打开这10个usb端口,如果端口没有这么多,调用CreateFile,就会返回 INVALID_HANDLE_VALUE。
for (HCNum = 0; HCNum < NUM_HCS_TO_CHECK; HCNum++)
{
wsprintf(HCName, ".//HCD%d", HCNum);
hHCDev = CreateFile(HCName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hHCDev == INVALID_HANDLE_VALUE)
break;
3)获取root hub
ULONG nBytes;
rootHubName =(char*) GetRootHubName(hHCDev);
if(rootHubName==NULL)
goto end;
4) 遍历连接在root hub上的节点
int port;
port=HubInfo->u.HubInformation.HubDescriptor.bNumberOfPorts;
for (index=1; index <= port; index++)
{
ULONG nBytes;
nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION) +
sizeof(USB_PIPE_INFO) * 30;
connectionInfo = (PUSB_NODE_CONNECTION_INFORMATION)malloc(nBytes);
if (connectionInfo == NULL)
goto end;
connectionInfo->ConnectionIndex = index;
success = DeviceIoControl(hHubDevice,
IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,
connectionInfo,
nBytes,
connectionInfo,
nBytes,
&nBytes,
NULL);
if (!success)
{
free(connectionInfo);
goto end;
}
5)根据节点的连接状态,获取节点信息,得到序列号。
if (connectionInfo->ConnectionStatus == DeviceConnected)
{
//取出序列号索引
UCHAR nSerialno = connectionInfo->DeviceDescriptor.iSerialNumber;
CHAR OutBuff[20] = {0};
GetStringDescriptor(hHubDevice,connectionInfo->ConnectionIndex,nSerialno,OutBuff);
6)得到序列号的方法在理论部分已经详细说明了,对应的函数是GetStringDescriptor,这里不再重复。