代码:见光盘GetSerialNo
#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,这里不再重复
|