int
USBGetEndpointDescriptor(void *deviceHandle, int endpoint_index,
        struct USBEndpointDescriptor *desc) {
    DWORD bytesReturned = 0;
    BOOL flag = FALSE;
    BYTE temp[DEVICE_PATH_SIZE];
    int offset = 0;
    __usb_interface_t *usb;

    if(0 == desc) {
        return -1;
    }

    if(0 == deviceHandle) {
        return -2;
    }

    usb = (__usb_interface_t *)deviceHandle;
    memset(temp, 0, sizeof(temp));

    flag = WinUsb_GetDescriptor(usb->winUSBHandle,
        USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0, temp,
        sizeof(temp), &bytesReturned);

    if(FALSE == flag) {
        return -1;
    }

    /* If we got here without the flag above getting set to false
     * all appears well.  We now should have the following data
     * in temp:
     *
     * Configuration Descriptor (9 bytes)
     * Interface Descriptor (9 bytes)
     * Endpoint 0 Descriptor (7 bytes)
     * Endpoint 1 Descriptor (7 bytes)
     * Enpoint 2 Descriptor (7 bytes)
     * Endpoint 3 Descriptor (7 bytes)
     * <<< and so on (if there are more than 4 endpoints) ... >>>
     *
     * Next, parse the descriptors out correctly.  We can use the
     * WinUsb_ParseDescriptors function to search for the descriptor
     * we want but the implementation of that fucntion means we have to
     * find the first Endpoint Descriptor, then loop until we've iterated
     * through to find what we think is the Endpoint Descriptor we need.
     * It is cumbersome and seems unecessary since the documetation implies
     * that the resulting data will always be returned in the same order.
     * Calculating the memory offset and just doing a memcpy is faster.
     */
    offset = sizeof(struct USBConfigurationDescriptor) +
        sizeof(struct USBInterfaceDescriptor) +
        (sizeof(struct USBEndpointDescriptor) * endpoint_index) -
        endpoint_index - 1;

    memcpy(desc, temp + offset, sizeof(struct USBEndpointDescriptor));

    return 0;
}
示例#2
0
int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, 
                          size_t buflen)
{
   unsigned char temp[MAXIMUM_USB_STRING_LENGTH];

   ULONG actlen = 0;
   if (!WinUsb_GetDescriptor(dev->fd, USB_STRING_DESCRIPTOR_TYPE, index, 0x0409, 
                             temp, sizeof(temp), &actlen))
   {
      return -(int)GetLastError();
   }

   // Skip first two bytes of result (descriptor id and length), then take 
   // every other byte as a cheap way to convert Unicode to ASCII
   unsigned int i, j;
   for (i = 2, j = 0; i < actlen && j < (buflen-1); i+=2, ++j)
      buf[j] = temp[i];
   buf[j] = '\0';

   return strlen(buf);
}
示例#3
0
static int usb_get_device_desc(struct usb_device *dev)
{
   struct usb_dev_handle *hnd = usb_open(dev);
   if (!hnd)
      return 1;

   ULONG actlen = 0;
   if (!WinUsb_GetDescriptor(hnd->fd, USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, 
                             (unsigned char*)&dev->descriptor, 
                             sizeof(dev->descriptor), &actlen)
       || actlen != sizeof(dev->descriptor))
   {
      return 1;
   }

   // Descriptor as read from the device is in little-endian format. No need
   // to convert since this is guaranteed to be Windows which runs only on
   // little-endian processors.

   return usb_close(hnd);
}
int
USBGetInterfaceDescriptor(void *deviceHandle, struct USBInterfaceDescriptor *desc) {
    DWORD bytesReturned = 0;
    BOOL flag = FALSE;
    BYTE temp[DEVICE_PATH_SIZE];
    PUSB_COMMON_DESCRIPTOR retval;
    __usb_interface_t *usb;

    if(0 == desc) {
        return -1;
    }

    if(0 == deviceHandle) {
        return -2;
    }

    usb = (__usb_interface_t *)deviceHandle;
    memset(temp, 0, sizeof(temp));

    flag = WinUsb_GetDescriptor(usb->winUSBHandle,
        USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0, temp,
        sizeof(temp), &bytesReturned);

    if(FALSE == flag) {
        return -3;
    }

    retval = WinUsb_ParseDescriptors(temp, bytesReturned, temp,
        USB_INTERFACE_DESCRIPTOR_TYPE);

    if(NULL == retval) {
        return -4;
    }

    memcpy(desc, retval, sizeof(struct USBInterfaceDescriptor));

    return 0;
}
int __getDeviceDescriptor(WINUSB_INTERFACE_HANDLE handle,
        struct USBDeviceDescriptor *desc) {
    DWORD bytesReturned;
    BOOL flag;

    if(NULL == handle) {
        return 0;
    }

    if(NULL == desc) {
        return 0;
    }

    flag = WinUsb_GetDescriptor(handle,
        USB_DEVICE_DESCRIPTOR_TYPE, 0, 0x0409, (PUCHAR)desc,
        sizeof(struct USBDeviceDescriptor), &bytesReturned);

    if(FALSE == flag) {
        return -1;
    }

    return 0;
}
int
USBGetStringDescriptor(void *deviceHandle, unsigned int string_index,
                       char *user_buffer, int maxLength) {
    __usb_interface_t *usb;
    char buffer[512];
    DWORD bytesReturned;
    BOOL retval = TRUE;
    int stringLength = 0;
    int i = 0;

    if(0 == deviceHandle) {
        return -1;
    }

    usb = (__usb_interface_t *)deviceHandle;
    memset(buffer, 0, sizeof(buffer));

    retval = WinUsb_GetDescriptor(usb->winUSBHandle,
            USB_STRING_DESCRIPTOR_TYPE, (UCHAR) string_index, 0x0409, (PUCHAR) buffer,
            (ULONG)sizeof(buffer), &bytesReturned);

    if (FALSE == retval) {
        return -1;
    }

    /* The string in the buffer is a string of Unicode characters.  This
     * converts back to a simple ASCII string.  If the caller really
     * wanted Unicode this could be done differently.
     */
    stringLength = (bytesReturned - 2) / 2;
    for (i = 0; i < stringLength && i < maxLength; i++) {
        user_buffer[i] = buffer[2 + (i * 2)];
    }

    return stringLength;
}
示例#7
0
LONG __cdecl
_tmain(
    LONG     Argc,
    LPTSTR * Argv
    )
