枚举USB设备(代码)

来源:互联网 发布:手机淘宝外卖 编辑:程序博客网 时间:2024/05/01 05:25

枚举USB设备(代码)

作者:李sir | 出处:博客园 | 阅读181次 2011/10/27 17:48:25
 
 

转载于http://www.misssir.cn/art/_show.aspx?art=44

摘要:     从主控开始遍历,先是RootHub,然后每个端口,端口连接的设备类型、描述符,如果是Hub则继续向下遍历。代码已贴出来,如果您看到附件中的样例,会不会感觉和DDK中的usbview很像呢?

 

USB View是DDK中的示例程序,以前我也看过,感觉有点乱,这些天我有的是时间,就模仿它用VC++重新写了一个。全部代码如下:

//这里没有考虑释放句柄的问题,实际应用的时候要添上

//--------------------------------------------------------------------------

//USB设备在Windows中的显示名字

char* GetUsbDeviceLabel(char* key_name)

{

  HDEVINFO di = SetupDiGetClassDevs(&GUID_CLASS_USB_DEVICE, 0, 0, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);

  if(di == INVALID_HANDLE_VALUE)

  {

    MyPrintf("没有找到");

    return 0;

  }  

  for(int i = 0; ; i++)

  {

    BYTE tmp_buf1[513];  

    //主控的描述字符串

    SP_DEVINFO_DATA DevInfoData;

    DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    if(! SetupDiEnumDeviceInfo(di, i, &DevInfoData))

      break;

    if(! SetupDiGetDeviceRegistryProperty(di, &DevInfoData, SPDRP_DRIVER, 0, tmp_buf1, 513, 0))

      continue;

    if(strcmp(key_name, (char*)tmp_buf1) != 0)

      continue;

    if(SetupDiGetDeviceRegistryProperty(di, &DevInfoData, SPDRP_DEVICEDESC, 0, tmp_buf1, 513, 0))

    {

      strcpy(key_name, (char*)tmp_buf1);

      return key_name;

    }

    else

    {

      return 0;

    }

  }

  return 0;

}

void GetPortDevDescString(HANDLE hub, int port_idx, USB_DEVICE_DESCRIPTOR* dev_desc)

