Revert "Split AdbWinApi.dll into two dlls to remove dependency on WINUSB.DLL"
which breaks the Windows SDK on Donut.
This reverts commit f855c4e8469e31114fccca4c28aeb01a806a9a48.
diff --git a/host/windows/usb/api/AdbWinApi.cpp b/host/windows/usb/api/AdbWinApi.cpp
index e81c2c7..4d18d37 100644
--- a/host/windows/usb/api/AdbWinApi.cpp
+++ b/host/windows/usb/api/AdbWinApi.cpp
@@ -17,7 +17,6 @@
// AdbWinApi.cpp : Implementation of DLL Exports.
#include "stdafx.h"
-#include "adb_api.h"
extern "C" {
int _forceCRTManifest;
@@ -25,73 +24,8 @@
int _forceAtlDllManifest;
};
-/// References InstantiateWinUsbInterface declared in adb_api.cpp
-extern PFN_INSTWINUSBINTERFACE InstantiateWinUsbInterface;
-
class CAdbWinApiModule : public CAtlDllModuleT< CAdbWinApiModule > {
- public:
- CAdbWinApiModule()
- : CAtlDllModuleT< CAdbWinApiModule >(),
- adbwinusbapi_handle_(NULL),
- is_initialized_(false) {
- }
-
- ~CAdbWinApiModule() {
- // Unload AdbWinUsbApi.dll before we exit
- if (NULL != adbwinusbapi_handle_) {
- FreeLibrary(adbwinusbapi_handle_);
- }
- }
-
- /** \brief Loads AdbWinUsbApi.dll and caches its InstantiateWinUsbInterface
- export.
-
- This method is called from DllMain on DLL_PROCESS_ATTACH event. In this
- method we will check if WINUSB.DLL required by AdbWinUsbApi.dll is
- installed, and if it is we will load AdbWinUsbApi.dll and cache address of
- InstantiateWinUsbInterface routine exported from AdbWinUsbApi.dll
- */
- void AttachToAdbWinUsbApi() {
- // We only need to run this only once.
- if (is_initialized_) {
- return;
- }
-
- // Just mark that we have ran initialization.
- is_initialized_ = true;
-
- // Before we can load AdbWinUsbApi.dll we must make sure that WINUSB.DLL
- // has been installed. Build path to the file.
- wchar_t path_to_winusb_dll[MAX_PATH+1];
- if (!GetSystemDirectory(path_to_winusb_dll, MAX_PATH)) {
- return;
- }
- wcscat(path_to_winusb_dll, L"\\WINUSB.DLL");
-
- if (0xFFFFFFFF == GetFileAttributes(path_to_winusb_dll)) {
- // WINUSB.DLL is not installed. We don't (in fact, can't) load
- // AdbWinUsbApi.dll
- return;
- }
-
- // WINUSB.DLL is installed. Lets load AdbWinUsbApi.dll and cache its
- // InstantiateWinUsbInterface export.
- // We require that AdbWinUsbApi.dll is located in the same folder
- // where AdbWinApi.dll and adb.exe are located, so by Windows
- // conventions we can pass just module name, and not the full path.
- adbwinusbapi_handle_ = LoadLibrary(L"AdbWinUsbApi.dll");
- if (NULL != adbwinusbapi_handle_) {
- InstantiateWinUsbInterface = reinterpret_cast<PFN_INSTWINUSBINTERFACE>
- (GetProcAddress(adbwinusbapi_handle_, "InstantiateWinUsbInterface"));
- }
- }
-
- protected:
- /// Handle to the loaded AdbWinUsbApi.dll
- HINSTANCE adbwinusbapi_handle_;
-
- /// Flags whether or not this module has been initialized.
- bool is_initialized_;
+public:
};
CAdbWinApiModule _AtlModule;
@@ -100,12 +34,5 @@
extern "C" BOOL WINAPI DllMain(HINSTANCE instance,
DWORD reason,
LPVOID reserved) {
- // Lets see if we need to initialize InstantiateWinUsbInterface
- // variable. We do that only once, on condition that this DLL is
- // being attached to the process and InstantiateWinUsbInterface
- // address has not been calculated yet.
- if (DLL_PROCESS_ATTACH == reason) {
- _AtlModule.AttachToAdbWinUsbApi();
- }
- return _AtlModule.DllMain(reason, reserved);
+ return _AtlModule.DllMain(reason, reserved);
}
diff --git a/host/windows/usb/api/SOURCES b/host/windows/usb/api/SOURCES
index 3569521..f6e6614 100755
--- a/host/windows/usb/api/SOURCES
+++ b/host/windows/usb/api/SOURCES
@@ -50,7 +50,8 @@
$(SDK_LIB_PATH)\wbemuuid.lib \
$(SDK_LIB_PATH)\uuid.lib \
$(SDK_LIB_PATH)\setupapi.lib \
- $(SDK_LIB_PATH)\usbd.lib
+ $(SDK_LIB_PATH)\usbd.lib \
+ $(SDK_LIB_PATH)\winusb.lib
!IF "$(DDKBUILDENV)" == "fre"
# Libraries for release (free) builds
@@ -86,12 +87,15 @@
# Define source files for AdbWinApi.dll
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 \
adb_legacy_interface.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 \
diff --git a/host/windows/usb/api/adb_api.cpp b/host/windows/usb/api/adb_api.cpp
index 493f62d..f9bd94e 100644
--- a/host/windows/usb/api/adb_api.cpp
+++ b/host/windows/usb/api/adb_api.cpp
@@ -24,19 +24,12 @@
#include "adb_object_handle.h"
#include "adb_interface_enum.h"
#include "adb_interface.h"
+#include "adb_winusb_interface.h"
#include "adb_legacy_interface.h"
#include "adb_endpoint_object.h"
#include "adb_io_completion.h"
#include "adb_helper_routines.h"
-/** \brief Points to InstantiateWinUsbInterface exported from AdbWinUsbApi.dll.
-
- This variable is initialized with the actual address in DllMain routine for
- this DLL on DLL_PROCESS_ATTACH event.
- @see PFN_INSTWINUSBINTERFACE for more information.
-*/
-PFN_INSTWINUSBINTERFACE InstantiateWinUsbInterface = NULL;
-
ADBAPIHANDLE __cdecl AdbEnumInterfaces(GUID class_id,
bool exclude_not_present,
bool exclude_removed,
@@ -108,22 +101,11 @@
ADBAPIHANDLE ret = NULL;
try {
- // Instantiate interface object, depending on the USB driver type.
+ // Instantiate object
if (IsLegacyInterface(interface_name)) {
- // We have legacy USB driver underneath us.
obj = new AdbLegacyInterfaceObject(interface_name);
} else {
- // We have WinUsb driver underneath us. Make sure that AdbWinUsbApi.dll
- // is loaded and its InstantiateWinUsbInterface routine address has
- // been cached.
- if (NULL != InstantiateWinUsbInterface) {
- obj = InstantiateWinUsbInterface(interface_name);
- if (NULL == obj) {
- return NULL;
- }
- } else {
- return NULL;
- }
+ obj = new AdbWinUsbInterfaceObject(interface_name);
}
// Create handle for it
diff --git a/host/windows/usb/api/adb_api.h b/host/windows/usb/api/adb_api.h
index 429a56d..e2ad129 100644
--- a/host/windows/usb/api/adb_api.h
+++ b/host/windows/usb/api/adb_api.h
@@ -110,30 +110,6 @@
/// the driver in isolation from hardware.
#define DEVICE_EMULATOR_PROD_ID 0xDDDD
-/** \brief Function prototype for InstantiateWinUsbInterface routine exported
- from AdbWinUsbApi.dll
-
- In order to provide backward compatibility with the systems that still run
- legacy (custom) USB drivers, and have not installed WINUSB.DLL we need to
- split functionality of our ADB API on Windows between two DLLs: AdbWinApi,
- and AdbWinUsbApi. AdbWinApi is fully capable of working on top of the legacy
- driver, but has no traces to WinUsb. AdbWinUsbApi is capable of working on
- top of WinUsb API. We are forced to do this split, because we can have
- dependency on WINUSB.DLL in the DLL that implements legacy API. The problem
- is that customers may have a legacy driver that they don't want to upgrade
- to WinUsb, so they may not have WINUSB.DLL installed on their machines, but
- they still must be able to use ADB. So, the idea behind the split is as
- such. When AdbWinApi.dll is loaded into a process, it will check WINUSB.DLL
- installation (by checking existance of C:\Windows\System32\winusb.dll). If
- WINUSB.DLL is installed, AdbWinApi will also load AdbWinUsbApi.dll (by
- calling LoadLibrary), and will extract address of InstantiateWinUsbInterface
- routine exported from AdbWinUsbApi.dll. Then this routine will be used to
- instantiate AdbInterfaceObject instance on condition that it is confirmed
- that USB driver underneath us is in deed WinUsb.
-*/
-typedef class AdbInterfaceObject* \
- (__cdecl *PFN_INSTWINUSBINTERFACE)(const wchar_t*);
-
// The following ifdef block is the standard way of creating macros which make
// exporting from a DLL simpler. All files within this DLL are compiled with
// the ADBWIN_EXPORTS symbol defined on the command line. this symbol should
@@ -143,10 +119,8 @@
// as being exported.
#ifdef ADBWIN_EXPORTS
#define ADBWIN_API EXTERN_C __declspec(dllexport)
-#define ADBWIN_API_CLASS __declspec(dllexport)
#else
#define ADBWIN_API EXTERN_C __declspec(dllimport)
-#define ADBWIN_API_CLASS __declspec(dllimport)
#endif
/** \brief Handle to an API object.
diff --git a/host/windows/usb/api/adb_endpoint_object.h b/host/windows/usb/api/adb_endpoint_object.h
index d92aaad..295eb46 100644
--- a/host/windows/usb/api/adb_endpoint_object.h
+++ b/host/windows/usb/api/adb_endpoint_object.h
@@ -29,7 +29,7 @@
This class implement functionality that is common for both, WinUsb and
legacy APIs.
*/
-class ADBWIN_API_CLASS AdbEndpointObject : public AdbObjectHandle {
+class AdbEndpointObject : public AdbObjectHandle {
public:
/** \brief Constructs the object
diff --git a/host/windows/usb/api/adb_interface.h b/host/windows/usb/api/adb_interface.h
index 0aa0d1d..4afb17d 100644
--- a/host/windows/usb/api/adb_interface.h
+++ b/host/windows/usb/api/adb_interface.h
@@ -23,17 +23,12 @@
#include "adb_object_handle.h"
-// 'AdbInterfaceObject::interface_name_' : class 'std::basic_string<_E,_Tr,_A>'
-// needs to have dll-interface to be used by clients of class
-// 'AdbInterfaceObject' We're ok with that, since interface_name_ will not
-// be referenced by name from outside of this class.
-#pragma warning(disable: 4251)
/** \brief Encapsulates an interface on our USB device.
This is an abstract class that implements functionality common for both,
legacy, and WinUsb based interfaces.
*/
-class ADBWIN_API_CLASS AdbInterfaceObject : public AdbObjectHandle {
+class AdbInterfaceObject : public AdbObjectHandle {
public:
/** \brief Constructs the object.
@@ -185,6 +180,9 @@
}
protected:
+ /// Name of the USB interface (device name) for this object
+ std::wstring interface_name_;
+
/// Cached usb device descriptor
USB_DEVICE_DESCRIPTOR usb_device_descriptor_;
@@ -193,11 +191,6 @@
/// Cached usb interface descriptor
USB_INTERFACE_DESCRIPTOR usb_interface_descriptor_;
-
- private:
- /// Name of the USB interface (device name) for this object
- std::wstring interface_name_;
};
-#pragma warning(default: 4251)
#endif // ANDROID_USB_API_ADB_INTERFACE_H__
diff --git a/host/windows/usb/api/adb_io_completion.h b/host/windows/usb/api/adb_io_completion.h
index ea4b4fb..8a7c1d9 100644
--- a/host/windows/usb/api/adb_io_completion.h
+++ b/host/windows/usb/api/adb_io_completion.h
@@ -33,7 +33,7 @@
like all other handles this handle must be closed after it's no longer
needed.
*/
-class ADBWIN_API_CLASS AdbIOCompletion : public AdbObjectHandle {
+class AdbIOCompletion : public AdbObjectHandle {
public:
/** \brief Constructs the object
diff --git a/host/windows/usb/api/adb_object_handle.h b/host/windows/usb/api/adb_object_handle.h
index 2fa4ad0..29ac5e2 100644
--- a/host/windows/usb/api/adb_object_handle.h
+++ b/host/windows/usb/api/adb_object_handle.h
@@ -22,7 +22,6 @@
of the API through a handle.
*/
-#include "adb_api.h"
#include "adb_api_private_defines.h"
/** \brief Defines types of internal API objects
@@ -72,7 +71,7 @@
All API objects that have handles that are sent back to API client must be
derived from this class.
*/
-class ADBWIN_API_CLASS AdbObjectHandle {
+class AdbObjectHandle {
public:
/** \brief Constructs the object
diff --git a/host/windows/usb/api/adb_winusb_endpoint_object.cpp b/host/windows/usb/api/adb_winusb_endpoint_object.cpp
new file mode 100755
index 0000000..236de3b
--- /dev/null
+++ b/host/windows/usb/api/adb_winusb_endpoint_object.cpp
@@ -0,0 +1,159 @@
+/*
+ * 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 AdbWinUsbEndpointObject that
+ encapsulates a handle opened to a WinUsb endpoint on our device.
+*/
+
+#include "stdafx.h"
+#include "adb_winusb_endpoint_object.h"
+#include "adb_winusb_io_completion.h"
+#include "adb_helper_routines.h"
+
+AdbWinUsbEndpointObject::AdbWinUsbEndpointObject(
+ AdbWinUsbInterfaceObject* parent_interf,
+ UCHAR endpoint_id,
+ UCHAR endpoint_index)
+ : AdbEndpointObject(parent_interf, endpoint_id, endpoint_index) {
+}
+
+AdbWinUsbEndpointObject::~AdbWinUsbEndpointObject() {
+}
+
+ADBAPIHANDLE AdbWinUsbEndpointObject::CommonAsyncReadWrite(
+ bool is_read,
+ void* buffer,
+ ULONG bytes_to_transfer,
+ ULONG* bytes_transferred,
+ HANDLE event_handle,
+ ULONG time_out) {
+ if (!SetTimeout(time_out))
+ return false;
+
+ // Create completion i/o object
+ AdbIOCompletion* adb_io_completion = NULL;
+
+ try {
+ adb_io_completion = new AdbWinUsbIOCompletion(this,
+ bytes_to_transfer,
+ event_handle);
+ } catch (... ) {
+ 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;
+ // Go the read / write file way
+ res = is_read ?
+ WinUsb_ReadPipe(parent_winusb_interface()->winusb_handle(),
+ endpoint_id(),
+ reinterpret_cast<PUCHAR>(buffer),
+ bytes_to_transfer,
+ &transferred,
+ adb_io_completion->overlapped()) :
+ WinUsb_WritePipe(parent_winusb_interface()->winusb_handle(),
+ endpoint_id(),
+ reinterpret_cast<PUCHAR>(buffer),
+ bytes_to_transfer,
+ &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 AdbWinUsbEndpointObject::CommonSyncReadWrite(bool is_read,
+ void* buffer,
+ ULONG bytes_to_transfer,
+ ULONG* bytes_transferred,
+ ULONG time_out) {
+ if (!SetTimeout(time_out))
+ return false;
+
+ // 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));
+ overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ BOOL ret = TRUE;
+ ULONG transferred = 0;
+ // Go the read / write file way
+ ret = is_read ?
+ WinUsb_ReadPipe(parent_winusb_interface()->winusb_handle(),
+ endpoint_id(),
+ reinterpret_cast<PUCHAR>(buffer),
+ bytes_to_transfer,
+ &transferred,
+ &overlapped) :
+ WinUsb_WritePipe(parent_winusb_interface()->winusb_handle(),
+ endpoint_id(),
+ reinterpret_cast<PUCHAR>(buffer),
+ bytes_to_transfer,
+ &transferred,
+ &overlapped);
+
+ // Lets see the result
+ if (!ret && (ERROR_IO_PENDING != GetLastError())) {
+ // I/O failed.
+ if (NULL != overlapped.hEvent)
+ ::CloseHandle(overlapped.hEvent);
+ return false;
+ }
+
+ // Lets wait till I/O completes
+ ret = WinUsb_GetOverlappedResult(parent_winusb_interface()->winusb_handle(), &overlapped,
+ &transferred, TRUE);
+ if (ret && (NULL != bytes_transferred)) {
+ *bytes_transferred = transferred;
+ }
+
+ if (NULL != overlapped.hEvent)
+ ::CloseHandle(overlapped.hEvent);
+
+ return ret ? true : false;
+}
+
+bool AdbWinUsbEndpointObject::SetTimeout(ULONG timeout) {
+ if (!WinUsb_SetPipePolicy(parent_winusb_interface()->winusb_handle(),
+ endpoint_id(), PIPE_TRANSFER_TIMEOUT,
+ sizeof(ULONG), &timeout)) {
+ return false;
+ }
+
+ return true;
+}
diff --git a/host/windows/usb/api/adb_winusb_endpoint_object.h b/host/windows/usb/api/adb_winusb_endpoint_object.h
new file mode 100755
index 0000000..26ef53b
--- /dev/null
+++ b/host/windows/usb/api/adb_winusb_endpoint_object.h
@@ -0,0 +1,131 @@
+/*
+ * 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_WINUSB_ENDPOINT_OBJECT_H__
+#define ANDROID_USB_API_ADB_WINUSB_ENDPOINT_OBJECT_H__
+/** \file
+ This file consists of declaration of class AdbWinUsbEndpointObject that
+ encapsulates a handle opened to a WinUsb endpoint on our device.
+*/
+
+#include "adb_endpoint_object.h"
+#include "adb_winusb_interface.h"
+
+/** Class AdbWinUsbEndpointObject encapsulates a handle opened to an endpoint on
+ our device.
+*/
+class AdbWinUsbEndpointObject : public AdbEndpointObject {
+ public:
+ /** \brief Constructs the object
+
+ @param[in] interface Parent WinUsb 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.
+ */
+ AdbWinUsbEndpointObject(AdbWinUsbInterfaceObject* 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 ~AdbWinUsbEndpointObject();
+
+ //
+ // 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
+ //
+
+ protected:
+ /** \brief Sets read / write operation timeout.
+
+ @param[in] timeout Timeout value in milliseconds to use for current read
+ or write operation. Zero value passed in this parameters indicate
+ not timeout at all. Note that timeout that is set with this method is
+ global per endpoint (pipe). I.e. once set, it will be used against
+ all read / write operations performed on this endpoint, untill
+ another call to this method modifies it. This is a WinUsb design
+ flaw. Microsoft is aware of this and (hopefuly) future versions of
+ WinUsb framework will accept a timeout parameter in WinUsb_Read/Write
+ routines. For the purposes of ADB this flaw doesn't apperar to be an
+ issue, since we use single-threaded synchronous read / writes, so
+ there is no conflict in setting per-endpoint timeouts.
+ @return true on success, false on failure. If false is returned
+ GetLastError() provides extended error information.
+ */
+ virtual bool SetTimeout(ULONG timeout);
+
+ public:
+ /// Gets parent WinUsb interface
+ AdbWinUsbInterfaceObject* parent_winusb_interface() const {
+ return reinterpret_cast<AdbWinUsbInterfaceObject*>(parent_interface());
+ }
+
+ /// Gets parent interface WinUsb handle
+ WINUSB_INTERFACE_HANDLE winusb_handle() const {
+ return parent_winusb_interface()->winusb_handle();
+ }
+};
+
+#endif // ANDROID_USB_API_ADB_WINUSB_ENDPOINT_OBJECT_H__
diff --git a/host/windows/usb/api/adb_winusb_interface.cpp b/host/windows/usb/api/adb_winusb_interface.cpp
new file mode 100755
index 0000000..d09c1cb
--- /dev/null
+++ b/host/windows/usb/api/adb_winusb_interface.cpp
@@ -0,0 +1,329 @@
+/*
+ * 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 AdbWinUsbInterfaceObject
+ that encapsulates an interface on our USB device that is accessible
+ via WinUsb API.
+*/
+
+#include "stdafx.h"
+#include "adb_winusb_interface.h"
+#include "adb_winusb_endpoint_object.h"
+
+AdbWinUsbInterfaceObject::AdbWinUsbInterfaceObject(const wchar_t* interf_name)
+ : AdbInterfaceObject(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) {
+}
+
+AdbWinUsbInterfaceObject::~AdbWinUsbInterfaceObject() {
+ ATLASSERT(NULL == winusb_handle_);
+ ATLASSERT(INVALID_HANDLE_VALUE == usb_device_handle_);
+}
+
+ADBAPIHANDLE AdbWinUsbInterfaceObject::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 AdbInterfaceObject::CreateHandle();
+}
+
+bool AdbWinUsbInterfaceObject::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 AdbInterfaceObject::CloseHandle();
+}
+
+bool AdbWinUsbInterfaceObject::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 AdbWinUsbInterfaceObject::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 AdbWinUsbInterfaceObject::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 AdbWinUsbInterfaceObject::OpenEndpoint(UCHAR endpoint_id,
+ UCHAR endpoint_index) {
+ if (!IsOpened()) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ AdbEndpointObject* adb_endpoint = NULL;
+
+ try {
+ adb_endpoint =
+ new AdbWinUsbEndpointObject(this, endpoint_id, endpoint_index);
+ } catch (...) {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return NULL;
+ }
+
+ ADBAPIHANDLE ret = adb_endpoint->CreateHandle();
+
+ adb_endpoint->Release();
+
+ return ret;
+}
diff --git a/host/windows/usb/api/adb_winusb_interface.h b/host/windows/usb/api/adb_winusb_interface.h
new file mode 100755
index 0000000..82f7f89
--- /dev/null
+++ b/host/windows/usb/api/adb_winusb_interface.h
@@ -0,0 +1,186 @@
+/*
+ * 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_WINUSB_INTERFACE_H__
+#define ANDROID_USB_API_ADB_WINUSB_INTERFACE_H__
+/** \file
+ This file consists of declaration of class AdbWinUsbInterfaceObject
+ that encapsulates an interface on our USB device that is accessible
+ via WinUsb API.
+*/
+
+#include "adb_interface.h"
+
+/** \brief Encapsulates an interface on our USB device that is accessible
+ via WinUsb API.
+*/
+class AdbWinUsbInterfaceObject : public AdbInterfaceObject {
+ public:
+ /** \brief Constructs the object.
+
+ @param[in] interf_name Name of the interface
+ */
+ explicit AdbWinUsbInterfaceObject(const wchar_t* interf_name);
+
+ 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 ~AdbWinUsbInterfaceObject();
+
+ //
+ // Virtual overrides
+ //
+
+ public:
+ /** \brief Creates handle to this object.
+
+ In this call a handle for this object is generated and object is added
+ to the AdbObjectHandleMap. We override this method in order to initialize
+ WinUsb API for the given interface.
+ @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();
+
+ /** \brief This method is called when handle to this object gets closed.
+
+ In this call object is deleted from the AdbObjectHandleMap. We override
+ this method in order close WinUsb handle created 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();
+
+ //
+ // Abstract overrides
+ //
+
+ public:
+ /** \brief Gets serial number for interface's device.
+
+ @param[out] buffer Buffer for the serail number string. Can be NULL in
+ which case buffer_char_size will contain number of characters
+ required for the string.
+ @param[in,out] buffer_char_size On the way in supplies size (in characters)
+ of the buffer. On the way out, if method failed and GetLastError
+ reports ERROR_INSUFFICIENT_BUFFER, will contain number of characters
+ required for the name.
+ @param[in] ansi If true the name will be returned as single character
+ string. Otherwise name will be returned as wide character string.
+ @return true on success, false on failure. If false is returned
+ GetLastError() provides extended error information.
+ */
+ virtual bool GetSerialNumber(void* buffer,
+ unsigned long* buffer_char_size,
+ bool ansi);
+
+ /** \brief Gets information about an endpoint on this interface.
+
+ @param[in] endpoint_index Zero-based endpoint index. There are two
+ shortcuts for this parameter: ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX
+ and ADB_QUERY_BULK_READ_ENDPOINT_INDEX that provide infor about
+ (default?) bulk write and read endpoints respectively.
+ @param[out] info Upon successful completion will have endpoint information.
+ @return true on success, false on failure. If false is returned
+ GetLastError() provides extended error information.
+ */
+ virtual bool GetEndpointInformation(UCHAR endpoint_index,
+ AdbEndpointInformation* info);
+
+ /** \brief Opens an endpoint on this interface.
+
+ @param[in] endpoint_index Zero-based endpoint index. There are two
+ shortcuts for this parameter: ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX
+ and ADB_QUERY_BULK_READ_ENDPOINT_INDEX that provide infor about
+ (default?) bulk write and read endpoints respectively.
+ @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.
+ */
+ virtual ADBAPIHANDLE OpenEndpoint(UCHAR endpoint_index,
+ AdbOpenAccessType access_type,
+ AdbOpenSharingMode sharing_mode);
+
+ //
+ // Operations
+ //
+
+ protected:
+ /** \brief Opens an endpoint on this interface.
+
+ @param[in] endpoint_id Endpoint (pipe) address on the device.
+ @param[in] endpoint_index Zero-based endpoint index.
+ @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(UCHAR endpoint_id, UCHAR endpoint_index);
+
+ public:
+ /// Gets handle to the USB device
+ HANDLE usb_device_handle() const {
+ return usb_device_handle_;
+ }
+
+ /// Gets interface handle used by WinUSB API
+ WINUSB_INTERFACE_HANDLE winusb_handle() const {
+ return winusb_handle_;
+ }
+
+ /// Gets current interface number.
+ UCHAR interface_number() const {
+ return interface_number_;
+ }
+
+ protected:
+ /// Handle to the USB device
+ HANDLE usb_device_handle_;
+
+ /// Interface handle used by WinUSB API
+ WINUSB_INTERFACE_HANDLE winusb_handle_;
+
+ /// Current interface number. This value is obtained via call to
+ /// WinUsb_GetCurrentAlternateSetting and is used in WinUsb_Xxx
+ /// calls that require interface number.
+ UCHAR interface_number_;
+
+ /// 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_WINUSB_INTERFACE_H__
diff --git a/host/windows/usb/api/adb_winusb_io_completion.cpp b/host/windows/usb/api/adb_winusb_io_completion.cpp
new file mode 100755
index 0000000..baeb7bb
--- /dev/null
+++ b/host/windows/usb/api/adb_winusb_io_completion.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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 AdbWinUsbIOCompletion that
+ encapsulates a wrapper around OVERLAPPED Win32 structure returned from
+ asynchronous I/O requests issued via WinUsb API.
+*/
+
+#include "stdafx.h"
+#include "adb_winusb_io_completion.h"
+
+AdbWinUsbIOCompletion::AdbWinUsbIOCompletion(
+ AdbWinUsbEndpointObject* parent_io_obj,
+ ULONG expected_trans_size,
+ HANDLE event_hndl)
+ : AdbIOCompletion(parent_io_obj, expected_trans_size, event_hndl) {
+}
+
+AdbWinUsbIOCompletion::~AdbWinUsbIOCompletion() {
+}
+
+bool AdbWinUsbIOCompletion::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 = WinUsb_GetOverlappedResult(
+ parent_winusb_io_object()->winusb_handle(),
+ overlapped(),
+ &transfer,
+ wait ? TRUE : FALSE) ? 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 = WinUsb_GetOverlappedResult(
+ parent_winusb_io_object()->winusb_handle(),
+ overlapped(),
+ &transfer,
+ wait ? TRUE : FALSE) ? 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 = transfer;
+ }
+
+ return ret;
+}
diff --git a/host/windows/usb/api/adb_winusb_io_completion.h b/host/windows/usb/api/adb_winusb_io_completion.h
new file mode 100755
index 0000000..a97a3a8
--- /dev/null
+++ b/host/windows/usb/api/adb_winusb_io_completion.h
@@ -0,0 +1,94 @@
+/*
+ * 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_WINUSB_IO_COMPLETION_H__
+#define ANDROID_USB_API_ADB_WINUSB_IO_COMPLETION_H__
+/** \file
+ This file consists of declaration of class AdbWinUsbIOCompletion that
+ encapsulates a wrapper around OVERLAPPED Win32 structure returned from
+ asynchronous I/O requests issued via WinUsb API.
+*/
+
+#include "adb_io_completion.h"
+#include "adb_winusb_endpoint_object.h"
+
+/** \brief Encapsulates encapsulates a wrapper around OVERLAPPED Win32
+ structure returned from asynchronous I/O requests issued via WinUsb 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 AdbWinUsbIOCompletion : public AdbIOCompletion {
+ public:
+ /** \brief Constructs the object
+
+ @param[in] parent_io_obj Parent WinUsb I/O object 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.
+ */
+ AdbWinUsbIOCompletion(AdbWinUsbEndpointObject* parent_io_obj,
+ ULONG expected_trans_size,
+ HANDLE event_hndl);
+
+ 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 ~AdbWinUsbIOCompletion();
+
+ //
+ // Abstract overrides
+ //
+
+ public:
+ /** \brief Gets overlapped I/O result
+
+ This method uses WinUsb_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 WinUsb parent object
+ AdbWinUsbEndpointObject* parent_winusb_io_object() const {
+ return reinterpret_cast<AdbWinUsbEndpointObject*>(parent_io_object());
+ }
+};
+
+#endif // ANDROID_USB_API_ADB_WINUSB_IO_COMPLETION_H__
diff --git a/host/windows/usb/api/stdafx.h b/host/windows/usb/api/stdafx.h
index d57bec7..92b2652 100644
--- a/host/windows/usb/api/stdafx.h
+++ b/host/windows/usb/api/stdafx.h
@@ -71,8 +71,11 @@
#include <string>
#pragma warning(default: 4201)
#pragma warning(disable: 4200)
+extern "C" {
#include <usbdi.h>
+#include <winusb.h>
#include <usb100.h>
+}
#include "resource.h"