ADBAPIHANDLE AdbInterfaceObject::CreateHandle() {
  // Open USB device for this intefface
  HANDLE usb_device_handle = CreateFile(interface_name().c_str(),
                                        GENERIC_READ | GENERIC_WRITE,
                                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                                        NULL,
                                        OPEN_EXISTING,
                                        0,
                                        NULL);
  if (INVALID_HANDLE_VALUE == usb_device_handle)
    return NULL;

  // Now, we ensured that our usb device / interface is up and running.
  // Lets collect device, interface and pipe information
  bool ok = true;
  if (!CacheUsbDeviceDescriptor(usb_device_handle) ||
      !CacheUsbConfigurationDescriptor(usb_device_handle) ||
      !CacheUsbInterfaceDescriptor(usb_device_handle)) {
    ok = false;
  }

  // Preserve error accross handle close
  ULONG error = ok ? NO_ERROR : GetLastError();

  ::CloseHandle(usb_device_handle);

  if (NO_ERROR != error)
    SetLastError(error);

  if (!ok)
    return false;

  return AdbObjectHandle::CreateHandle();
}
SDBAPIHANDLE SdbLegacyInterfaceObject::CreateHandle() {
  // Open USB device for this intefface
  HANDLE usb_device_handle = CreateFile(interface_name().c_str(),
                                        GENERIC_READ | GENERIC_WRITE,
                                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                                        NULL,
                                        OPEN_EXISTING,
                                        0,
                                        NULL);
  if (INVALID_HANDLE_VALUE == usb_device_handle) {
    return NULL;
  }

  // Now, we ensured that our usb device / interface is up and running.
  // Lets collect device, interface and pipe information
  bool ok = true;
  if (!CacheUsbDeviceDescriptor(usb_device_handle) ||
      !CacheUsbConfigurationDescriptor(usb_device_handle) ||
      !CacheUsbInterfaceDescriptor(usb_device_handle)) {
    ok = false;
  }

  // Preserve error accross handle close
  ULONG error = ok ? NO_ERROR : GetLastError();

  ::CloseHandle(usb_device_handle);

  if (NO_ERROR != error) {
    SetLastError(error);
  }

  if (!ok) {
    return false;
  }

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

    if (SdbEndpointTypeBulk == pipe_info.endpoint_type) {
      // This is a bulk endpoint. Cache its index and ID.
      if (0 != (pipe_info.endpoint_address & 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.endpoint_address;
      } else {
        // Use this endpoint as default bulk write endpoint
        ATLASSERT(0xFF == def_write_endpoint_);
        def_write_endpoint_ = endpoint;
        write_endpoint_id_ = pipe_info.endpoint_address;
      }
    }
  }

  return SdbObjectHandle::CreateHandle();
}