{

  //读语言的种类

  BYTE tmp_buf1[513] = {0};  

  DWORD data_len;

  USB_DESCRIPTOR_REQUEST* str_req = (USB_DESCRIPTOR_REQUEST*)tmp_buf1;

  USB_STRING_DESCRIPTOR* str_desc = (USB_STRING_DESCRIPTOR*)(tmp_buf1 + sizeof(USB_DESCRIPTOR_REQUEST) - 1);

  int LanIDs_num = 0;

  WORD* LanIDs = 0;

  int i;

  str_req->ConnectionIndex = port_idx;

  str_req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) | 0;

  str_req->SetupPacket.wIndex = 0;

  str_req->SetupPacket.wLength = (USHORT)(513 - sizeof(USB_DESCRIPTOR_REQUEST) + 1);

  if(! DeviceIoControl(hub, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, str_req, 513, str_req, 513, &data_len, 0))

  {

    LanIDs_num = 0;

    LanIDs = 0;

  }

  else

  {

    LanIDs_num = (str_desc->bLength - 2) / 2;

    LanIDs = str_desc->bString;

  }  

  //读语言

  BYTE tmp_buf2[513] = {0};

  str_req = (USB_DESCRIPTOR_REQUEST*)tmp_buf2;

  str_desc = (USB_STRING_DESCRIPTOR*)(tmp_buf2 + sizeof(USB_DESCRIPTOR_REQUEST) - 1);

  //输出

  MyPrintf("Device Descriptor:");

  MyPrintf("bcdUSB: 0x%04X", dev_desc->bcdUSB);

  MyPrintf("bDeviceClass: 0x%02X", dev_desc->bDeviceClass);

  MyPrintf("bDeviceSubClass: 0x%02X", dev_desc->bDeviceSubClass);

  MyPrintf("bDeviceProtocol: 0x%02X", dev_desc->bDeviceProtocol);

  MyPrintf("bMaxPacketSize0: 0x%02X (%d)", dev_desc->bMaxPacketSize0, dev_desc->bMaxPacketSize0);

  MyPrintf("idVendor: 0x%04X", dev_desc->idVendor);

  MyPrintf("idProduct: 0x%04X", dev_desc->idProduct);

  MyPrintf("bcdDevice: 0x%04X", dev_desc->bcdDevice);

  MyPrintf("iManufacturer: 0x%02X", dev_desc->iManufacturer);

  if(dev_desc->iManufacturer != 0)

  {

    for (i=0; i< LanIDs_num; i++)

    {

      str_req->ConnectionIndex = port_idx;

      str_req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) | dev_desc->iManufacturer;

      str_req->SetupPacket.wIndex = LanIDs[i];

      str_req->SetupPacket.wLength = (USHORT)(513 - sizeof(USB_DESCRIPTOR_REQUEST) + 1);

      if(! DeviceIoControl(hub, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, str_req, 513, str_req, 513, &data_len, 0))

        MyPrintf("0x%04X: 失败", LanIDs[i]);

      else

        MyPrintf("0x%04X: \"%S\"", LanIDs[i], str_desc->bString);

    }

  }

  MyPrintf("iProduct: 0x%02X", dev_desc->iProduct);

  if(dev_desc->iProduct != 0)

  {

    for (i=0; i< LanIDs_num; i++)

    {

      str_req->ConnectionIndex = port_idx;

      str_req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) | dev_desc->iProduct;

      str_req->SetupPacket.wIndex = LanIDs[i];

      str_req->SetupPacket.wLength = (USHORT)(513 - sizeof(USB_DESCRIPTOR_REQUEST) + 1);

      if(! DeviceIoControl(hub, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, str_req, 513, str_req, 513, &data_len, 0))

        MyPrintf("0x%04X: 失败", LanIDs[i]);

      else

        MyPrintf("0x%04X: \"%S\"", LanIDs[i], str_desc->bString);

    }

  }

  MyPrintf("iSerialNumber:: 0x%02X", dev_desc->iSerialNumber);

  if(dev_desc->iSerialNumber != 0)

  {

    for (i=0; i< LanIDs_num; i++)

    {

      memset(str_req, 0, 513);

      str_req->ConnectionIndex = port_idx;

      str_req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) | dev_desc->iSerialNumber;

      str_req->SetupPacket.wIndex = LanIDs[i];

      str_req->SetupPacket.wLength = (USHORT)(513 - sizeof(USB_DESCRIPTOR_REQUEST) + 1);

      if(! DeviceIoControl(hub, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, str_req, 513, str_req, 513, &data_len, 0))

        MyPrintf("0x%04X: 失败", LanIDs[i]);

      else

        MyPrintf("0x%04X: \"%S\"", LanIDs[i], str_desc->bString);

    }

  }

  MyPrintf("bNumConfigurations: 0x%02X", dev_desc->bNumConfigurations);

  MyPrintf("");

}

void GetEndpoint(int pip_num, USB_PIPE_INFO* pip_list)

{

  for(int i = 0; i < pip_num; i++)

  {

    USB_ENDPOINT_DESCRIPTOR* ep_desc = &(pip_list[i].EndpointDescriptor);

    MyPrintf("Endpoint Descriptor:");

    if(USB_ENDPOINT_DIRECTION_IN(ep_desc->bEndpointAddress))

      MyPrintf("bEndpointAddress: 0x%02X  IN", ep_desc->bEndpointAddress);

    else

      MyPrintf("bEndpointAddress: 0x%02X  OUT", ep_desc->bEndpointAddress);

    switch(ep_desc->bmAttributes & 0x03)

    {

      case 0x00:

        MyPrintf("Transfer Type: Control");

        break;

      case 0x01:

        MyPrintf("Transfer Type: Isochronous");

        break;

      case 0x02:

        MyPrintf("Transfer Type: Bulk");

        break;

      case 0x03:

        MyPrintf("Transfer Type: Interrupt");

        break;

    }

    MyPrintf("wMaxPacketSize: 0x%04X (%d)", ep_desc->wMaxPacketSize, ep_desc->wMaxPacketSize);

    if(ep_desc->bLength == sizeof(USB_ENDPOINT_DESCRIPTOR))

    {

      MyPrintf("bInterval: 0x%02X", ep_desc->bInterval);

    }

    else

    {

      USB_ENDPOINT_DESCRIPTOR2* ep_desc2 = (USB_ENDPOINT_DESCRIPTOR2*)ep_desc;

      MyPrintf("wInterval: 0x%04X", ep_desc2->wInterval);

      MyPrintf("bSyncAddress: 0x%02X", ep_desc2->bSyncAddress);

    }

    MyPrintf("");

  }  

}

