diff options
Diffstat (limited to 'host/windows/usb/api/adb_legacy_interface.cpp')
| -rwxr-xr-x | host/windows/usb/api/adb_legacy_interface.cpp | 290 |
1 files changed, 275 insertions, 15 deletions
diff --git a/host/windows/usb/api/adb_legacy_interface.cpp b/host/windows/usb/api/adb_legacy_interface.cpp index 95c750e69..9eab9bd56 100755 --- a/host/windows/usb/api/adb_legacy_interface.cpp +++ b/host/windows/usb/api/adb_legacy_interface.cpp @@ -17,48 +17,308 @@ /** \file
This file consists of implementation of class AdbLegacyInterfaceObject
that encapsulates an interface on our USB device that is accessible
- via WinUsb API.
*/
#include "stdafx.h"
+#include "adb_api_legacy.h"
#include "adb_legacy_interface.h"
-#include "adb_endpoint_object.h"
+#include "adb_legacy_endpoint_object.h"
AdbLegacyInterfaceObject::AdbLegacyInterfaceObject(const wchar_t* interf_name)
- : AdbInterfaceObject(interf_name) {
+ : AdbInterfaceObject(interf_name),
+ def_read_endpoint_(0xFF),
+ read_endpoint_id_(0xFF),
+ def_write_endpoint_(0xFF),
+ write_endpoint_id_(0xFF) {
}
AdbLegacyInterfaceObject::~AdbLegacyInterfaceObject() {
}
ADBAPIHANDLE AdbLegacyInterfaceObject::CreateHandle() {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return NULL;
-}
+ // 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;
+ }
-bool AdbLegacyInterfaceObject::CloseHandle() {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- 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
+ AdbEndpointInformation pipe_info;
+ if (!GetEndpointInformation(endpoint, &pipe_info)) {
+ return false;
+ }
+
+ if (AdbEndpointTypeBulk == 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 AdbObjectHandle::CreateHandle();
}
bool AdbLegacyInterfaceObject::GetSerialNumber(void* buffer,
unsigned long* buffer_char_size,
bool ansi) {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return false;
+ 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 AdbLegacyInterfaceObject::GetEndpointInformation(
UCHAR endpoint_index,
AdbEndpointInformation* info) {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- 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 AdbLegacyInterfaceObject::OpenEndpoint(
UCHAR endpoint_index,
AdbOpenAccessType access_type,
AdbOpenSharingMode sharing_mode) {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return NULL;
+ // Convert index into name and ID.
+ std::wstring endpoint_name;
+ UCHAR endpoint_id;
+
+ try {
+ if ((ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index) ||
+ (def_read_endpoint_ == endpoint_index)) {
+ endpoint_name = DEVICE_BULK_READ_PIPE_NAME;
+ 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_name = DEVICE_BULK_WRITE_PIPE_NAME;
+ endpoint_id = write_endpoint_id_;
+ endpoint_index = def_write_endpoint_;
+ } else {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+ } catch (...) {
+ // We don't expect exceptions other than OOM thrown here.
+ SetLastError(ERROR_OUTOFMEMORY);
+ return NULL;
+ }
+
+ return OpenEndpoint(endpoint_name.c_str(), endpoint_id, endpoint_index,
+ access_type, sharing_mode);
+}
+
+ADBAPIHANDLE AdbLegacyInterfaceObject::OpenEndpoint(
+ const wchar_t* endpoint_name,
+ UCHAR endpoint_id,
+ UCHAR endpoint_index,
+ AdbOpenAccessType access_type,
+ AdbOpenSharingMode sharing_mode) {
+ if (!IsOpened()) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ AdbLegacyEndpointObject* adb_endpoint = NULL;
+
+ try {
+ adb_endpoint =
+ new AdbLegacyEndpointObject(this, endpoint_id, endpoint_index);
+ } catch (...) {
+ // We don't expect exceptions other than OOM thrown here.
+ 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 AdbLegacyInterfaceObject::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 AdbLegacyInterfaceObject::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 AdbLegacyInterfaceObject::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;
}
|