/*++

Routine description:

    Sample program that communicates with a USB device using WinUSB

--*/
{
    DEVICE_DATA           deviceData;
    HRESULT               hr;
    USB_DEVICE_DESCRIPTOR deviceDesc;
    BOOL                  bResult;
    BOOL                  noDevice;
    ULONG                 lengthReceived;

    UNREFERENCED_PARAMETER(Argc);
    UNREFERENCED_PARAMETER(Argv);

    //
    // Find a device connected to the system that has WinUSB installed using our
    // INF
    //
    hr = OpenDevice(&deviceData, &noDevice);

    if (FAILED(hr)) {

        if (noDevice) {

            printf(_T("Device not connected or driver not installed\n"));

        } else {

            printf(_T("Failed looking for device, HRESULT 0x%x\n"), hr);
        }

        return 0;
    }

    //
    // Get device descriptor
    //
    bResult = WinUsb_GetDescriptor(deviceData.WinusbHandle,
                                   USB_DEVICE_DESCRIPTOR_TYPE,
                                   0,
                                   0,
                                   (PBYTE) &deviceDesc,
                                   sizeof(deviceDesc),
                                   &lengthReceived);

    if (FALSE == bResult || lengthReceived != sizeof(deviceDesc)) {

        printf(_T("Error among LastError %d or lengthReceived %d\n"),
               FALSE == bResult ? GetLastError() : 0,
               lengthReceived);
        CloseDevice(&deviceData);
        return 0;
    }

    //
    // Print a few parts of the device descriptor
    //
    printf(_T("Device found: VID_%04X&PID_%04X; bcdUsb %04X\n"),
           deviceDesc.idVendor,
           deviceDesc.idProduct,
           deviceDesc.bcdUSB);

    CloseDevice(&deviceData);
    return 0;
}
ADBAPIHANDLE AdbWinUsbInterfaceObject::CreateHandle() {
  // Open USB device for this inteface Note that WinUsb API
  // requires the handle to be opened for overlapped I/O.
  usb_device_handle_ = CreateFile(interface_name().c_str(),
                                  GENERIC_READ | GENERIC_WRITE,
                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
                                  NULL, OPEN_EXISTING,
                                  FILE_FLAG_OVERLAPPED, NULL);
  if (INVALID_HANDLE_VALUE == usb_device_handle_)
    return NULL;

  // Initialize WinUSB API for this interface
  if (!WinUsb_Initialize(usb_device_handle_, &winusb_handle_))
    return NULL;

  // Cache current interface number that will be used in
  // WinUsb_Xxx calls performed on this interface.
  if (!WinUsb_GetCurrentAlternateSetting(winusb_handle(), &interface_number_))
    return false;

  // Cache interface properties
  unsigned long bytes_written;

  // Cache USB device descriptor
  if (!WinUsb_GetDescriptor(winusb_handle(), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0,
                            reinterpret_cast<PUCHAR>(&usb_device_descriptor_),
                            sizeof(usb_device_descriptor_), &bytes_written)) {
    return false;
  }

  // Cache USB configuration descriptor
  if (!WinUsb_GetDescriptor(winusb_handle(), USB_CONFIGURATION_DESCRIPTOR_TYPE,
                            0, 0,
                            reinterpret_cast<PUCHAR>(&usb_config_descriptor_),
                            sizeof(usb_config_descriptor_), &bytes_written)) {
    return false;
  }

  // Cache USB interface descriptor
  if (!WinUsb_QueryInterfaceSettings(winusb_handle(), interface_number(),
                                     &usb_interface_descriptor_)) {
    return false;
  }

  // Save indexes and IDs for bulk read / write endpoints. We will use them to
  // convert ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX and
  // ADB_QUERY_BULK_READ_ENDPOINT_INDEX into actual endpoint indexes and IDs.
  for (UCHAR endpoint = 0; endpoint < usb_interface_descriptor_.bNumEndpoints;
       endpoint++) {
    // Get endpoint information
    WINUSB_PIPE_INFORMATION pipe_info;
    if (!WinUsb_QueryPipe(winusb_handle(), interface_number(), endpoint,
                          &pipe_info)) {
      return false;
    }

    if (UsbdPipeTypeBulk == pipe_info.PipeType) {
      // This is a bulk endpoint. Cache its index and ID.
      if (0 != (pipe_info.PipeId & USB_ENDPOINT_DIRECTION_MASK)) {
        // Use this endpoint as default bulk read endpoint
        ATLASSERT(0xFF == def_read_endpoint_);
        def_read_endpoint_ = endpoint;
        read_endpoint_id_ = pipe_info.PipeId;
      } else {
        // Use this endpoint as default bulk write endpoint
        ATLASSERT(0xFF == def_write_endpoint_);
        def_write_endpoint_ = endpoint;
        write_endpoint_id_ = pipe_info.PipeId;
      }
    }
  }

  return AdbInterfaceObject::CreateHandle();
}
bool AdbWinUsbInterfaceObject::GetSerialNumber(void* buffer,
                                               unsigned long* buffer_char_size,
                                               bool ansi) {
  if (!IsOpened()) {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }

  if (NULL == buffer_char_size) {
    SetLastError(ERROR_INVALID_PARAMETER);
    return false;
  }

  // Calculate serial number string size. Note that WinUsb_GetDescriptor
  // API will not return number of bytes needed to store serial number
  // string. So we will have to start with a reasonably large preallocated
  // buffer and then loop through WinUsb_GetDescriptor calls, doubling up
  // string buffer size every time ERROR_INSUFFICIENT_BUFFER is returned.
  union {
    // Preallocate reasonably sized buffer on the stack.
    char small_buffer[64];
    USB_STRING_DESCRIPTOR initial_ser_num;
  };
  USB_STRING_DESCRIPTOR* ser_num = &initial_ser_num;
  // Buffer byte size
  unsigned long ser_num_size = sizeof(small_buffer);
  // After successful call to WinUsb_GetDescriptor will contain serial
  // number descriptor size.
  unsigned long bytes_written;
  while (!WinUsb_GetDescriptor(winusb_handle(), USB_STRING_DESCRIPTOR_TYPE,
                               usb_device_descriptor_.iSerialNumber,
                               0x0409, // English (US)
                               reinterpret_cast<PUCHAR>(ser_num),
                               ser_num_size, &bytes_written)) {
    // Any error other than ERROR_INSUFFICIENT_BUFFER is terminal here.
    if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) {
      if (ser_num != &initial_ser_num)
        delete[] reinterpret_cast<char*>(ser_num);
      return false;
    }

    // Double up buffer size and reallocate string buffer
    ser_num_size *= 2;
    if (ser_num != &initial_ser_num)
      delete[] reinterpret_cast<char*>(ser_num);
    try {
      ser_num =
          reinterpret_cast<USB_STRING_DESCRIPTOR*>(new char[ser_num_size]);
    } catch (...) {
      SetLastError(ERROR_OUTOFMEMORY);
      return false;
    }
  }

  // Serial number string length
  unsigned long str_len = (ser_num->bLength -
                           FIELD_OFFSET(USB_STRING_DESCRIPTOR, bString)) /
                          sizeof(wchar_t);

  // Lets see if requested buffer is big enough to fit the string
  if ((NULL == buffer) || (*buffer_char_size < (str_len + 1))) {
    // Requested buffer is too small.
    if (ser_num != &initial_ser_num)
      delete[] reinterpret_cast<char*>(ser_num);
    *buffer_char_size = str_len + 1;
    SetLastError(ERROR_INSUFFICIENT_BUFFER);
    return false;
  }

  bool ret = true;
  if (ansi) {
    // We need to convert name from wide char to ansi string
    if (0 != WideCharToMultiByte(CP_ACP, 0, ser_num->bString,
                                 static_cast<int>(str_len),
                                 reinterpret_cast<PSTR>(buffer),
                                 static_cast<int>(*buffer_char_size),
                                 NULL, NULL)) {
      // Zero-terminate output string.
      reinterpret_cast<char*>(buffer)[str_len] = '\0';
    } else {
      ret = false;
    }
  } else {
    // For wide char output just copy string buffer,
    // and zero-terminate output string.
    CopyMemory(buffer, ser_num->bString, bytes_written);
    reinterpret_cast<wchar_t*>(buffer)[str_len] = L'\0';
  }

  if (ser_num != &initial_ser_num)
    delete[] reinterpret_cast<char*>(ser_num);

  return ret;
}