void GetPortConfDescString(USB_CONFIGURATION_DESCRIPTOR* conf_desc)

{

  BYTE* desc_end = (BYTE*)conf_desc + conf_desc->wTotalLength;

  BYTE* desc_start = (BYTE*)conf_desc;

  while((desc_start + sizeof(USB_COMMON_DESCRIPTOR) < desc_end) && (desc_start + ((USB_COMMON_DESCRIPTOR*)desc_start)->bLength <= desc_end))

  {

    BYTE type = ((USB_COMMON_DESCRIPTOR*)desc_start)->bDescriptorType;

    if(type == USB_CONFIGURATION_DESCRIPTOR_TYPE)

    {

      USB_CONFIGURATION_DESCRIPTOR* conf2 = (USB_CONFIGURATION_DESCRIPTOR*)desc_start;

      MyPrintf("Configuration Descriptor:");

      MyPrintf("wTotalLength: 0x%04X", conf2->wTotalLength);

      MyPrintf("bNumInterfaces: 0x%02X", conf2->bNumInterfaces);

      MyPrintf("bConfigurationValue: 0x%02X", conf2->bConfigurationValue);

      MyPrintf("iConfiguration: 0x%02X", conf2->iConfiguration);

      char power[100] = {0};

      if (conf_desc->bmAttributes & 0x80)

        strcat(power, "Bus Powered ");

      if (conf_desc->bmAttributes & 0x40)

        strcat(power, "Self Powered ");

      if (conf_desc->bmAttributes & 0x20)

        strcat(power, "Remote Wakeup");

      MyPrintf("bmAttributes: 0x%02X (%s)", conf2->bmAttributes, power);

      MyPrintf("MaxPower: 0x%02X (%d mA)", conf2->MaxPower, conf_desc->MaxPower * 2);

    }

    else if(type == USB_INTERFACE_DESCRIPTOR_TYPE)

    {

      USB_INTERFACE_DESCRIPTOR* intf2 = (USB_INTERFACE_DESCRIPTOR*)desc_start;

      char* str2;

      MyPrintf("Interface Descriptor:");

      MyPrintf("bInterfaceNumber: 0x%02X", intf2->bInterfaceNumber);

      MyPrintf("bAlternateSetting: 0x%02X", intf2->bAlternateSetting);

      MyPrintf("bNumEndpoints: 0x%02X", intf2->bNumEndpoints);

      str2 = "";

      switch(intf2->bInterfaceClass)

      {

        case USB_DEVICE_CLASS_AUDIO:

          str2 = "(Audio)";

          break;

        case USB_DEVICE_CLASS_HUMAN_INTERFACE:

          str2 = "(HID)";

          break;

        case USB_DEVICE_CLASS_HUB:

          str2 = "(Hub)";

          break;

      }

      MyPrintf("bInterfaceClass: 0x%02X %s", intf2->bInterfaceClass, str2);

      str2 = "";

      if(intf2->bInterfaceClass == USB_DEVICE_CLASS_AUDIO)

      {

        switch (intf2->bInterfaceSubClass)

        {

          case USB_AUDIO_SUBCLASS_AUDIOCONTROL:

            str2 = " (Audio Control)";

            break;

          case USB_AUDIO_SUBCLASS_AUDIOSTREAMING:

            str2 = " (Audio Streaming)";

            break;

          case USB_AUDIO_SUBCLASS_MIDISTREAMING:

            str2 = " (MIDI Streaming)";

            break;

        }

      }

      MyPrintf("bInterfaceSubClass: 0x%02X %s", intf2->bInterfaceSubClass, str2);

      MyPrintf("bInterfaceProtocol: 0x%02X", intf2->bInterfaceProtocol);

      MyPrintf("iInterface: 0x%02X", intf2->iInterface);

      if(intf2->bLength == sizeof(USB_INTERFACE_DESCRIPTOR2))

      {

        USB_INTERFACE_DESCRIPTOR2* intf3 = (PUSB_INTERFACE_DESCRIPTOR2)intf2;

        MyPrintf("wNumClasses: 0x%04X", intf3->wNumClasses);

      }

    }

    else if(type == USB_ENDPOINT_DESCRIPTOR_TYPE)

    {

      USB_ENDPOINT_DESCRIPTOR* end2 = (USB_ENDPOINT_DESCRIPTOR*)desc_start;

      MyPrintf("Endpoint Descriptor:");

      if (USB_ENDPOINT_DIRECTION_IN(end2->bEndpointAddress))

        MyPrintf("bEndpointAddress: 0x%02X  IN", end2->bEndpointAddress);

      else

        MyPrintf("bEndpointAddress: 0x%02X  OUT", end2->bEndpointAddress);

      switch (end2->bmAttributes & 0x03)

      {

        case 0x00:

          MyPrintf("Transfer Type: Control");

          break;

        case 0x01:

          MyPrintf("Transfer Type: Isochronous");

          break;

        case 0x02:

          MyPrintf("Transfer Type: Bulk");

          break;

        case 0x03:

          MyPrintf("Transfer Type: Interrupt");

          break;

      }

      MyPrintf("wMaxPacketSize: 0x%04X (%d)", end2->wMaxPacketSize, end2->wMaxPacketSize);

      if (end2->bLength == sizeof(USB_ENDPOINT_DESCRIPTOR))

      {

        MyPrintf("bInterval: 0x%02X", end2->bInterval);

      }

      else

      {

        USB_ENDPOINT_DESCRIPTOR2* end3 = (USB_ENDPOINT_DESCRIPTOR2*)end2;

        MyPrintf("wInterval: 0x%04X", end3->wInterval);

        MyPrintf("bSyncAddress: 0x%02X", end3->bSyncAddress);

      }

    }

    else if(type == USB_HID_DESCRIPTOR_TYPE)

    {

      USB_HID_DESCRIPTOR* hid2 = (USB_HID_DESCRIPTOR*)desc_start;

      MyPrintf("HID Descriptor:");

      MyPrintf("bcdHID: 0x%04X", hid2->bcdHID);

      MyPrintf("bCountryCode: 0x%02X", hid2->bCountryCode);

      MyPrintf("bNumDescriptors: 0x%02X", hid2->bNumDescriptors);

      for(int i = 0; i < hid2->bNumDescriptors; i++)

      {

        MyPrintf("bDescriptorType: 0x%02X", hid2->OptionalDescriptors[i].bDescriptorType);

        MyPrintf("wDescriptorLength: 0x%04X", hid2->OptionalDescriptors[i].wDescriptorLength);

      }

    }

    else

    {

      MyPrintf("未知的描述符");

    }

    desc_start += ((USB_COMMON_DESCRIPTOR*)desc_start)->bLength;

    MyPrintf("");

  }

}

