Split AdbWinApi.dll into two dlls to remove dependency on WINUSB.DLL
Move all WINUSB-dependent functionality into AdbWinUsbApi.dll in order to
enable ADB on condition that WINUSB has not been installed.
diff --git a/host/windows/usb/api/AdbWinApi.cpp b/host/windows/usb/api/AdbWinApi.cpp
index 4d18d37..e81c2c7 100644
--- a/host/windows/usb/api/AdbWinApi.cpp
+++ b/host/windows/usb/api/AdbWinApi.cpp
@@ -17,6 +17,7 @@
// AdbWinApi.cpp : Implementation of DLL Exports.
#include "stdafx.h"
+#include "adb_api.h"
extern "C" {
int _forceCRTManifest;
@@ -24,8 +25,73 @@
int _forceAtlDllManifest;
};
+/// References InstantiateWinUsbInterface declared in adb_api.cpp
+extern PFN_INSTWINUSBINTERFACE InstantiateWinUsbInterface;
+
class CAdbWinApiModule : public CAtlDllModuleT< CAdbWinApiModule > {
-public:
+ 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_;
};
CAdbWinApiModule _AtlModule;
@@ -34,5 +100,12 @@
extern "C" BOOL WINAPI DllMain(HINSTANCE instance,
DWORD reason,
LPVOID reserved) {
- return _AtlModule.DllMain(reason, 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);
}
diff --git a/host/windows/usb/api/SOURCES b/host/windows/usb/api/SOURCES
index f6e6614..3569521 100755
--- a/host/windows/usb/api/SOURCES
+++ b/host/windows/usb/api/SOURCES
@@ -50,8 +50,7 @@
$(SDK_LIB_PATH)\wbemuuid.lib \
$(SDK_LIB_PATH)\uuid.lib \
$(SDK_LIB_PATH)\setupapi.lib \
- $(SDK_LIB_PATH)\usbd.lib \
- $(SDK_LIB_PATH)\winusb.lib
+ $(SDK_LIB_PATH)\usbd.lib
!IF "$(DDKBUILDENV)" == "fre"
# Libraries for release (free) builds
@@ -87,15 +86,12 @@
# 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 f9bd94e..493f62d 100644
--- a/host/windows/usb/api/adb_api.cpp
+++ b/host/windows/usb/api/adb_api.cpp
@@ -24,12 +24,19 @@
#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,
@@ -101,11 +108,22 @@
ADBAPIHANDLE ret = NULL;
try {
- // Instantiate object
+ // Instantiate interface object, depending on the USB driver type.
if (IsLegacyInterface(interface_name)) {
+ // We have legacy USB driver underneath us.
obj = new AdbLegacyInterfaceObject(interface_name);
} else {
- obj = new AdbWinUsbInterfaceObject(interface_name);
+ // 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;
+ }
}
// Create handle for it
diff --git a/host/windows/usb/api/adb_api.h b/host/windows/usb/api/adb_api.h
index e2ad129..429a56d 100644
--- a/host/windows/usb/api/adb_api.h
+++ b/host/windows/usb/api/adb_api.h
@@ -110,6 +110,30 @@
/// 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
@@ -119,8 +143,10 @@
// 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 295eb46..d92aaad 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 AdbEndpointObject : public AdbObjectHandle {
+class ADBWIN_API_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 4afb17d..0aa0d1d 100644
--- a/host/windows/usb/api/adb_interface.h
+++ b/host/windows/usb/api/adb_interface.h
@@ -23,12 +23,17 @@
#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 AdbInterfaceObject : public AdbObjectHandle {
+class ADBWIN_API_CLASS AdbInterfaceObject : public AdbObjectHandle {
public:
/** \brief Constructs the object.
@@ -180,9 +185,6 @@
}
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_;
@@ -191,6 +193,11 @@
/// 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 8a7c1d9..ea4b4fb 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 AdbIOCompletion : public AdbObjectHandle {
+class ADBWIN_API_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 29ac5e2..2fa4ad0 100644
--- a/host/windows/usb/api/adb_object_handle.h
+++ b/host/windows/usb/api/adb_object_handle.h
@@ -22,6 +22,7 @@
of the API through a handle.
*/
+#include "adb_api.h"
#include "adb_api_private_defines.h"
/** \brief Defines types of internal API objects
@@ -71,7 +72,7 @@
All API objects that have handles that are sent back to API client must be
derived from this class.
*/
-class AdbObjectHandle {
+class ADBWIN_API_CLASS AdbObjectHandle {
public:
/** \brief Constructs the object
diff --git a/host/windows/usb/api/stdafx.h b/host/windows/usb/api/stdafx.h
index 92b2652..d57bec7 100644
--- a/host/windows/usb/api/stdafx.h
+++ b/host/windows/usb/api/stdafx.h
@@ -71,11 +71,8 @@
#include <string>
#pragma warning(default: 4201)
#pragma warning(disable: 4200)
-extern "C" {
#include <usbdi.h>
-#include <winusb.h>
#include <usb100.h>
-}
#include "resource.h"
diff --git a/host/windows/usb/winusb/AdbWinUsbApi.cpp b/host/windows/usb/winusb/AdbWinUsbApi.cpp
new file mode 100755
index 0000000..4916eeb
--- /dev/null
+++ b/host/windows/usb/winusb/AdbWinUsbApi.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+// AdbWinUsbApi.cpp : Implementation of DLL Exports.
+
+#include "stdafx.h"
+#include "adb_winusb_interface.h"
+
+class CAdbWinApiModule : public CAtlDllModuleT< CAdbWinApiModule > {
+public:
+};
+
+CAdbWinApiModule _AtlModule;
+
+// DLL Entry Point
+extern "C" BOOL WINAPI DllMain(HINSTANCE instance,
+ DWORD reason,
+ LPVOID reserved) {
+ return _AtlModule.DllMain(reason, reserved);
+}
+
+/** \brief Instantiates interface instance that uses WinUsb API to communicate
+ with USB driver.
+
+ This is the only exported routine from this DLL. This routine instantiates an
+ object of AdbWinUsbInterfaceObject on request from AdbWinApi.dll when it is
+ detected that underlying USB driver is WinUsb.sys.
+ @param[in] interface_name Name of the interface.
+ @return AdbInterfaceObject - casted instance of AdbWinUsbInterfaceObject
+ object on success, or NULL on failure with GetLastError providing
+ information on an error that occurred.
+*/
+extern "C" __declspec(dllexport)
+AdbInterfaceObject* __cdecl InstantiateWinUsbInterface(
+ const wchar_t* interface_name) {
+ // Validate parameter.
+ if (NULL == interface_name) {
+ return NULL;
+ }
+
+ // Instantiate requested object.
+ try {
+ return new AdbWinUsbInterfaceObject(interface_name);
+ } catch (...) {
+ // We expect only OOM exceptions here.
+ SetLastError(ERROR_OUTOFMEMORY);
+ return NULL;
+ }
+}
diff --git a/host/windows/usb/winusb/AdbWinUsbApi.def b/host/windows/usb/winusb/AdbWinUsbApi.def
new file mode 100755
index 0000000..9e616e9
--- /dev/null
+++ b/host/windows/usb/winusb/AdbWinUsbApi.def
@@ -0,0 +1,5 @@
+; AdbWinUsbApi.def : Declares the module parameters.
+
+LIBRARY "AdbWinUsbApi.DLL"
+
+EXPORTS
diff --git a/host/windows/usb/winusb/AdbWinUsbApi.rc b/host/windows/usb/winusb/AdbWinUsbApi.rc
new file mode 100755
index 0000000..44aa100
--- /dev/null
+++ b/host/windows/usb/winusb/AdbWinUsbApi.rc
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+//Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2,0,0,0
+ PRODUCTVERSION 2,0,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "Google, inc"
+ VALUE "FileDescription", "Android ADB API (WinUsb)"
+ VALUE "FileVersion", "2.0.0.0"
+ VALUE "LegalCopyright", "Copyright (C) 2006 The Android Open Source Project"
+ VALUE "InternalName", "AdbWinUsbApi.dll"
+ VALUE "OriginalFilename", "AdbWinUsbApi.dll"
+ VALUE "ProductName", "Android SDK"
+ VALUE "ProductVersion", "2.0.0.0"
+ VALUE "OLESelfRegister", ""
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 1252
+ END
+END
+
+#endif // !_MAC
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_PROJNAME "AdbWinUsbApi"
+END
+
+////////////////////////////////////////////////////////////////////////////
+
+
+#endif
+
+#ifndef APSTUDIO_INVOKED
+#endif // not APSTUDIO_INVOKED
diff --git a/host/windows/usb/winusb/BUILDME.TXT b/host/windows/usb/winusb/BUILDME.TXT
new file mode 100755
index 0000000..2a459ef
--- /dev/null
+++ b/host/windows/usb/winusb/BUILDME.TXT
@@ -0,0 +1,7 @@
+In order to build AdbWinUsbApi.dll you will need to install Windows Driver Kit,
+which can be obtained from Microsoft. Assuming that WDK is installed, you
+need to set one of the WDK's build environments, "cd" back into this directory,
+and execute "build -cbeEIFZ" to clean and rebuild this project, or you can
+execute "build -befEIF" to do a minimal build.
+Note that you need to build AdbWinApi.dll (..\api) before you build
+AdbWinUsbApi.dll, as it depends on AdbWinApi.lib library.
diff --git a/host/windows/usb/winusb/MAKEFILE b/host/windows/usb/winusb/MAKEFILE
new file mode 100755
index 0000000..fcd896d
--- /dev/null
+++ b/host/windows/usb/winusb/MAKEFILE
@@ -0,0 +1,22 @@
+#
+# 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.
+#
+
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/host/windows/usb/winusb/Resource.h b/host/windows/usb/winusb/Resource.h
new file mode 100755
index 0000000..3ede761
--- /dev/null
+++ b/host/windows/usb/winusb/Resource.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by AdbWinApi.rc
+//
+
+#define IDS_PROJNAME 100
+#define IDR_ADBWINAPI 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 201
+#define _APS_NEXT_COMMAND_VALUE 32768
+#define _APS_NEXT_CONTROL_VALUE 201
+#define _APS_NEXT_SYMED_VALUE 102
+#endif
+#endif
diff --git a/host/windows/usb/winusb/SOURCES b/host/windows/usb/winusb/SOURCES
new file mode 100755
index 0000000..80d17ae
--- /dev/null
+++ b/host/windows/usb/winusb/SOURCES
@@ -0,0 +1,93 @@
+#
+# 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.
+#
+
+TARGETNAME = AdbWinUsbApi
+TARGETPATH = obj
+TARGETTYPE = DYNLINK
+
+UMTYPE = windows
+DLLDEF = AdbWinUsbApi.def
+
+# Use statically linked atl libraries:
+# - atls.lib for free build
+# - atlsd.lib for checked build
+USE_STATIC_ATL = 1
+# Use ATL v. 7.1
+ATL_VER = 71
+# Use STL v. 6.0
+USE_STL = 1
+STL_VER = 60
+# Use multithreaded libraries
+USE_LIBCMT = 1
+
+# Include directories
+INCLUDES = $(DDK_INC_PATH); \
+ $(SDK_INC_PATH); \
+ $(CRT_INC_PATH); \
+ $(SDK_INC_PATH)\crt; \
+ $(CRT_INC_PATH)\atl71; \
+ $(SDK_INC_PATH)\crt\stl60
+
+# Common target libraries
+TARGETLIBS = $(SDK_LIB_PATH)\ole32.lib \
+ $(SDK_LIB_PATH)\Advapi32.lib \
+ $(SDK_LIB_PATH)\Kernel32.lib \
+ $(SDK_LIB_PATH)\User32.lib \
+ $(SDK_LIB_PATH)\oleaut32.lib \
+ $(SDK_LIB_PATH)\wbemuuid.lib \
+ $(SDK_LIB_PATH)\uuid.lib \
+ $(SDK_LIB_PATH)\setupapi.lib \
+ $(SDK_LIB_PATH)\usbd.lib \
+ $(SDK_LIB_PATH)\winusb.lib \
+ ..\api\obj$(BUILD_ALT_DIR)\i386\AdbWinApi.lib
+
+!IF "$(DDKBUILDENV)" == "fre"
+# Libraries for release (free) builds
+TARGETLIBS = $(TARGETLIBS) $(ATL_LIB_PATH)\atls.lib
+!ELSE
+# Libraries for debug (checked) builds
+TARGETLIBS = $(TARGETLIBS) $(ATL_LIB_PATH)\atlsd.lib
+!ENDIF
+
+# Common C defines
+C_DEFINES= $(C_DEFINES) -DADBWINUSB_EXPORTS -D_UNICODE \
+ -DUNICODE -DWIN32 -D_WINDOWS -D_USRDLL -D_WINDLL
+
+!IF "$(DDKBUILDENV)" == "fre"
+# C defines for release (free) builds
+C_DEFINES = $(C_DEFINES) -DNDEBUG
+!ELSE
+# C defines for debug (checked) builds
+C_DEFINES = $(C_DEFINES) -D_DEBUG
+!ENDIF
+
+# Turn on all warnings, and treat warnings as errors
+MSC_WARNING_LEVEL = /W4 /Wp64 /WX
+
+# Common C defines
+USER_C_FLAGS = $(USER_C_FLAGS) /FD /EHsc /wd4100 /wd4200 /wd4702 /nologo
+
+# Set precompiled header information
+PRECOMPILED_CXX = 1
+PRECOMPILED_INCLUDE = stdafx.h
+PRECOMPILED_SOURCEFILE = stdafx.cpp
+
+# Define source files for AdbWinUsbApi.dll
+SOURCES = adb_winusb_endpoint_object.cpp \
+ adb_winusb_interface.cpp \
+ adb_winusb_io_completion.cpp \
+ AdbWinUsbApi.cpp \
+ AdbWinUsbApi.rc
diff --git a/host/windows/usb/api/adb_winusb_endpoint_object.cpp b/host/windows/usb/winusb/adb_winusb_endpoint_object.cpp
similarity index 95%
rename from host/windows/usb/api/adb_winusb_endpoint_object.cpp
rename to host/windows/usb/winusb/adb_winusb_endpoint_object.cpp
index 236de3b..16f7837 100755
--- a/host/windows/usb/api/adb_winusb_endpoint_object.cpp
+++ b/host/windows/usb/winusb/adb_winusb_endpoint_object.cpp
@@ -22,7 +22,6 @@
#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,
@@ -34,6 +33,17 @@
AdbWinUsbEndpointObject::~AdbWinUsbEndpointObject() {
}
+LONG AdbWinUsbEndpointObject::Release() {
+ ATLASSERT(ref_count_ > 0);
+ LONG ret = InterlockedDecrement(&ref_count_);
+ ATLASSERT(ret >= 0);
+ if (0 == ret) {
+ LastReferenceReleased();
+ delete this;
+ }
+ return ret;
+}
+
ADBAPIHANDLE AdbWinUsbEndpointObject::CommonAsyncReadWrite(
bool is_read,
void* buffer,
diff --git a/host/windows/usb/api/adb_winusb_endpoint_object.h b/host/windows/usb/winusb/adb_winusb_endpoint_object.h
similarity index 83%
rename from host/windows/usb/api/adb_winusb_endpoint_object.h
rename to host/windows/usb/winusb/adb_winusb_endpoint_object.h
index 26ef53b..92b6e04 100755
--- a/host/windows/usb/api/adb_winusb_endpoint_object.h
+++ b/host/windows/usb/winusb/adb_winusb_endpoint_object.h
@@ -21,7 +21,7 @@
encapsulates a handle opened to a WinUsb endpoint on our device.
*/
-#include "adb_endpoint_object.h"
+#include "..\api\adb_endpoint_object.h"
#include "adb_winusb_interface.h"
/** Class AdbWinUsbEndpointObject encapsulates a handle opened to an endpoint on
@@ -49,6 +49,30 @@
virtual ~AdbWinUsbEndpointObject();
//
+ // Virtual overrides
+ //
+
+ public:
+ /** \brief Releases the object.
+
+ If refcount drops to zero as the result of this release, the object is
+ destroyed in this method. As a general rule, objects must not be touched
+ after this method returns even if returned value is not zero. We override
+ this method in order to make sure that objects of this class are deleted
+ in contect of the DLL they were created in. The problem is that since
+ objects of this class were created in context of AdbWinUsbApi module, they
+ are allocated from the heap assigned to that module. Now, if these objects
+ are deleted outside of AdbWinUsbApi module, this will lead to the heap
+ corruption in the module that deleted these objects. Since all objects of
+ this class are deleted in the Release method only, by overriding it we make
+ sure that we free memory in the context of the module where it was
+ allocated.
+ @return Value of the reference counter after object is released in this
+ method.
+ */
+ virtual LONG Release();
+
+ //
// Abstract overrides
//
diff --git a/host/windows/usb/api/adb_winusb_interface.cpp b/host/windows/usb/winusb/adb_winusb_interface.cpp
similarity index 97%
rename from host/windows/usb/api/adb_winusb_interface.cpp
rename to host/windows/usb/winusb/adb_winusb_interface.cpp
index d09c1cb..9d0377a 100755
--- a/host/windows/usb/api/adb_winusb_interface.cpp
+++ b/host/windows/usb/winusb/adb_winusb_interface.cpp
@@ -40,6 +40,17 @@
ATLASSERT(INVALID_HANDLE_VALUE == usb_device_handle_);
}
+LONG AdbWinUsbInterfaceObject::Release() {
+ ATLASSERT(ref_count_ > 0);
+ LONG ret = InterlockedDecrement(&ref_count_);
+ ATLASSERT(ret >= 0);
+ if (0 == ret) {
+ LastReferenceReleased();
+ delete this;
+ }
+ return ret;
+}
+
ADBAPIHANDLE AdbWinUsbInterfaceObject::CreateHandle() {
// Open USB device for this inteface Note that WinUsb API
// requires the handle to be opened for overlapped I/O.
diff --git a/host/windows/usb/api/adb_winusb_interface.h b/host/windows/usb/winusb/adb_winusb_interface.h
similarity index 86%
rename from host/windows/usb/api/adb_winusb_interface.h
rename to host/windows/usb/winusb/adb_winusb_interface.h
index 82f7f89..2311fd1 100755
--- a/host/windows/usb/api/adb_winusb_interface.h
+++ b/host/windows/usb/winusb/adb_winusb_interface.h
@@ -22,7 +22,7 @@
via WinUsb API.
*/
-#include "adb_interface.h"
+#include "..\api\adb_interface.h"
/** \brief Encapsulates an interface on our USB device that is accessible
via WinUsb API.
@@ -48,6 +48,25 @@
//
public:
+ /** \brief Releases the object.
+
+ If refcount drops to zero as the result of this release, the object is
+ destroyed in this method. As a general rule, objects must not be touched
+ after this method returns even if returned value is not zero. We override
+ this method in order to make sure that objects of this class are deleted
+ in contect of the DLL they were created in. The problem is that since
+ objects of this class were created in context of AdbWinUsbApi module, they
+ are allocated from the heap assigned to that module. Now, if these objects
+ are deleted outside of AdbWinUsbApi module, this will lead to the heap
+ corruption in the module that deleted these objects. Since all objects of
+ this class are deleted in the Release method only, by overriding it we make
+ sure that we free memory in the context of the module where it was
+ allocated.
+ @return Value of the reference counter after object is released in this
+ method.
+ */
+ virtual LONG Release();
+
/** \brief Creates handle to this object.
In this call a handle for this object is generated and object is added
diff --git a/host/windows/usb/api/adb_winusb_io_completion.cpp b/host/windows/usb/winusb/adb_winusb_io_completion.cpp
similarity index 92%
rename from host/windows/usb/api/adb_winusb_io_completion.cpp
rename to host/windows/usb/winusb/adb_winusb_io_completion.cpp
index baeb7bb..d98f872 100755
--- a/host/windows/usb/api/adb_winusb_io_completion.cpp
+++ b/host/windows/usb/winusb/adb_winusb_io_completion.cpp
@@ -33,6 +33,17 @@
AdbWinUsbIOCompletion::~AdbWinUsbIOCompletion() {
}
+LONG AdbWinUsbIOCompletion::Release() {
+ ATLASSERT(ref_count_ > 0);
+ LONG ret = InterlockedDecrement(&ref_count_);
+ ATLASSERT(ret >= 0);
+ if (0 == ret) {
+ LastReferenceReleased();
+ delete this;
+ }
+ return ret;
+}
+
bool AdbWinUsbIOCompletion::GetOvelappedIoResult(LPOVERLAPPED ovl_data,
ULONG* bytes_transferred,
bool wait) {
diff --git a/host/windows/usb/api/adb_winusb_io_completion.h b/host/windows/usb/winusb/adb_winusb_io_completion.h
similarity index 77%
rename from host/windows/usb/api/adb_winusb_io_completion.h
rename to host/windows/usb/winusb/adb_winusb_io_completion.h
index a97a3a8..93a4c07 100755
--- a/host/windows/usb/api/adb_winusb_io_completion.h
+++ b/host/windows/usb/winusb/adb_winusb_io_completion.h
@@ -22,7 +22,7 @@
asynchronous I/O requests issued via WinUsb API.
*/
-#include "adb_io_completion.h"
+#include "..\api\adb_io_completion.h"
#include "adb_winusb_endpoint_object.h"
/** \brief Encapsulates encapsulates a wrapper around OVERLAPPED Win32
@@ -57,6 +57,30 @@
virtual ~AdbWinUsbIOCompletion();
//
+ // Virtual overrides
+ //
+
+ public:
+ /** \brief Releases the object.
+
+ If refcount drops to zero as the result of this release, the object is
+ destroyed in this method. As a general rule, objects must not be touched
+ after this method returns even if returned value is not zero. We override
+ this method in order to make sure that objects of this class are deleted
+ in contect of the DLL they were created in. The problem is that since
+ objects of this class were created in context of AdbWinUsbApi module, they
+ are allocated from the heap assigned to that module. Now, if these objects
+ are deleted outside of AdbWinUsbApi module, this will lead to the heap
+ corruption in the module that deleted these objects. Since all objects of
+ this class are deleted in the Release method only, by overriding it we make
+ sure that we free memory in the context of the module where it was
+ allocated.
+ @return Value of the reference counter after object is released in this
+ method.
+ */
+ virtual LONG Release();
+
+ //
// Abstract overrides
//
diff --git a/host/windows/usb/winusb/stdafx.cpp b/host/windows/usb/winusb/stdafx.cpp
new file mode 100755
index 0000000..562765b
--- /dev/null
+++ b/host/windows/usb/winusb/stdafx.cpp
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+// stdafx.cpp : source file that includes just the standard includes
+// AdbWinUsbApi.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
diff --git a/host/windows/usb/winusb/stdafx.h b/host/windows/usb/winusb/stdafx.h
new file mode 100755
index 0000000..c2aa8de
--- /dev/null
+++ b/host/windows/usb/winusb/stdafx.h
@@ -0,0 +1,78 @@
+/*
+ * 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
+ Visual Studio generated include file for standard system include files, or
+ project specific include files that are used frequently, but are changed
+ infrequently.
+*/
+
+#pragma once
+
+#ifndef STRICT
+#define STRICT
+#endif
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
+#define WINVER 0x0500 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
+#define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0500 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
+#define _WIN32_IE 0x0501 // Change this to the appropriate value to target IE 5.0 or later.
+#endif
+
+// These defines prevent the MS header files from ejecting #pragma comment
+// statements with the manifest information of the used ATL, STL, and CRT
+#define _ATL_NOFORCE_MANIFEST
+#define _STL_NOFORCE_MANIFEST
+#define _CRT_NOFORCE_MANIFEST
+
+#define _ATL_APARTMENT_THREADED
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+// turns off ATL's hiding of some common and often safely ignored warning messages
+#define _ATL_ALL_WARNINGS
+
+// #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+
+#include <windows.h>
+#pragma warning(disable: 4702)
+#pragma warning(disable: 4201)
+#include <atlbase.h>
+#include <winioctl.h>
+#include <setupapi.h>
+#include <vector>
+#include <map>
+#include <string>
+#pragma warning(default: 4201)
+#pragma warning(disable: 4200)
+#include <winusb.h>
+
+#include "resource.h"
+
+using namespace ATL;