title: How to enumerate an USB hub that is attached to the first port of root hub on Windows Embedded 7
body: <p>I am posting here for the first time, I hope this will be clear and readable.</p>
  
  <p>I am currently trying to test the presence of usb devices on an embedded system using a specific HCD and port path programmatically using C++ and Visual Studio 2008.</p>
  
  <p>The idea is to pass in the port number and the hcd value as the parameters of the function, and the function will return a true or false that indicates the connection status.  </p>
  
  <p>I have written some code to populate the root hub and prove that the device attached to port 1 of the root hub is a hub using <code>bool DeviceIsHub</code> from <code>usbioctl.h</code>.</p>
  
  <p>However, when I attempt to enumerate the usb hub attached to port 1 of root so that I may test for the connection status of the downstream ports for the presence of device(ports 1 and 2 of this usb hub). It does not seem to know how many downstream ports the usb hub has. </p>
  
  <p>I checked USBVIEW/TreeView, both application tells me that devices are there
  but I am not sure what ioctl command code to use such that I can enumerate the downstream ports so I can check the connection status.</p>
  
  <p>The structure of the device based on USB view and USB tree provides the following.</p>
  
  <ul>
  <li><p>Root hub - it has 7 ports, only the first port is being used. </p></li>
  <li><p>A USB hub (it has four available ports) is attached to the first port of the root hub. </p></li>
  <li><p>Two USB devices (USB mouse and USB keyboard) are attached to port 1 and port 2 of the USB hub.</p></li>
  </ul>
  
  <p>I have tried <code>IOCTL_USB_GET_CONNECTION_INFORMATION</code>, <code>IOCTL_USB_GET_CONNECTION_NAME</code>, <code>
  IOCTL_USB_GET_CONNECTION_INFORMATION_EX</code>, <code>IOCTL_USB_PORT_CONNECTOR_PROPERTIES</code></p>
  
  <p>(which is not supported, it can only be used in windows 8, this is the exact ioctl call they used to enumerate the ports).</p>
  
  <p>Please ignore the MessageBoxes, those are for me to check the control path status and determine which route it was following. </p>
  
  <p>Please find the code that I wrote as I attempt to enumerate/populate the usb hub. I did not include the Root hub code because it would make this snippet too big. </p>
  
  <p>My questions mainly resides in the enumeration process of the secondary USB hub I believe.
  I just checked the registry key of the device. it appears that the USB hub is enumerated and present on the device since the information is shown under regedit <code>HKLM-&gt;System-&gt;CurrentControlSet-&gt;Enum-&gt;USB</code>. I believe I am not enumerating it correctly within my test application. </p>
  
  <p>Any help would be greatly appreciated. </p>
  
  <p><strong>Update</strong></p>
  
  <p>The part that I am most concerned about is the DeviceIoControl Calls that attempts to get the size and the actual name of that USB hub.</p>
  
  <p>It currently only takes in USB_GET_NODE_INFORMATION. Any other ioctl calls that are intended to retrieve the name of the hub will fail at the first DeviceIoControl where it attempts to get the size of the hub name so that it know how much memory to allocate 
  for it.</p>
  
  <p><strong>Update Part 2</strong></p>
  
  <p>From observing the usbview open source code, I believe I need to enumerate the host controller and all the devices first before checking for the presence of device. I drew a conclusion such that without doing the enumeration of controller, it only goes so far down the tree (at best second layer, which is where the external hub is attached to in my case). </p>
  
  <p>I am currently attempting to enumerate the other devices and controllers in hope that I can get to the third layer of device. I will keep on updating this thread until either I figure out the problem myself or someone is capable of answering my questions.</p>
  
  <pre><code>    //we are connected to the external hub, now we can begin the configuration and enumeration of the external hub.
          ULONG           kBytes = 0;
          USB_HUB_NAME    SubHubName;
      //Create a Handle for the external hub driver
          char Name[16];
               wsprintf(Name, "\\\\.\\HCD%d", HcdSub);
               HANDLE SubHub = CreateFile(Name,
                            GENERIC_WRITE,
                            FILE_SHARE_WRITE,
                            NULL,
                            OPEN_EXISTING,
                            0,
                            NULL);
  
      //Check to see if the handle was created successfully 
      if (SubHub == INVALID_HANDLE_VALUE)
           {
               MessageBox(NULL,"SubHandle Fail ","TEST",MB_OK);
                   return false;
           }
  //Query the SUBHUB/External Hub for the structure, this will tell us the number of down stream ports we need to enumerate
      ioctlSuccess = DeviceIoControl(SubHub,
                        IOCTL_USB_GET_NODE_INFORMATION,
                        0,
                        0,
                        &amp;SubHubName,
                        sizeof(SubHubName),
                        &amp;kBytes,
                        NULL);
  
      //If the command failed, close the handle and return false.
      if(!ioctlSuccess)
      {
          CloseHandle(SubHub);
          MessageBox(NULL," sub hub size fail ","TEST",MB_OK);
          return false;
      }
      //Prepare to receive the SubHubName
      kBytes = SubHubName.ActualLength;
      USB_HUB_NAME *subHubNameW = (USB_HUB_NAME *) malloc(sizeof(USB_HUB_NAME) * kBytes);
      //Check if the allocation failed, if it did, free the memory allocated and return false.
      if (subHubNameW == NULL)
      {
          free(subHubNameW);
          CloseHandle(SubHub);
          MessageBox(NULL,"SUBHubNameW=NULL ","TEST",MB_OK);
          return false;
      }
      //Send the command to retrieve the name
          ioctlSuccess = DeviceIoControl(SubHub,
                        IOCTL_USB_GET_NODE_INFORMATION,
                        NULL,
                        0,
                        subHubNameW,
                        kBytes,
                        &amp;kBytes,
                        NULL);
      //We no longer need this handle.
      CloseHandle(SubHub);
      if(!ioctlSuccess)
      {
          if(subHubNameW !=NULL)
          {
              free(subHubNameW);
          }
          MessageBox(NULL,"GET NODE INFO FAIL ","TEST",MB_OK);
          return false;
      }
  
      //Converts the SubHubNAme from widechar to a cahr.
      MessageBox(NULL,"BEGIN CONVERTION","TEST",MB_OK);
      kBytes = wcslen(subHubNameW-&gt;HubName) + 1;
      char *subhubname = (char *) malloc(sizeof(char)*kBytes);
      wcstombs(subhubname,subHubNameW-&gt;HubName, kBytes);
      //we no longer need subHubNameW the information is now in subhubname.
      if(subHubNameW !=NULL)
      {
          free(subHubNameW);
      }
      //Attempt to open a handle to driver for sub hub.
      int SubhdnSize = strlen(subhubname) + sizeof("\\\\.\\");
      char *subhubnamelength = (char *) malloc(sizeof(char) * SubhdnSize);
      sprintf(subhubnamelength, "\\\\.\\%s", subhubname);
      //We no longer need subhubname, so free it.
      if(subhubname !=NULL) free(subhubname);
      //Attempt to open a handle for enumerating ports on this hub.
  
      HANDLE ExternalHub = CreateFile(subhubnamelength,
                      GENERIC_WRITE,
                      FILE_SHARE_WRITE,
                      NULL,
                      OPEN_EXISTING,
                      0,
                      NULL);
  //we no longer need subhubnamelength, so free it if it is not NULL
      if(subhubnamelength != NULL) free(subhubnamelength);
          //Check and see if the handle was created successfully, if not, return false.
          if(ExternalHub == INVALID_HANDLE_VALUE)
          {
                  CloseHandle(ExternalHub);
                  MessageBox(NULL,"EXT handle fail ","TEST",MB_OK);
                  return false;
          }
      }
  
  USB_NODE_CONNECTION_ATTRIBUTES *PortConnection = 
  (USB_NODE_CONNECTION_ATTRIBUTES *) malloc(sizeof(USB_NODE_CONNECTION_ATTRIBUTES));
  PortConnection -&gt;ConnectionIndex = Port;
  
  ioctlSuccess = DeviceIoControl(ExternalHub,
                    IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES,
                    PortConnection,
                    sizeof(USB_NODE_CONNECTION_ATTRIBUTES),
                    PortConnection,
                    sizeof(USB_NODE_CONNECTION_ATTRIBUTES),
                    &amp;kBytes,
                    NULL);
  
      if(!ioctlSuccess)
      {
          MessageBox(NULL,"DEVICE CONNECTION FAIL ","TEST",MB_OK);
          return false;
      }
      if(PortConnection-&gt;ConnectionStatus !=DeviceConnected)
      {
          printf("The Connection Status Returns: %d",PortConnection-&gt;ConnectionStatus);
          printf("\n");
          return false;
      }
  </code></pre>