bool GetHubPort(HANDLE hub, int port_idx)

{

  BYTE tmp_buf1[513] = {0};  

  BYTE tmp_buf2[513] = {0};

  DWORD data_len;

 

  USB_NODE_CONNECTION_INFORMATION_EX* conn_info = (USB_NODE_CONNECTION_INFORMATION_EX*)tmp_buf1;

  conn_info->ConnectionIndex = port_idx;

  if(! DeviceIoControl(hub, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, conn_info, 513, conn_info, 513, &data_len, 0))

  {

    MyPrintf("端口%d连接失败", port_idx);

    return false;

  }  

  if (conn_info->ConnectionStatus == NoDeviceConnected)

  {

    MyPrintf("[Port%d]NoDeviceConnected", port_idx);

  }

  else

  {

    USB_NODE_CONNECTION_DRIVERKEY_NAME* key_name = (USB_NODE_CONNECTION_DRIVERKEY_NAME*)tmp_buf2;

    key_name->ConnectionIndex = port_idx;

    if(! DeviceIoControl(hub, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, key_name, 513, key_name, 513, &data_len, 0))

    {

      MyPrintf("[Port%d]DeviceConnected: 失败 \n", port_idx);

    }

    else

    {

      char* label = GetUsbDeviceLabel(WideStrToMultiStr(key_name->DriverKeyName));

      if(label != 0)

        MyPrintf("[Port%d]DeviceConnected: %s \n", port_idx, label);

      else

        MyPrintf("[Port%d]DeviceConnected: 失败 \n", port_idx);

    }

    gLevel++;

    //读设备的字符串

    GetPortDevDescString(hub, port_idx, &(conn_info->DeviceDescriptor));

    //连接状态信息

    MyPrintf("ConnectionStatus: %s", gHubPortConn[conn_info->ConnectionStatus]);

    MyPrintf("Current Config Value: 0x%02X", conn_info->CurrentConfigurationValue);

    switch(conn_info->Speed)

    {

      case UsbLowSpeed:

        MyPrintf("Device Bus Speed: Low");

        break;

      case UsbFullSpeed:

        MyPrintf("Device Bus Speed: Full");

        break;

      case UsbHighSpeed:

        MyPrintf("Device Bus Speed: High");

        break;

      default:

        MyPrintf("Device Bus Speed: Unknown");

    }

    MyPrintf("Device Address: 0x%02X", conn_info->DeviceAddress);

    MyPrintf("Open Pipes: %2d", conn_info->NumberOfOpenPipes);

    MyPrintf("");

    //端点描述符

    GetEndpoint(conn_info->NumberOfOpenPipes, conn_info->PipeList);

    //配置描述符

    if(conn_info->ConnectionStatus == DeviceConnected)

    {

      USB_DESCRIPTOR_REQUEST* conf_req = (USB_DESCRIPTOR_REQUEST*)tmp_buf2;

      USB_CONFIGURATION_DESCRIPTOR* conf_desc = (USB_CONFIGURATION_DESCRIPTOR*)(tmp_buf2 + sizeof(USB_DESCRIPTOR_REQUEST) - 1);

      conf_req->ConnectionIndex = port_idx;

      conf_req->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | 0;

      conf_req->SetupPacket.wIndex = 0;

      conf_req->SetupPacket.wLength = (USHORT)(513 - sizeof(USB_DESCRIPTOR_REQUEST) + 1);

      //读配置描述符等

      if(DeviceIoControl(hub, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, conf_req, 513, conf_req, 513, &data_len, 0))

        GetPortConfDescString(conf_desc);

      else     

        MyPrintf("读配置描述符失败 \n");

    }

    if(conn_info->DeviceIsHub)

    {

      USB_NODE_CONNECTION_NAME* hub_name = (USB_NODE_CONNECTION_NAME*)tmp_buf2;

      hub_name->ConnectionIndex = port_idx;

      if(! DeviceIoControl(hub, IOCTL_USB_GET_NODE_CONNECTION_NAME, 0, 0, hub_name, 513, &data_len, 0))

      {

        MyPrintf("不能得到连接的Hub的名字");

        return false;

      }

      else

      {

        if(! GetHub(WideStrToMultiStr(hub_name->NodeName)))

          return false;

      }

    }

    gLevel--;

  }

  return true;

}

