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"