diff options
Diffstat (limited to 'host/windows/usb/api/adb_interface.cpp')
| -rw-r--r-- | host/windows/usb/api/adb_interface.cpp | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/host/windows/usb/api/adb_interface.cpp b/host/windows/usb/api/adb_interface.cpp new file mode 100644 index 000000000..9369e13e9 --- /dev/null +++ b/host/windows/usb/api/adb_interface.cpp @@ -0,0 +1,344 @@ +/* + * 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; +} |
