Refactor ADB API dll to support WinUsb
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user