Refactor ADB API dll to support WinUsb
diff --git a/host/windows/usb/api/adb_interface.cpp b/host/windows/usb/api/adb_interface.cpp
index 9369e13..9b073a4 100644
--- a/host/windows/usb/api/adb_interface.cpp
+++ b/host/windows/usb/api/adb_interface.cpp
@@ -1,344 +1,413 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** \file
- This file consists of implementation of class AdbInterfaceObject that
- encapsulates an interface on our USB device.
-*/
-
-#include "stdafx.h"
-#include "adb_interface.h"
-#include "adb_endpoint_object.h"
-
-AdbInterfaceObject::AdbInterfaceObject(const wchar_t* interf_name)
- : AdbObjectHandle(AdbObjectTypeInterface),
- interface_name_(interf_name) {
- ATLASSERT(NULL != interf_name);
-}
-
-AdbInterfaceObject::~AdbInterfaceObject() {
-}
-
-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();
-}
-
-bool AdbInterfaceObject::GetInterfaceName(void* buffer,
- unsigned long* buffer_char_size,
- bool ansi) {
- // Lets see if buffer is big enough
- ULONG name_len = static_cast<ULONG>(interface_name_.length() + 1);
- if ((NULL == buffer) || (*buffer_char_size < name_len)) {
- *buffer_char_size = name_len;
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return false;
- }
-
- if (!ansi) {
- // If user asked for wide char name just return it
- wcscpy(reinterpret_cast<wchar_t*>(buffer), interface_name().c_str());
- return true;
- }
-
- // We need to convert name from wide char to ansi string
- int res = WideCharToMultiByte(CP_ACP,
- 0,
- interface_name().c_str(),
- static_cast<int>(name_len),
- reinterpret_cast<PSTR>(buffer),
- static_cast<int>(*buffer_char_size),
- NULL,
- NULL);
- return (res != 0);
-}
-
-bool AdbInterfaceObject::GetSerialNumber(void* buffer,
- unsigned long* buffer_char_size,
- bool ansi) {
- if (!IsOpened()) {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- // Open USB device for this intefface
- HANDLE usb_device_handle = CreateFile(interface_name().c_str(),
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- if (INVALID_HANDLE_VALUE == usb_device_handle)
- return NULL;
-
- WCHAR serial_number[512];
-
- // Send IOCTL
- DWORD ret_bytes = 0;
- BOOL ret = DeviceIoControl(usb_device_handle,
- ADB_IOCTL_GET_SERIAL_NUMBER,
- NULL, 0,
- serial_number, sizeof(serial_number),
- &ret_bytes,
- NULL);
-
- // Preserve error accross CloseHandle
- ULONG error = ret ? NO_ERROR : GetLastError();
-
- ::CloseHandle(usb_device_handle);
-
- if (NO_ERROR != error) {
- SetLastError(error);
- return false;
- }
-
- unsigned long str_len =
- static_cast<unsigned long>(wcslen(serial_number) + 1);
-
- if ((NULL == buffer) || (*buffer_char_size < str_len)) {
- *buffer_char_size = str_len;
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return false;
- }
-
- if (!ansi) {
- // If user asked for wide char name just return it
- wcscpy(reinterpret_cast<wchar_t*>(buffer), serial_number);
- return true;
- }
-
- // We need to convert name from wide char to ansi string
- int res = WideCharToMultiByte(CP_ACP,
- 0,
- serial_number,
- static_cast<int>(str_len),
- reinterpret_cast<PSTR>(buffer),
- static_cast<int>(*buffer_char_size),
- NULL,
- NULL);
- return (res != 0);
-}
-
-bool AdbInterfaceObject::GetUsbDeviceDescriptor(USB_DEVICE_DESCRIPTOR* desc) {
- if (!IsOpened()) {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- CopyMemory(desc, usb_device_descriptor(), sizeof(USB_DEVICE_DESCRIPTOR));
-
- return true;
-}
-
-bool AdbInterfaceObject::GetUsbConfigurationDescriptor(
- USB_CONFIGURATION_DESCRIPTOR* desc) {
- if (!IsOpened()) {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- CopyMemory(desc, usb_config_descriptor(),
- sizeof(USB_CONFIGURATION_DESCRIPTOR));
-
- return true;
-}
-
-bool AdbInterfaceObject::GetUsbInterfaceDescriptor(
- USB_INTERFACE_DESCRIPTOR* desc) {
- if (!IsOpened()) {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- CopyMemory(desc, usb_interface_descriptor(), sizeof(USB_INTERFACE_DESCRIPTOR));
-
- return true;
-}
-
-bool AdbInterfaceObject::GetEndpointInformation(UCHAR endpoint_index,
- AdbEndpointInformation* info) {
- if (!IsOpened()) {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- // Open USB device for this intefface
- HANDLE usb_device_handle = CreateFile(interface_name().c_str(),
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- if (INVALID_HANDLE_VALUE == usb_device_handle)
- return NULL;
-
- // Init ICTL param
- AdbQueryEndpointInformation param;
- param.endpoint_index = endpoint_index;
-
- // Send IOCTL
- DWORD ret_bytes = 0;
- BOOL ret = DeviceIoControl(usb_device_handle,
- ADB_IOCTL_GET_ENDPOINT_INFORMATION,
- ¶m, sizeof(param),
- info, sizeof(AdbEndpointInformation),
- &ret_bytes,
- NULL);
- ATLASSERT(!ret || (sizeof(AdbEndpointInformation) == ret_bytes));
-
- // Preserve error accross CloseHandle
- ULONG error = ret ? NO_ERROR : GetLastError();
-
- ::CloseHandle(usb_device_handle);
-
- if (NO_ERROR != error)
- SetLastError(error);
-
- return ret ? true : false;
-}
-
-ADBAPIHANDLE AdbInterfaceObject::OpenEndpoint(
- UCHAR endpoint_index,
- AdbOpenAccessType access_type,
- AdbOpenSharingMode sharing_mode) {
- // Convert index into name
- std::wstring endpoint_name;
-
- try {
- if (ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index) {
- endpoint_name = DEVICE_BULK_READ_PIPE_NAME;
- } else if (ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX == endpoint_index) {
- endpoint_name = DEVICE_BULK_WRITE_PIPE_NAME;
- } else {
- wchar_t fmt[265];
- swprintf(fmt, L"%ws%u", DEVICE_PIPE_NAME_PREFIX, endpoint_index);
- endpoint_name = fmt;
- }
- } catch (...) {
- SetLastError(ERROR_OUTOFMEMORY);
- return NULL;
- }
-
- return OpenEndpoint(endpoint_name.c_str(), access_type, sharing_mode);
-}
-
-ADBAPIHANDLE AdbInterfaceObject::OpenEndpoint(
- const wchar_t* endpoint_name,
- AdbOpenAccessType access_type,
- AdbOpenSharingMode sharing_mode) {
- if (!IsOpened()) {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- AdbEndpointObject* adb_endpoint = NULL;
-
- try {
- adb_endpoint = new AdbEndpointObject(this);
- } catch (...) {
- SetLastError(ERROR_OUTOFMEMORY);
- return NULL;
- }
-
- // Build full path to the object
- std::wstring endpoint_path = interface_name();
- endpoint_path += L"\\";
- endpoint_path += endpoint_name;
-
- ADBAPIHANDLE ret = adb_endpoint->CreateHandle(endpoint_path.c_str(),
- access_type,
- sharing_mode);
-
- adb_endpoint->Release();
-
- return ret;
-}
-
-bool AdbInterfaceObject::CacheUsbDeviceDescriptor(HANDLE usb_device_handle) {
- DWORD ret_bytes = 0;
- BOOL ret = DeviceIoControl(usb_device_handle,
- ADB_IOCTL_GET_USB_DEVICE_DESCRIPTOR,
- NULL, 0,
- &usb_device_descriptor_,
- sizeof(usb_device_descriptor_),
- &ret_bytes,
- NULL);
- ATLASSERT(!ret || (sizeof(USB_DEVICE_DESCRIPTOR) == ret_bytes));
-
- return ret ? true : false;
-}
-
-bool AdbInterfaceObject::CacheUsbConfigurationDescriptor(
- HANDLE usb_device_handle) {
- DWORD ret_bytes = 0;
- BOOL ret = DeviceIoControl(usb_device_handle,
- ADB_IOCTL_GET_USB_CONFIGURATION_DESCRIPTOR,
- NULL, 0,
- &usb_config_descriptor_,
- sizeof(usb_config_descriptor_),
- &ret_bytes,
- NULL);
- ATLASSERT(!ret || (sizeof(USB_CONFIGURATION_DESCRIPTOR) == ret_bytes));
-
- return ret ? true : false;
-}
-
-bool AdbInterfaceObject::CacheUsbInterfaceDescriptor(
- HANDLE usb_device_handle) {
- DWORD ret_bytes = 0;
- BOOL ret = DeviceIoControl(usb_device_handle,
- ADB_IOCTL_GET_USB_INTERFACE_DESCRIPTOR,
- NULL, 0,
- &usb_interface_descriptor_,
- sizeof(usb_interface_descriptor_),
- &ret_bytes,
- NULL);
- ATLASSERT(!ret || (sizeof(USB_INTERFACE_DESCRIPTOR) == ret_bytes));
-
- return ret ? true : false;
-}
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** \file
+ This file consists of implementation of class AdbInterfaceObject that
+ encapsulates an interface on our USB device.
+*/
+
+#include "stdafx.h"
+#include "adb_interface.h"
+#include "adb_endpoint_object.h"
+
+AdbInterfaceObject::AdbInterfaceObject(const wchar_t* interf_name)
+ : AdbObjectHandle(AdbObjectTypeInterface),
+ interface_name_(interf_name),
+ usb_device_handle_(INVALID_HANDLE_VALUE),
+ winusb_handle_(NULL),
+ interface_number_(0xFF),
+ def_read_endpoint_(0xFF),
+ read_endpoint_id_(0xFF),
+ def_write_endpoint_(0xFF),
+ write_endpoint_id_(0xFF) {
+ ATLASSERT(NULL != interf_name);
+}
+
+AdbInterfaceObject::~AdbInterfaceObject() {
+ ATLASSERT(NULL == winusb_handle_);
+ ATLASSERT(INVALID_HANDLE_VALUE == usb_device_handle_);
+}
+
+ADBAPIHANDLE AdbInterfaceObject::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 AdbObjectHandle::CreateHandle();
+}
+
+bool AdbInterfaceObject::CloseHandle() {
+ if (NULL != winusb_handle_) {
+ WinUsb_Free(winusb_handle_);
+ winusb_handle_ = NULL;
+ }
+ if (INVALID_HANDLE_VALUE != usb_device_handle_) {
+ ::CloseHandle(usb_device_handle_);
+ usb_device_handle_ = INVALID_HANDLE_VALUE;
+ }
+
+ return AdbObjectHandle::CloseHandle();
+}
+
+bool AdbInterfaceObject::GetInterfaceName(void* buffer,
+ unsigned long* buffer_char_size,
+ bool ansi) {
+ if (NULL == buffer_char_size) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ // Lets see if buffer is big enough
+ ULONG name_len = static_cast<ULONG>(interface_name_.length() + 1);
+ if ((NULL == buffer) || (*buffer_char_size < name_len)) {
+ *buffer_char_size = name_len;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return false;
+ }
+
+ if (!ansi) {
+ // If user asked for wide char name just return it
+ wcscpy(reinterpret_cast<wchar_t*>(buffer), interface_name().c_str());
+ return true;
+ }
+
+ // We need to convert name from wide char to ansi string
+ int res = WideCharToMultiByte(CP_ACP,
+ 0,
+ interface_name().c_str(),
+ static_cast<int>(name_len),
+ reinterpret_cast<PSTR>(buffer),
+ static_cast<int>(*buffer_char_size),
+ NULL,
+ NULL);
+ return (res != 0);
+}
+
+bool AdbInterfaceObject::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;
+}
+
+bool AdbInterfaceObject::GetUsbDeviceDescriptor(USB_DEVICE_DESCRIPTOR* desc) {
+ if (!IsOpened()) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ if (NULL == desc) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ CopyMemory(desc, usb_device_descriptor(), sizeof(USB_DEVICE_DESCRIPTOR));
+
+ return true;
+}
+
+bool AdbInterfaceObject::GetUsbConfigurationDescriptor(
+ USB_CONFIGURATION_DESCRIPTOR* desc) {
+ if (!IsOpened()) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ if (NULL == desc) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ CopyMemory(desc, usb_config_descriptor(),
+ sizeof(USB_CONFIGURATION_DESCRIPTOR));
+
+ return true;
+}
+
+bool AdbInterfaceObject::GetUsbInterfaceDescriptor(
+ USB_INTERFACE_DESCRIPTOR* desc) {
+ if (!IsOpened()) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ if (NULL == desc) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ CopyMemory(desc, usb_interface_descriptor(), sizeof(USB_INTERFACE_DESCRIPTOR));
+
+ return true;
+}
+
+bool AdbInterfaceObject::GetEndpointInformation(UCHAR endpoint_index,
+ AdbEndpointInformation* info) {
+ if (!IsOpened()) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ if (NULL == info) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ // Get actual endpoint index for predefined read / write endpoints.
+ if (ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index) {
+ endpoint_index = def_read_endpoint_;
+ } else if (ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX == endpoint_index) {
+ endpoint_index = def_write_endpoint_;
+ }
+
+ // Query endpoint information
+ WINUSB_PIPE_INFORMATION pipe_info;
+ if (!WinUsb_QueryPipe(winusb_handle(), interface_number(), endpoint_index,
+ &pipe_info)) {
+ return false;
+ }
+
+ // Save endpoint information into output.
+ info->max_packet_size = pipe_info.MaximumPacketSize;
+ info->max_transfer_size = 0xFFFFFFFF;
+ info->endpoint_address = pipe_info.PipeId;
+ info->polling_interval = pipe_info.Interval;
+ info->setting_index = interface_number();
+ switch (pipe_info.PipeType) {
+ case UsbdPipeTypeControl:
+ info->endpoint_type = AdbEndpointTypeControl;
+ break;
+
+ case UsbdPipeTypeIsochronous:
+ info->endpoint_type = AdbEndpointTypeIsochronous;
+ break;
+
+ case UsbdPipeTypeBulk:
+ info->endpoint_type = AdbEndpointTypeBulk;
+ break;
+
+ case UsbdPipeTypeInterrupt:
+ info->endpoint_type = AdbEndpointTypeInterrupt;
+ break;
+
+ default:
+ info->endpoint_type = AdbEndpointTypeInvalid;
+ break;
+ }
+
+ return true;
+}
+
+ADBAPIHANDLE AdbInterfaceObject::OpenEndpoint(
+ UCHAR endpoint_index,
+ AdbOpenAccessType access_type,
+ AdbOpenSharingMode sharing_mode) {
+ // Convert index into id
+ UCHAR endpoint_id;
+
+ if ((ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index) ||
+ (def_read_endpoint_ == endpoint_index)) {
+ endpoint_id = read_endpoint_id_;
+ endpoint_index = def_read_endpoint_;
+ } else if ((ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX == endpoint_index) ||
+ (def_write_endpoint_ == endpoint_index)) {
+ endpoint_id = write_endpoint_id_;
+ endpoint_index = def_write_endpoint_;
+ } else {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ return OpenEndpoint(endpoint_id, endpoint_index);
+}
+
+ADBAPIHANDLE AdbInterfaceObject::OpenEndpoint(UCHAR endpoint_id,
+ UCHAR endpoint_index) {
+ if (!IsOpened()) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ AdbEndpointObject* adb_endpoint = NULL;
+
+ try {
+ adb_endpoint = new AdbEndpointObject(this, endpoint_id, endpoint_index);
+ } catch (...) {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return NULL;
+ }
+
+ ADBAPIHANDLE ret = adb_endpoint->CreateHandle();
+
+ adb_endpoint->Release();
+
+ return ret;
+}