bool GetHub(char* hub_name)

{

  gLevel++;

  MyPrintf("Root Hub: %s", hub_name);

  BYTE tmp_buf1[513] = {0};

  char* hub_path = (char*)tmp_buf1;

  strcat(hub_path, "\\\\.\\");

  strcat(hub_path, hub_name);

  HANDLE hub = CreateFile(hub_path, GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);

  if(hub == INVALID_HANDLE_VALUE)

  {

    MyPrintf("打开Hub失败");

    return false;

  }

  USB_NODE_INFORMATION* hub_info = (USB_NODE_INFORMATION*)tmp_buf1;

  USB_HUB_DESCRIPTOR* hub_desc = &(hub_info->u.HubInformation.HubDescriptor);

  DWORD data_len;

  if(! DeviceIoControl(hub, IOCTL_USB_GET_NODE_INFORMATION, 0, 0, hub_info, 513, &data_len, 0))

  {

    MyPrintf("获得端口信息失败");

    return false;

  }

  if(hub_info->u.HubInformation.HubIsBusPowered)

    MyPrintf("Hub Power: Bus Power");

  else

    MyPrintf("Hub Power: Self Power");

  MyPrintf("Number of Ports: %d", hub_desc->bNumberOfPorts);

  switch(hub_desc->wHubCharacteristics & 0x0003)

  {

    case 0x0000:

      MyPrintf("Power switching: Ganged");

      break;

    case 0x0001:

      MyPrintf("Power switching: Individual");

      break;

    case 0x0002:

    case 0x0003:

      MyPrintf("Power switching: None");

      break;

  }

  switch (hub_desc->wHubCharacteristics & 0x0004)

  {

    case 0x0000:

      MyPrintf("Compound device: No");

      break;

    case 0x0004:

      MyPrintf("Compound device: Yes");

      break;

  }

  switch (hub_desc->wHubCharacteristics & 0x0018)

  {

    case 0x0000:

      MyPrintf("Over-current Protection: Global");

      break;

    case 0x0008:

      MyPrintf("Over-current Protection: Individual");

      break;

    case 0x0010:

    case 0x0018:

      MyPrintf("No Over-current Protection (Bus Power Only)");

      break;

  }

  MyPrintf("");

 

  for(int port_idx = 1; port_idx <= hub_desc->bNumberOfPorts; port_idx++)

  {    

    if(! GetHubPort(hub, port_idx))

      return false;

  }

  gLevel--;

  return true;

}

