Add classes encapsulatinglegacy USB API
Added implementation for endpoints and overlapped I/O support for legacy API support.
This commit is contained in:
@@ -88,6 +88,7 @@ PRECOMPILED_SOURCEFILE = stdafx.cpp
|
||||
SOURCES = adb_api.cpp \
|
||||
adb_endpoint_object.cpp \
|
||||
adb_winusb_endpoint_object.cpp \
|
||||
adb_legacy_endpoint_object.cpp \
|
||||
adb_helper_routines.cpp \
|
||||
adb_interface.cpp \
|
||||
adb_winusb_interface.cpp \
|
||||
@@ -95,6 +96,7 @@ SOURCES = adb_api.cpp \
|
||||
adb_interface_enum.cpp \
|
||||
adb_io_completion.cpp \
|
||||
adb_winusb_io_completion.cpp \
|
||||
adb_legacy_io_completion.cpp \
|
||||
adb_object_handle.cpp \
|
||||
AdbWinApi.cpp \
|
||||
AdbWinApi.rc
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
* Copyright (C) 2009 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.
|
||||
@@ -25,6 +25,61 @@
|
||||
#include "adb_helper_routines.h"
|
||||
#include "adb_interface_enum.h"
|
||||
|
||||
bool GetSDKComplientParam(AdbOpenAccessType access_type,
|
||||
AdbOpenSharingMode sharing_mode,
|
||||
ULONG* desired_access,
|
||||
ULONG* desired_sharing) {
|
||||
if (NULL != desired_access) {
|
||||
switch (access_type) {
|
||||
case AdbOpenAccessTypeReadWrite:
|
||||
*desired_access = GENERIC_READ | GENERIC_WRITE;
|
||||
break;
|
||||
|
||||
case AdbOpenAccessTypeRead:
|
||||
*desired_access = GENERIC_READ;
|
||||
break;
|
||||
|
||||
case AdbOpenAccessTypeWrite:
|
||||
*desired_access = GENERIC_WRITE;
|
||||
break;
|
||||
|
||||
case AdbOpenAccessTypeQueryInfo:
|
||||
*desired_access = FILE_READ_ATTRIBUTES | FILE_READ_EA;
|
||||
break;
|
||||
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_ACCESS);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != desired_sharing) {
|
||||
switch (sharing_mode) {
|
||||
case AdbOpenSharingModeReadWrite:
|
||||
*desired_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
|
||||
break;
|
||||
|
||||
case AdbOpenSharingModeRead:
|
||||
*desired_sharing = FILE_SHARE_READ;
|
||||
break;
|
||||
|
||||
case AdbOpenSharingModeWrite:
|
||||
*desired_sharing = FILE_SHARE_WRITE;
|
||||
break;
|
||||
|
||||
case AdbOpenSharingModeExclusive:
|
||||
*desired_sharing = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EnumerateDeviceInterfaces(HDEVINFO hardware_dev_info,
|
||||
GUID class_id,
|
||||
bool exclude_removed,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
* Copyright (C) 2009 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.
|
||||
@@ -23,6 +23,23 @@
|
||||
|
||||
#include "adb_api_private_defines.h"
|
||||
|
||||
/** \brief Converts access type and share mode from our enum into
|
||||
SDK - complient values.
|
||||
|
||||
@param[in] access_type Enumerated access type
|
||||
@param[in] sharing_mode Enumerated share mode
|
||||
@param[out] desired_access Will receive SDK - complient desired access
|
||||
flags. This parameter can be NULL.
|
||||
@param[out] desired_sharing Will receive SDK - complient share mode.
|
||||
This parameter can be NULL.
|
||||
@return True on success, false on failure, in which case GetLastError()
|
||||
provides extended information about the error that occurred.
|
||||
*/
|
||||
bool GetSDKComplientParam(AdbOpenAccessType access_type,
|
||||
AdbOpenSharingMode sharing_mode,
|
||||
ULONG* desired_access,
|
||||
ULONG* desired_sharing);
|
||||
|
||||
/** \brief Given the hardware device information enumerates interfaces for
|
||||
this device.
|
||||
|
||||
|
||||
237
host/windows/usb/api/adb_legacy_endpoint_object.cpp
Executable file
237
host/windows/usb/api/adb_legacy_endpoint_object.cpp
Executable file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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 AdbLegacyEndpointObject that
|
||||
encapsulates a handle opened to an endpoint on our device controlled by
|
||||
a custom (legacy) USB driver.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "adb_api_legacy.h"
|
||||
#include "adb_legacy_endpoint_object.h"
|
||||
#include "adb_legacy_io_completion.h"
|
||||
#include "adb_helper_routines.h"
|
||||
|
||||
AdbLegacyEndpointObject::AdbLegacyEndpointObject(
|
||||
AdbLegacyInterfaceObject* parent_interf,
|
||||
UCHAR endpoint_id,
|
||||
UCHAR endpoint_index)
|
||||
: AdbEndpointObject(parent_interf, endpoint_id, endpoint_index),
|
||||
usb_handle_(INVALID_HANDLE_VALUE) {
|
||||
}
|
||||
|
||||
AdbLegacyEndpointObject::~AdbLegacyEndpointObject() {
|
||||
if (INVALID_HANDLE_VALUE != usb_handle_) {
|
||||
::CloseHandle(usb_handle_);
|
||||
}
|
||||
}
|
||||
|
||||
ADBAPIHANDLE AdbLegacyEndpointObject::CommonAsyncReadWrite(
|
||||
bool is_read,
|
||||
void* buffer,
|
||||
ULONG bytes_to_transfer,
|
||||
ULONG* bytes_transferred,
|
||||
HANDLE event_handle,
|
||||
ULONG time_out) {
|
||||
if (NULL != bytes_transferred) {
|
||||
*bytes_transferred = 0;
|
||||
}
|
||||
|
||||
if (!IsOpened()) {
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_ioctl_write = is_read ? false : (0 != time_out);
|
||||
|
||||
// Create completion i/o object
|
||||
AdbLegacyIOCompletion* adb_io_completion = NULL;
|
||||
|
||||
try {
|
||||
adb_io_completion = new AdbLegacyIOCompletion(this,
|
||||
bytes_to_transfer,
|
||||
event_handle,
|
||||
is_ioctl_write);
|
||||
} catch (... ) {
|
||||
// We don't expect exceptions other than OOM thrown here.
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create a handle for it
|
||||
ADBAPIHANDLE ret = adb_io_completion->CreateHandle();
|
||||
ULONG transferred = 0;
|
||||
if (NULL != ret) {
|
||||
BOOL res = TRUE;
|
||||
if (0 == time_out) {
|
||||
// Go the read / write file way
|
||||
res = is_read ? ReadFile(usb_handle(),
|
||||
buffer,
|
||||
bytes_to_transfer,
|
||||
&transferred,
|
||||
adb_io_completion->overlapped()) :
|
||||
WriteFile(usb_handle(),
|
||||
buffer,
|
||||
bytes_to_transfer,
|
||||
&transferred,
|
||||
adb_io_completion->overlapped());
|
||||
} else {
|
||||
// Go IOCTL way
|
||||
AdbBulkTransfer transfer_param;
|
||||
transfer_param.time_out = time_out;
|
||||
transfer_param.transfer_size = is_read ? 0 : bytes_to_transfer;
|
||||
transfer_param.SetWriteBuffer(is_read ? NULL : buffer);
|
||||
|
||||
res = DeviceIoControl(usb_handle(),
|
||||
is_read ? ADB_IOCTL_BULK_READ : ADB_IOCTL_BULK_WRITE,
|
||||
&transfer_param, sizeof(transfer_param),
|
||||
is_read ? buffer : adb_io_completion->transferred_bytes_ptr(),
|
||||
is_read ? bytes_to_transfer : sizeof(ULONG),
|
||||
&transferred,
|
||||
adb_io_completion->overlapped());
|
||||
}
|
||||
|
||||
if (NULL != bytes_transferred) {
|
||||
*bytes_transferred = transferred;
|
||||
}
|
||||
|
||||
ULONG error = GetLastError();
|
||||
if (!res && (ERROR_IO_PENDING != error)) {
|
||||
// I/O failed immediatelly. We need to close i/o completion object
|
||||
// before we return NULL to the caller.
|
||||
adb_io_completion->CloseHandle();
|
||||
ret = NULL;
|
||||
SetLastError(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Offseting 'new'
|
||||
adb_io_completion->Release();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AdbLegacyEndpointObject::CommonSyncReadWrite(bool is_read,
|
||||
void* buffer,
|
||||
ULONG bytes_to_transfer,
|
||||
ULONG* bytes_transferred,
|
||||
ULONG time_out) {
|
||||
if (NULL != bytes_transferred) {
|
||||
*bytes_transferred = 0;
|
||||
}
|
||||
|
||||
if (!IsOpened()) {
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_ioctl_write = is_read ? false : (0 != time_out);
|
||||
|
||||
// This is synchronous I/O. Since we always open I/O items for
|
||||
// overlapped I/O we're obligated to always provide OVERLAPPED
|
||||
// structure to read / write routines. Prepare it now.
|
||||
OVERLAPPED overlapped;
|
||||
ZeroMemory(&overlapped, sizeof(overlapped));
|
||||
|
||||
BOOL ret = TRUE;
|
||||
ULONG ioctl_write_transferred = 0;
|
||||
if (0 == time_out) {
|
||||
// Go the read / write file way
|
||||
ret = is_read ?
|
||||
ReadFile(usb_handle(), buffer, bytes_to_transfer, bytes_transferred, &overlapped) :
|
||||
WriteFile(usb_handle(), buffer, bytes_to_transfer, bytes_transferred, &overlapped);
|
||||
} else {
|
||||
// Go IOCTL way
|
||||
AdbBulkTransfer transfer_param;
|
||||
transfer_param.time_out = time_out;
|
||||
transfer_param.transfer_size = is_read ? 0 : bytes_to_transfer;
|
||||
transfer_param.SetWriteBuffer(is_read ? NULL : buffer);
|
||||
|
||||
ULONG tmp;
|
||||
ret = DeviceIoControl(usb_handle(),
|
||||
is_read ? ADB_IOCTL_BULK_READ : ADB_IOCTL_BULK_WRITE,
|
||||
&transfer_param, sizeof(transfer_param),
|
||||
is_read ? buffer : &ioctl_write_transferred,
|
||||
is_read ? bytes_to_transfer : sizeof(ULONG),
|
||||
&tmp,
|
||||
&overlapped);
|
||||
}
|
||||
|
||||
// Lets see the result
|
||||
if (!ret && (ERROR_IO_PENDING != GetLastError())) {
|
||||
// I/O failed.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lets wait till I/O completes
|
||||
ULONG transferred = 0;
|
||||
ret = GetOverlappedResult(usb_handle(), &overlapped, &transferred, TRUE);
|
||||
if (ret && (NULL != bytes_transferred)) {
|
||||
*bytes_transferred = is_ioctl_write ? ioctl_write_transferred :
|
||||
transferred;
|
||||
}
|
||||
|
||||
return ret ? true : false;
|
||||
}
|
||||
|
||||
ADBAPIHANDLE AdbLegacyEndpointObject::CreateHandle(
|
||||
const wchar_t* item_path,
|
||||
AdbOpenAccessType access_type,
|
||||
AdbOpenSharingMode share_mode) {
|
||||
// Convert access / share parameters into CreateFile - compatible
|
||||
ULONG desired_access;
|
||||
ULONG desired_sharing;
|
||||
|
||||
if (!GetSDKComplientParam(access_type, share_mode,
|
||||
&desired_access, &desired_sharing)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Open USB handle
|
||||
usb_handle_ = CreateFile(item_path,
|
||||
desired_access,
|
||||
share_mode,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OVERLAPPED, // Always overlapped!
|
||||
NULL);
|
||||
if (INVALID_HANDLE_VALUE == usb_handle_) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create ADB handle
|
||||
ADBAPIHANDLE ret = AdbObjectHandle::CreateHandle();
|
||||
|
||||
if (NULL == ret) {
|
||||
// If creation of ADB handle failed we have to close USB handle too.
|
||||
ULONG error = GetLastError();
|
||||
::CloseHandle(usb_handle());
|
||||
usb_handle_ = INVALID_HANDLE_VALUE;
|
||||
SetLastError(error);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AdbLegacyEndpointObject::CloseHandle() {
|
||||
if (INVALID_HANDLE_VALUE != usb_handle_) {
|
||||
::CloseHandle(usb_handle_);
|
||||
usb_handle_ = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
return AdbEndpointObject::CloseHandle();
|
||||
}
|
||||
142
host/windows/usb/api/adb_legacy_endpoint_object.h
Executable file
142
host/windows/usb/api/adb_legacy_endpoint_object.h
Executable file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_API_ADB_LEGACY_ENDPOINT_OBJECT_H__
|
||||
#define ANDROID_USB_API_ADB_LEGACY_ENDPOINT_OBJECT_H__
|
||||
/** \file
|
||||
This file consists of declaration of class AdbLegacyEndpointObject that
|
||||
encapsulates a handle opened to an endpoint on our device controlled by
|
||||
a custom (legacy) USB driver.
|
||||
*/
|
||||
|
||||
#include "adb_endpoint_object.h"
|
||||
#include "adb_legacy_interface.h"
|
||||
|
||||
/** Encapsulates a handle opened to an endpoint on our device controlled by
|
||||
a custom (legacy) USB driver.
|
||||
*/
|
||||
class AdbLegacyEndpointObject : public AdbEndpointObject {
|
||||
public:
|
||||
/** \brief Constructs the object
|
||||
|
||||
@param[in] interface Parent legacy USB interface for this object.
|
||||
@param[in] endpoint_id Endpoint ID (endpoint address) on the device.
|
||||
@param[in] endpoint_index Zero-based endpoint index in the interface's
|
||||
array of endpoints.
|
||||
*/
|
||||
AdbLegacyEndpointObject(AdbLegacyInterfaceObject* parent_interf,
|
||||
UCHAR endpoint_id,
|
||||
UCHAR endpoint_index);
|
||||
|
||||
protected:
|
||||
/** \brief Destructs the object.
|
||||
|
||||
We hide destructor in order to prevent ourseves from accidentaly allocating
|
||||
instances on the stack. If such attemp occur, compiler will error.
|
||||
*/
|
||||
virtual ~AdbLegacyEndpointObject();
|
||||
|
||||
//
|
||||
// Abstract overrides
|
||||
//
|
||||
|
||||
protected:
|
||||
/** \brief Common code for async read / write
|
||||
|
||||
@param[in] is_read Read or write selector.
|
||||
@param[in,out] buffer Pointer to the buffer for read / write.
|
||||
@param[in] bytes_to_transfer Number of bytes to be read / written.
|
||||
@param[out] bytes_transferred Number of bytes read / written. Can be NULL.
|
||||
@param[in] event_handle Event handle that should be signaled when async I/O
|
||||
completes. Can be NULL. If it's not NULL this handle will be used to
|
||||
initialize OVERLAPPED structure for this I/O.
|
||||
@param[in] time_out A timeout (in milliseconds) required for this I/O to
|
||||
complete. Zero value in this parameter means that there is no
|
||||
timeout set for this I/O.
|
||||
@return A handle to IO completion object or NULL on failure. If NULL is
|
||||
returned GetLastError() provides extended error information.
|
||||
*/
|
||||
virtual ADBAPIHANDLE CommonAsyncReadWrite(bool is_read,
|
||||
void* buffer,
|
||||
ULONG bytes_to_transfer,
|
||||
ULONG* bytes_transferred,
|
||||
HANDLE event_handle,
|
||||
ULONG time_out);
|
||||
|
||||
/** \brief Common code for sync read / write
|
||||
|
||||
@param[in] is_read Read or write selector.
|
||||
@param[in,out] buffer Pointer to the buffer for read / write.
|
||||
@param[in] bytes_to_transfer Number of bytes to be read / written.
|
||||
@param[out] bytes_transferred Number of bytes read / written. Can be NULL.
|
||||
@param[in] time_out A timeout (in milliseconds) required for this I/O to
|
||||
complete. Zero value in this parameter means that there is no
|
||||
timeout set for this I/O.
|
||||
@return true on success, false on failure. If false is returned
|
||||
GetLastError() provides extended error information.
|
||||
*/
|
||||
virtual bool CommonSyncReadWrite(bool is_read,
|
||||
void* buffer,
|
||||
ULONG bytes_to_transfer,
|
||||
ULONG* bytes_transferred,
|
||||
ULONG time_out);
|
||||
|
||||
//
|
||||
// Operations
|
||||
//
|
||||
|
||||
public:
|
||||
/** \brief Opens endpoint and creates a handle to this object
|
||||
|
||||
@param item_path[in] Path to the endpoint on our USB device.
|
||||
@param access_type[in] Desired access type. In the current implementation
|
||||
this parameter has no effect on the way item is opened. It's
|
||||
always read / write access.
|
||||
@param sharing_mode[in] Desired share mode. In the current implementation
|
||||
this parameter has no effect on the way item is opened. It's
|
||||
always shared for read / write.
|
||||
@return A handle to this object on success or NULL on an error.
|
||||
If NULL is returned GetLastError() provides extended error
|
||||
information. ERROR_GEN_FAILURE is set if an attempt was
|
||||
made to create already opened object.
|
||||
*/
|
||||
virtual ADBAPIHANDLE CreateHandle(const wchar_t* item_path,
|
||||
AdbOpenAccessType access_type,
|
||||
AdbOpenSharingMode share_mode);
|
||||
|
||||
|
||||
/** \brief This method is called when handle to this object gets closed.
|
||||
|
||||
We override this method in order to close handle to the endpoint opened
|
||||
in CreateHandle method of this class.
|
||||
@return true on success or false if object is already closed. If
|
||||
false is returned GetLastError() provides extended error
|
||||
information.
|
||||
*/
|
||||
virtual bool CloseHandle();
|
||||
|
||||
public:
|
||||
/// Gets handle to the endpoint opened on our USB device.
|
||||
HANDLE usb_handle() const {
|
||||
return usb_handle_;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Handle to the endpoint opened on our USB device.
|
||||
HANDLE usb_handle_;
|
||||
};
|
||||
|
||||
#endif // ANDROID_USB_API_ADB_LEGACY_ENDPOINT_OBJECT_H__
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
bool AdbLegacyInterfaceObject::CloseHandle() {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return false;
|
||||
// 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 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;
|
||||
}
|
||||
|
||||
@@ -60,15 +60,6 @@ class AdbLegacyInterfaceObject : public AdbInterfaceObject {
|
||||
*/
|
||||
virtual ADBAPIHANDLE CreateHandle();
|
||||
|
||||
/** \brief This method is called when handle to this object gets closed.
|
||||
|
||||
In this call object is deleted from the AdbObjectHandleMap.
|
||||
@return true on success or false if object is already closed. If
|
||||
false is returned GetLastError() provides extended error
|
||||
information.
|
||||
*/
|
||||
virtual bool CloseHandle();
|
||||
|
||||
//
|
||||
// Abstract overrides
|
||||
//
|
||||
@@ -124,6 +115,76 @@ class AdbLegacyInterfaceObject : public AdbInterfaceObject {
|
||||
virtual ADBAPIHANDLE OpenEndpoint(UCHAR endpoint_index,
|
||||
AdbOpenAccessType access_type,
|
||||
AdbOpenSharingMode sharing_mode);
|
||||
|
||||
//
|
||||
// Internal operations
|
||||
//
|
||||
|
||||
protected:
|
||||
/** \brief Opens an endpoint on this interface.
|
||||
|
||||
@param[in] endpoint_name Endpoint file name.
|
||||
@param[in] endpoint_id Endpoint (pipe) address on the device.
|
||||
@param[in] endpoint_index Zero-based endpoint index.
|
||||
@param[in] access_type Desired access type. In the current implementation
|
||||
this parameter has no effect on the way endpoint is opened. It's
|
||||
always read / write access.
|
||||
@param[in] sharing_mode Desired share mode. In the current implementation
|
||||
this parameter has no effect on the way endpoint is opened. It's
|
||||
always shared for read / write.
|
||||
@return Handle to the opened endpoint object or NULL on failure.
|
||||
If NULL is returned GetLastError() provides extended information
|
||||
about the error that occurred.
|
||||
*/
|
||||
ADBAPIHANDLE OpenEndpoint(const wchar_t* endpoint_name,
|
||||
UCHAR endpoint_id,
|
||||
UCHAR endpoint_index,
|
||||
AdbOpenAccessType access_type,
|
||||
AdbOpenSharingMode sharing_mode);
|
||||
|
||||
/** \brief Caches device descriptor for the USB device associated with
|
||||
this interface.
|
||||
|
||||
This method is called from CreateHandle method to cache some interface
|
||||
information.
|
||||
@param[in] usb_device_handle Handle to USB device.
|
||||
@return 'true' on success, 'false' on failure. If 'false' is returned
|
||||
GetLastError() provides extended error information.
|
||||
*/
|
||||
bool CacheUsbDeviceDescriptor(HANDLE usb_device_handle);
|
||||
|
||||
/** \brief Caches descriptor for the selected USB device configuration.
|
||||
|
||||
This method is called from CreateHandle method to cache some interface
|
||||
information.
|
||||
@param[in] usb_device_handle Handle to USB device.
|
||||
@return 'true' on success, 'false' on failure. If 'false' is returned
|
||||
GetLastError() provides extended error information.
|
||||
*/
|
||||
bool CacheUsbConfigurationDescriptor(HANDLE usb_device_handle);
|
||||
|
||||
/** \brief Caches descriptor for this interface.
|
||||
|
||||
This method is called from CreateHandle method to cache some interface
|
||||
information.
|
||||
@param[in] usb_device_handle Handle to USB device.
|
||||
@return 'true' on success, 'false' on failure. If 'false' is returned
|
||||
GetLastError() provides extended error information.
|
||||
*/
|
||||
bool CacheUsbInterfaceDescriptor(HANDLE usb_device_handle);
|
||||
|
||||
protected:
|
||||
/// Index for the default bulk read endpoint
|
||||
UCHAR def_read_endpoint_;
|
||||
|
||||
/// ID for the default bulk read endpoint
|
||||
UCHAR read_endpoint_id_;
|
||||
|
||||
/// Index for the default bulk write endpoint
|
||||
UCHAR def_write_endpoint_;
|
||||
|
||||
/// ID for the default bulk write endpoint
|
||||
UCHAR write_endpoint_id_;
|
||||
};
|
||||
|
||||
#endif // ANDROID_USB_API_ADB_LEGACY_INTERFACE_H__
|
||||
|
||||
90
host/windows/usb/api/adb_legacy_io_completion.cpp
Executable file
90
host/windows/usb/api/adb_legacy_io_completion.cpp
Executable file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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 AdbLegacyIOCompletion that
|
||||
encapsulates a wrapper around OVERLAPPED Win32 structure returned from
|
||||
asynchronous I/O requests issued via legacy USB API.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "adb_legacy_io_completion.h"
|
||||
|
||||
AdbLegacyIOCompletion::AdbLegacyIOCompletion(
|
||||
AdbLegacyEndpointObject* parent_io_obj,
|
||||
ULONG expected_trans_size,
|
||||
HANDLE event_hndl,
|
||||
bool is_write_ctl)
|
||||
: AdbIOCompletion(parent_io_obj, expected_trans_size, event_hndl),
|
||||
transferred_bytes_(0),
|
||||
is_write_ioctl_(is_write_ctl) {
|
||||
}
|
||||
|
||||
AdbLegacyIOCompletion::~AdbLegacyIOCompletion() {
|
||||
}
|
||||
|
||||
bool AdbLegacyIOCompletion::GetOvelappedIoResult(LPOVERLAPPED ovl_data,
|
||||
ULONG* bytes_transferred,
|
||||
bool wait) {
|
||||
if (NULL != bytes_transferred) {
|
||||
*bytes_transferred = 0;
|
||||
}
|
||||
|
||||
if (!IsOpened()) {
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
ULONG transfer;
|
||||
bool ret = GetOverlappedResult(parent_legacy_io_object()->usb_handle(),
|
||||
overlapped(),
|
||||
&transfer,
|
||||
wait) ? true :
|
||||
false;
|
||||
|
||||
// TODO: This is bizzare but I've seen it happening
|
||||
// that GetOverlappedResult with wait set to true returns "prematurely",
|
||||
// with wrong transferred bytes value and GetLastError reporting
|
||||
// ERROR_IO_PENDING. So, lets give it an up to a 20 ms loop!
|
||||
ULONG error = GetLastError();
|
||||
|
||||
if (wait && ret && (0 == transfer) && (0 != expected_transfer_size_) &&
|
||||
((ERROR_IO_INCOMPLETE == error) || (ERROR_IO_PENDING == error))) {
|
||||
for (int trying = 0; trying < 10; trying++) {
|
||||
Sleep(2);
|
||||
ret = GetOverlappedResult(parent_legacy_io_object()->usb_handle(),
|
||||
overlapped(),
|
||||
&transfer,
|
||||
wait) ? true :
|
||||
false;
|
||||
error = GetLastError();
|
||||
if (!ret || (0 != transfer) ||
|
||||
((ERROR_IO_INCOMPLETE != error) && (ERROR_IO_PENDING != error))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != ovl_data) {
|
||||
CopyMemory(ovl_data, overlapped(), sizeof(OVERLAPPED));
|
||||
}
|
||||
|
||||
if (NULL != bytes_transferred) {
|
||||
*bytes_transferred = is_write_ioctl() ? transferred_bytes_ : transfer;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
115
host/windows/usb/api/adb_legacy_io_completion.h
Executable file
115
host/windows/usb/api/adb_legacy_io_completion.h
Executable file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_API_ADB_LEGACY_IO_COMPLETION_H__
|
||||
#define ANDROID_USB_API_ADB_LEGACY_IO_COMPLETION_H__
|
||||
/** \file
|
||||
This file consists of declaration of class AdbLegacyIOCompletion that
|
||||
encapsulates a wrapper around OVERLAPPED Win32 structure returned from
|
||||
asynchronous I/O requests issued via legacy USB API.
|
||||
*/
|
||||
|
||||
#include "adb_io_completion.h"
|
||||
#include "adb_legacy_endpoint_object.h"
|
||||
|
||||
/** \brief Encapsulates a wrapper around OVERLAPPED Win32 structure returned
|
||||
from asynchronous I/O requests issued via legacy USB API.
|
||||
|
||||
A handle to this object is returned to the caller of each successful
|
||||
asynchronous I/O request. Just like all other handles this handle
|
||||
must be closed after it's no longer needed.
|
||||
*/
|
||||
class AdbLegacyIOCompletion : public AdbIOCompletion {
|
||||
public:
|
||||
/** \brief Constructs the object.
|
||||
|
||||
@param[in] parent_io_obj Parent legacy endpoint that created this
|
||||
instance.
|
||||
@param[in] expected_trans_size Number of bytes expected to be transferred
|
||||
with the I/O.
|
||||
@param[in] event_hndl Event handle that should be signaled when I/O
|
||||
completes. Can be NULL. If it's not NULL this handle will be
|
||||
used to initialize OVERLAPPED structure for this object.
|
||||
@param[in] is_write_ctl Flag indicating whether or not this completion
|
||||
object is created for ADB_IOCTL_BULK_WRITE I/O.
|
||||
*/
|
||||
AdbLegacyIOCompletion(AdbLegacyEndpointObject* parent_io_obj,
|
||||
ULONG expected_trans_size,
|
||||
HANDLE event_hndl,
|
||||
bool is_write_ctl);
|
||||
|
||||
protected:
|
||||
/** \brief Destructs the object.
|
||||
|
||||
We hide destructor in order to prevent ourseves from accidentaly allocating
|
||||
instances on the stack. If such attemp occur, compiler will error.
|
||||
*/
|
||||
virtual ~AdbLegacyIOCompletion();
|
||||
|
||||
//
|
||||
// Abstract overrides
|
||||
//
|
||||
|
||||
public:
|
||||
/** \brief Gets overlapped I/O result
|
||||
|
||||
This method uses GetOverlappedResult to get results of the overlapped I/O
|
||||
operation.
|
||||
@param[out] ovl_data Buffer for the copy of this object's OVERLAPPED
|
||||
structure. Can be NULL.
|
||||
@param[out] bytes_transferred Pointer to a variable that receives the
|
||||
number of bytes that were actually transferred by a read or write
|
||||
operation. See SDK doc on GetOvelappedResult for more information.
|
||||
Unlike regular GetOvelappedResult call this parameter can be NULL.
|
||||
@param[in] wait If this parameter is true, the method does not return
|
||||
until the operation has been completed. If this parameter is false
|
||||
and the operation is still pending, the method returns false and
|
||||
the GetLastError function returns ERROR_IO_INCOMPLETE.
|
||||
@return true if I/O has been completed or false on failure or if request
|
||||
is not yet completed. If false is returned GetLastError() provides
|
||||
extended error information. If GetLastError returns
|
||||
ERROR_IO_INCOMPLETE it means that I/O is not yet completed.
|
||||
*/
|
||||
virtual bool GetOvelappedIoResult(LPOVERLAPPED ovl_data,
|
||||
ULONG* bytes_transferred,
|
||||
bool wait);
|
||||
|
||||
public:
|
||||
/// Gets parent legacy endpoint.
|
||||
AdbLegacyEndpointObject* parent_legacy_io_object() const {
|
||||
return reinterpret_cast<AdbLegacyEndpointObject*>(parent_io_object());
|
||||
}
|
||||
|
||||
/// Gets write IOCTL flag.
|
||||
bool is_write_ioctl() const {
|
||||
return is_write_ioctl_;
|
||||
}
|
||||
|
||||
/// Gets address for ADB_IOCTL_BULK_WRITE output buffer.
|
||||
ULONG* transferred_bytes_ptr() {
|
||||
ATLASSERT(is_write_ioctl());
|
||||
return &transferred_bytes_;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Recepient for number of transferred bytes in write IOCTL.
|
||||
ULONG transferred_bytes_;
|
||||
|
||||
/// Write IOCTL flag.
|
||||
bool is_write_ioctl_;
|
||||
};
|
||||
|
||||
#endif // ANDROID_USB_API_ADB_LEGACY_IO_COMPLETION_H__
|
||||
@@ -305,7 +305,7 @@ ADBAPIHANDLE AdbWinUsbInterfaceObject::OpenEndpoint(
|
||||
}
|
||||
|
||||
ADBAPIHANDLE AdbWinUsbInterfaceObject::OpenEndpoint(UCHAR endpoint_id,
|
||||
UCHAR endpoint_index) {
|
||||
UCHAR endpoint_index) {
|
||||
if (!IsOpened()) {
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user