bool GetHostControll()

{

  gLevel++;

  HDEVINFO di = SetupDiGetClassDevs(&GUID_CLASS_USB_HOST_CONTROLLER, 0, 0, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);

  if(di == INVALID_HANDLE_VALUE)

  {

    MyPrintf("没有找到主控类的设备");

    return false;

  }  

  for(int i = 0; ; i++)

  {

    BYTE tmp_buf1[513];  

    DWORD data_len;

   

    //枚举类别中每一个主控

    SP_DEVICE_INTERFACE_DATA ifdata;

    ifdata.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

    if(! SetupDiEnumDeviceInterfaces(di, 0, &GUID_CLASS_USB_HOST_CONTROLLER, i, &ifdata))

    {

      MyPrintf("USB主控类中再没有其它设备了 \n");

      break;     

    }

    //主控的描述字符串

    SP_DEVINFO_DATA DevInfoData;

    DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    if(SetupDiEnumDeviceInfo(di, i, &DevInfoData))

    {

      if(SetupDiGetDeviceRegistryProperty(di, &DevInfoData, SPDRP_DEVICEDESC, 0, tmp_buf1, 513, 0))

      {

        MyPrintf("%s", (char*)tmp_buf1);

      }

      if(SetupDiGetDeviceRegistryProperty(di, &DevInfoData, SPDRP_HARDWAREID, 0, tmp_buf1, 513, 0))

      {

        MyPrintf("%s", (char*)tmp_buf1);

      }

    }

    //主控的路径

    SP_DEVICE_INTERFACE_DETAIL_DATA* ifdetail = (SP_DEVICE_INTERFACE_DETAIL_DATA*)tmp_buf1;

    ifdetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    if(! SetupDiGetDeviceInterfaceDetail(di, &ifdata, ifdetail, 513, 0, 0))

    {

      MyPrintf("获得主控的设备路径失败");

      return false;

    }

    //打开主控

    HANDLE host = CreateFile(ifdetail->DevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);

    if(host == INVALID_HANDLE_VALUE)

    {

      MyPrintf("打开主控失败");

      return false;

    }

    USB_HCD_DRIVERKEY_NAME* key_name = (USB_HCD_DRIVERKEY_NAME*)tmp_buf1;

    if(! DeviceIoControl(host, IOCTL_GET_HCD_DRIVERKEY_NAME, 0, 0, key_name, 513, &data_len, 0))

      MyPrintf("DriverKey: 失败");

    else

      MyPrintf("DriverKey: %S", key_name->DriverKeyName);

    MyPrintf("");

    MyPrintf("RootHub \n");

    //根Hub的名字(路径)

    USB_ROOT_HUB_NAME* hub_name = (USB_ROOT_HUB_NAME*)tmp_buf1;

    if(! DeviceIoControl(host, IOCTL_USB_GET_ROOT_HUB_NAME, 0, 0, hub_name, 513, &data_len, 0))

    {

      MyPrintf("根Hub名字失败");

      return false;

    }

    else

    {

      //枚举Hub下面的设备

      if(! GetHub(WideStrToMultiStr(hub_name->RootHubName)))

        return false;

    }

    MyPrintf("");

  }

  gLevel--;

  return true;

}

void main()

{

  gLevel = 0;

  MyPrintf("My Computer \n");

 

  if(GetHostControll())

    MyPrintf("遍历成功");

  else

    MyPrintf("遍历失败");

}