From dceaaa52cec11631c72cfea5fb74ee607602ecde Mon Sep 17 00:00:00 2001 From: vchtchetkine Date: Wed, 22 Jul 2009 13:34:53 -0700 Subject: Refactor ADB API dll to support WinUsb --- host/windows/usb/api/AdbWinApi.cpp | 70 +- host/windows/usb/api/AdbWinApi.def | 10 +- host/windows/usb/api/AdbWinApi.rc | 222 ++--- host/windows/usb/api/AdbWinApi.sln | 21 - host/windows/usb/api/AdbWinApi.vcproj | 290 ------ host/windows/usb/api/MAKEFILE | 22 + host/windows/usb/api/Resource.h | 68 +- host/windows/usb/api/SOURCES | 96 ++ host/windows/usb/api/adb_api.cpp | 1016 ++++++++++----------- host/windows/usb/api/adb_api.h | 1160 +++++++++++++----------- host/windows/usb/api/adb_api_extra.h | 88 -- host/windows/usb/api/adb_api_instance.cpp | 94 +- host/windows/usb/api/adb_api_instance.h | 226 ++--- host/windows/usb/api/adb_api_private_defines.h | 229 +++-- host/windows/usb/api/adb_endpoint_object.cpp | 275 ++++-- host/windows/usb/api/adb_endpoint_object.h | 304 +++++-- host/windows/usb/api/adb_helper_routines.cpp | 437 ++++----- host/windows/usb/api/adb_helper_routines.h | 235 +++-- host/windows/usb/api/adb_interface.cpp | 757 +++++++++------- host/windows/usb/api/adb_interface.h | 502 +++++----- host/windows/usb/api/adb_interface_enum.cpp | 206 ++--- host/windows/usb/api/adb_interface_enum.h | 199 ++-- host/windows/usb/api/adb_io_completion.cpp | 201 ++-- host/windows/usb/api/adb_io_completion.h | 262 +++--- host/windows/usb/api/adb_io_object.cpp | 284 ------ host/windows/usb/api/adb_io_object.h | 238 ----- host/windows/usb/api/adb_object_handle.cpp | 334 +++---- host/windows/usb/api/adb_object_handle.h | 424 +++++---- host/windows/usb/api/stdafx.cpp | 42 +- host/windows/usb/api/stdafx.h | 153 ++-- 30 files changed, 4032 insertions(+), 4433 deletions(-) delete mode 100644 host/windows/usb/api/AdbWinApi.sln delete mode 100644 host/windows/usb/api/AdbWinApi.vcproj create mode 100755 host/windows/usb/api/MAKEFILE create mode 100755 host/windows/usb/api/SOURCES delete mode 100644 host/windows/usb/api/adb_api_extra.h delete mode 100644 host/windows/usb/api/adb_io_object.cpp delete mode 100644 host/windows/usb/api/adb_io_object.h (limited to 'host') diff --git a/host/windows/usb/api/AdbWinApi.cpp b/host/windows/usb/api/AdbWinApi.cpp index c7e530393..4d18d3793 100644 --- a/host/windows/usb/api/AdbWinApi.cpp +++ b/host/windows/usb/api/AdbWinApi.cpp @@ -1,32 +1,38 @@ -/* - * Copyright (C) 2008 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. - */ - -// AdbWinApi.cpp : Implementation of DLL Exports. - -#include "stdafx.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); -} +/* + * Copyright (C) 2008 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. + */ + +// AdbWinApi.cpp : Implementation of DLL Exports. + +#include "stdafx.h" + +extern "C" { +int _forceCRTManifest; +int _forceMFCManifest; +int _forceAtlDllManifest; +}; + +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); +} diff --git a/host/windows/usb/api/AdbWinApi.def b/host/windows/usb/api/AdbWinApi.def index d55786eed..c31f09206 100644 --- a/host/windows/usb/api/AdbWinApi.def +++ b/host/windows/usb/api/AdbWinApi.def @@ -1,5 +1,5 @@ -; AdbWinApi.def : Declares the module parameters. - -LIBRARY "AdbWinApi.DLL" - -EXPORTS +; AdbWinApi.def : Declares the module parameters. + +LIBRARY "AdbWinApi.DLL" + +EXPORTS diff --git a/host/windows/usb/api/AdbWinApi.rc b/host/windows/usb/api/AdbWinApi.rc index 013ea035e..ffc172547 100644 --- a/host/windows/usb/api/AdbWinApi.rc +++ b/host/windows/usb/api/AdbWinApi.rc @@ -1,111 +1,111 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//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 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - 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", "TODO: " - VALUE "FileVersion", "1.0.0.1" - VALUE "LegalCopyright", "Copyright (C) 2006 The Android Open Source Project" - VALUE "InternalName", "AdbWinApi.dll" - VALUE "OriginalFilename", "AdbWinApi.dll" - VALUE "ProductName", "TODO: " - VALUE "ProductVersion", "1.0.0.1" - VALUE "OLESelfRegister", "" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0409, 1252 - END -END - -#endif // !_MAC - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_PROJNAME "AdbWinApi" -END - -//////////////////////////////////////////////////////////////////////////// - - -#endif - -#ifndef APSTUDIO_INVOKED -#endif // not APSTUDIO_INVOKED +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//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 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + 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", "TODO: " + VALUE "FileVersion", "1.0.0.1" + VALUE "LegalCopyright", "Copyright (C) 2006 The Android Open Source Project" + VALUE "InternalName", "AdbWinApi.dll" + VALUE "OriginalFilename", "AdbWinApi.dll" + VALUE "ProductName", "TODO: " + VALUE "ProductVersion", "1.0.0.1" + VALUE "OLESelfRegister", "" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END + +#endif // !_MAC + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_PROJNAME "AdbWinApi" +END + +//////////////////////////////////////////////////////////////////////////// + + +#endif + +#ifndef APSTUDIO_INVOKED +#endif // not APSTUDIO_INVOKED diff --git a/host/windows/usb/api/AdbWinApi.sln b/host/windows/usb/api/AdbWinApi.sln deleted file mode 100644 index f6f4fc047..000000000 --- a/host/windows/usb/api/AdbWinApi.sln +++ /dev/null @@ -1,21 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdbWinApi", "AdbWinApi.vcproj", "{C0A471E9-6892-4270-96DE-DB5F8D526FB1}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {C0A471E9-6892-4270-96DE-DB5F8D526FB1}.Debug.ActiveCfg = Debug|Win32 - {C0A471E9-6892-4270-96DE-DB5F8D526FB1}.Debug.Build.0 = Debug|Win32 - {C0A471E9-6892-4270-96DE-DB5F8D526FB1}.Release.ActiveCfg = Release|Win32 - {C0A471E9-6892-4270-96DE-DB5F8D526FB1}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/host/windows/usb/api/AdbWinApi.vcproj b/host/windows/usb/api/AdbWinApi.vcproj deleted file mode 100644 index c8dfe5509..000000000 --- a/host/windows/usb/api/AdbWinApi.vcproj +++ /dev/null @@ -1,290 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/host/windows/usb/api/MAKEFILE b/host/windows/usb/api/MAKEFILE new file mode 100755 index 000000000..c38c73f14 --- /dev/null +++ b/host/windows/usb/api/MAKEFILE @@ -0,0 +1,22 @@ +# +# Copyright (C) 2006 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# +# 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/api/Resource.h b/host/windows/usb/api/Resource.h index fd2b2f9e5..9a9f194b3 100644 --- a/host/windows/usb/api/Resource.h +++ b/host/windows/usb/api/Resource.h @@ -1,34 +1,34 @@ -/* - * Copyright (C) 2008 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 +/* + * Copyright (C) 2008 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/api/SOURCES b/host/windows/usb/api/SOURCES new file mode 100755 index 000000000..fcca80288 --- /dev/null +++ b/host/windows/usb/api/SOURCES @@ -0,0 +1,96 @@ +# +# Copyright (C) 2006 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +TARGETNAME = AdbWinApi +TARGETPATH = obj +TARGETTYPE = DYNLINK + +UMTYPE = windows +DLLDEF = AdbWinApi.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 + +!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) -DADBWIN_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 AdbWinApi.dll +SOURCES = adb_api.cpp \ + adb_endpoint_object.cpp \ + adb_helper_routines.cpp \ + adb_interface.cpp \ + adb_interface_enum.cpp \ + adb_io_completion.cpp \ + adb_object_handle.cpp \ + AdbWinApi.cpp \ + AdbWinApi.rc diff --git a/host/windows/usb/api/adb_api.cpp b/host/windows/usb/api/adb_api.cpp index 50356c794..eadf07abc 100644 --- a/host/windows/usb/api/adb_api.cpp +++ b/host/windows/usb/api/adb_api.cpp @@ -1,508 +1,508 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - This file consists of implementation of rotines that are exported - from this DLL. -*/ - -#include "stdafx.h" -#include "adb_api.h" -#include "adb_object_handle.h" -#include "adb_interface_enum.h" -#include "adb_interface.h" -#include "adb_endpoint_object.h" -#include "adb_io_completion.h" -#include "adb_helper_routines.h" - -ADBAPIHANDLE AdbEnumInterfaces(GUID class_id, - bool exclude_not_present, - bool exclude_removed, - bool active_only) { - AdbInterfaceEnumObject* enum_obj = NULL; - ADBAPIHANDLE ret = NULL; - - try { - // Instantiate and initialize enum object - enum_obj = new AdbInterfaceEnumObject(); - - if (enum_obj->InitializeEnum(class_id, - exclude_not_present, - exclude_removed, - active_only)) { - // After successful initialization we can create handle. - ret = enum_obj->CreateHandle(); - } - } catch (...) { - SetLastError(ERROR_OUTOFMEMORY); - } - - if (NULL != enum_obj) - enum_obj->Release(); - - return ret; -} - -bool AdbNextInterface(ADBAPIHANDLE adb_handle, - AdbInterfaceInfo* info, - unsigned long* size) { - if (NULL == size) { - SetLastError(ERROR_INVALID_PARAMETER); - return false; - } - - // Lookup AdbInterfaceEnumObject object for the handle - AdbInterfaceEnumObject* adb_ienum_object = - LookupObject(adb_handle); - if (NULL == adb_ienum_object) - return false; - - // Everything is verified. Pass it down to the object - bool ret = adb_ienum_object->Next(info, size); - - adb_ienum_object->Release(); - - return ret; -} - -bool AdbResetInterfaceEnum(ADBAPIHANDLE adb_handle) { - // Lookup AdbInterfaceEnumObject object for the handle - AdbInterfaceEnumObject* adb_ienum_object = - LookupObject(adb_handle); - if (NULL == adb_ienum_object) - return false; - - // Everything is verified. Pass it down to the object - bool ret = adb_ienum_object->Reset(); - - adb_ienum_object->Release(); - - return ret; -} - -ADBWIN_API ADBAPIHANDLE AdbCreateInterfaceByName( - const wchar_t* interface_name) { - AdbInterfaceObject* obj = NULL; - ADBAPIHANDLE ret = NULL; - - try { - // Instantiate object - obj = new AdbInterfaceObject(interface_name); - - // Create handle for it - ret = obj->CreateHandle(); - } catch (...) { - SetLastError(ERROR_OUTOFMEMORY); - } - - if (NULL != obj) - obj->Release(); - - return ret; -} - -ADBAPIHANDLE AdbCreateInterface(GUID class_id, - unsigned short vendor_id, - unsigned short product_id, - unsigned char interface_id) { - // Enumerate all active interfaces for the given class - AdbEnumInterfaceArray interfaces; - - if (!EnumerateDeviceInterfaces(class_id, - DIGCF_DEVICEINTERFACE | DIGCF_PRESENT, - true, - true, - &interfaces)) { - return NULL; - } - - if (interfaces.empty()) { - SetLastError(ERROR_DEVICE_NOT_AVAILABLE); - return NULL; - } - - // Now iterate over active interfaces looking for the name match. - // The name is formatted as such: - // "\\\\?\\usb#vid_xxxx&pid_xxxx&mi_xx#123456789abcdef#{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" - // where - // vid_xxxx is for the vendor id (xxxx are hex for the given vendor id), - // pid_xxxx is for the product id (xxxx are hex for the given product id) - // mi_xx is for the interface id (xx are hex for the given interface id) - // EnumerateDeviceInterfaces will guarantee that returned interface names - // will have our class id at the end of the name (those last XXXes in the - // format). So, we only need to match the beginning of the name - wchar_t match_name[64]; - if (0xFF == interface_id) { - // No interface id for the name. - swprintf(match_name, L"\\\\?\\usb#vid_%04x&pid_%04x#", - vendor_id, product_id); - } else { - // With interface id for the name. - swprintf(match_name, L"\\\\?\\usb#vid_%04x&pid_%04x&mi_%02x#", - vendor_id, product_id, interface_id); - } - size_t match_len = wcslen(match_name); - - for (AdbEnumInterfaceArray::iterator it = interfaces.begin(); - it != interfaces.end(); it++) { - const AdbInstanceEnumEntry& next_interface = *it; - if (0 == wcsnicmp(match_name, - next_interface.device_name().c_str(), - match_len)) { - // Found requested interface among active interfaces. - return AdbCreateInterfaceByName(next_interface.device_name().c_str()); - } - } - - SetLastError(ERROR_DEVICE_NOT_AVAILABLE); - return NULL; -} - -bool AdbGetInterfaceName(ADBAPIHANDLE adb_interface, - void* buffer, - unsigned long* buffer_char_size, - bool ansi) { - // Lookup interface object for the handle - AdbInterfaceObject* adb_object = - LookupObject(adb_interface); - - if (NULL != adb_object) { - // Dispatch call to the found object - bool ret = adb_object->GetInterfaceName(buffer, buffer_char_size, ansi); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } -} - -bool AdbGetSerialNumber(ADBAPIHANDLE adb_interface, - void* buffer, - unsigned long* buffer_char_size, - bool ansi) { - // Lookup interface object for the handle - AdbInterfaceObject* adb_object = - LookupObject(adb_interface); - - if (NULL != adb_object) { - // Dispatch call to the found object - bool ret = adb_object->GetSerialNumber(buffer, buffer_char_size, ansi); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } -} - -bool AdbGetUsbDeviceDescriptor(ADBAPIHANDLE adb_interface, - USB_DEVICE_DESCRIPTOR* desc) { - // Lookup interface object for the handle - AdbInterfaceObject* adb_object = - LookupObject(adb_interface); - - if (NULL != adb_object) { - // Dispatch close to the found object - bool ret = adb_object->GetUsbDeviceDescriptor(desc); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } -} - -bool AdbGetUsbConfigurationDescriptor(ADBAPIHANDLE adb_interface, - USB_CONFIGURATION_DESCRIPTOR* desc) { - // Lookup interface object for the handle - AdbInterfaceObject* adb_object = - LookupObject(adb_interface); - - if (NULL != adb_object) { - // Dispatch close to the found object - bool ret = adb_object->GetUsbConfigurationDescriptor(desc); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } -} - -bool AdbGetUsbInterfaceDescriptor(ADBAPIHANDLE adb_interface, - USB_INTERFACE_DESCRIPTOR* desc) { - // Lookup interface object for the handle - AdbInterfaceObject* adb_object = - LookupObject(adb_interface); - - if (NULL != adb_object) { - // Dispatch close to the found object - bool ret = adb_object->GetUsbInterfaceDescriptor(desc); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } -} - -bool AdbGetEndpointInformation(ADBAPIHANDLE adb_interface, - UCHAR endpoint_index, - AdbEndpointInformation* info) { - // Lookup interface object for the handle - AdbInterfaceObject* adb_object = - LookupObject(adb_interface); - - if (NULL != adb_object) { - // Dispatch close to the found object - bool ret = adb_object->GetEndpointInformation(endpoint_index, info); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } -} - -bool AdbGetDefaultBulkReadEndpointInformation(ADBAPIHANDLE adb_interface, - AdbEndpointInformation* info) { - return AdbGetEndpointInformation(adb_interface, - ADB_QUERY_BULK_READ_ENDPOINT_INDEX, - info); -} - -bool AdbGetDefaultBulkWriteEndpointInformation(ADBAPIHANDLE adb_interface, - AdbEndpointInformation* info) { - return AdbGetEndpointInformation(adb_interface, - ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX, - info); -} - -ADBAPIHANDLE AdbOpenEndpoint(ADBAPIHANDLE adb_interface, - unsigned char endpoint_index, - AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode) { - // Lookup interface object for the handle - AdbInterfaceObject* adb_object = - LookupObject(adb_interface); - - if (NULL != adb_object) { - // Dispatch close to the found object - ADBAPIHANDLE ret = - adb_object->OpenEndpoint(endpoint_index, access_type, sharing_mode); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return NULL; - } -} - -ADBAPIHANDLE AdbOpenDefaultBulkReadEndpoint(ADBAPIHANDLE adb_interface, - AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode) { - return AdbOpenEndpoint(adb_interface, - ADB_QUERY_BULK_READ_ENDPOINT_INDEX, - access_type, - sharing_mode); -} - -ADBAPIHANDLE AdbOpenDefaultBulkWriteEndpoint(ADBAPIHANDLE adb_interface, - AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode) { - return AdbOpenEndpoint(adb_interface, - ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX, - access_type, - sharing_mode); -} - -ADBAPIHANDLE AdbGetEndpointInterface(ADBAPIHANDLE adb_endpoint) { - // Lookup endpoint object for the handle - AdbEndpointObject* adb_object = - LookupObject(adb_endpoint); - - if (NULL != adb_object) { - // Dispatch the call to the found object - ADBAPIHANDLE ret = adb_object->GetParentInterfaceHandle(); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return NULL; - } -} - -bool AdbQueryInformationEndpoint(ADBAPIHANDLE adb_endpoint, - AdbEndpointInformation* info) { - // Lookup endpoint object for the handle - AdbEndpointObject* adb_object = - LookupObject(adb_endpoint); - - if (NULL != adb_object) { - // Dispatch the call to the found object - bool ret = adb_object->GetEndpointInformation(info); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } -} - -ADBAPIHANDLE AdbReadEndpointAsync(ADBAPIHANDLE adb_endpoint, - void* buffer, - unsigned long bytes_to_read, - unsigned long* bytes_read, - unsigned long time_out, - HANDLE event_handle) { - // Lookup endpoint object for the handle - AdbEndpointObject* adb_object = - LookupObject(adb_endpoint); - - if (NULL != adb_object) { - // Dispatch the call to the found object - ADBAPIHANDLE ret = adb_object->AsyncRead(buffer, - bytes_to_read, - bytes_read, - event_handle, - time_out); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return NULL; - } -} - -ADBAPIHANDLE AdbWriteEndpointAsync(ADBAPIHANDLE adb_endpoint, - void* buffer, - unsigned long bytes_to_write, - unsigned long* bytes_written, - unsigned long time_out, - HANDLE event_handle) { - // Lookup endpoint object for the handle - AdbEndpointObject* adb_object = - LookupObject(adb_endpoint); - - if (NULL != adb_object) { - // Dispatch the call to the found object - ADBAPIHANDLE ret = adb_object->AsyncWrite(buffer, - bytes_to_write, - bytes_written, - event_handle, - time_out); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } -} - -bool AdbReadEndpointSync(ADBAPIHANDLE adb_endpoint, - void* buffer, - unsigned long bytes_to_read, - unsigned long* bytes_read, - unsigned long time_out) { - // Lookup endpoint object for the handle - AdbEndpointObject* adb_object = - LookupObject(adb_endpoint); - - if (NULL != adb_object) { - // Dispatch the call to the found object - bool ret = - adb_object->SyncRead(buffer, bytes_to_read, bytes_read, time_out); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return NULL; - } -} - -bool AdbWriteEndpointSync(ADBAPIHANDLE adb_endpoint, - void* buffer, - unsigned long bytes_to_write, - unsigned long* bytes_written, - unsigned long time_out) { - // Lookup endpoint object for the handle - AdbEndpointObject* adb_object = - LookupObject(adb_endpoint); - - if (NULL != adb_object) { - // Dispatch the call to the found object - bool ret = - adb_object->SyncWrite(buffer, bytes_to_write, bytes_written, time_out); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } -} - -bool AdbGetOvelappedIoResult(ADBAPIHANDLE adb_io_completion, - LPOVERLAPPED overlapped, - unsigned long* bytes_transferred, - bool wait) { - // Lookup endpoint object for the handle - AdbIOCompletion* adb_object = - LookupObject(adb_io_completion); - - if (NULL != adb_object) { - // Dispatch the call to the found object - bool ret = - adb_object->GetOvelappedIoResult(overlapped, bytes_transferred, wait); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } -} - -bool AdbHasOvelappedIoComplated(ADBAPIHANDLE adb_io_completion) { - // Lookup endpoint object for the handle - AdbIOCompletion* adb_object = - LookupObject(adb_io_completion); - - if (NULL != adb_object) { - // Dispatch the call to the found object - bool ret = - adb_object->IsCompleted(); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return true; - } -} - -bool AdbCloseHandle(ADBAPIHANDLE adb_handle) { - // Lookup object for the handle - AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle); - - if (NULL != adb_object) { - // Dispatch close to the found object - bool ret = adb_object->CloseHandle(); - adb_object->Release(); - return ret; - } else { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } -} +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \file + This file consists of implementation of rotines that are exported + from this DLL. +*/ + +#include "stdafx.h" +#include "adb_api.h" +#include "adb_object_handle.h" +#include "adb_interface_enum.h" +#include "adb_interface.h" +#include "adb_endpoint_object.h" +#include "adb_io_completion.h" +#include "adb_helper_routines.h" + +ADBAPIHANDLE __cdecl AdbEnumInterfaces(GUID class_id, + bool exclude_not_present, + bool exclude_removed, + bool active_only) { + AdbInterfaceEnumObject* enum_obj = NULL; + ADBAPIHANDLE ret = NULL; + + try { + // Instantiate and initialize enum object + enum_obj = new AdbInterfaceEnumObject(); + + if (enum_obj->InitializeEnum(class_id, + exclude_not_present, + exclude_removed, + active_only)) { + // After successful initialization we can create handle. + ret = enum_obj->CreateHandle(); + } + } catch (...) { + SetLastError(ERROR_OUTOFMEMORY); + } + + if (NULL != enum_obj) + enum_obj->Release(); + + return ret; +} + +bool __cdecl AdbNextInterface(ADBAPIHANDLE adb_handle, + AdbInterfaceInfo* info, + unsigned long* size) { + if (NULL == size) { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // Lookup AdbInterfaceEnumObject object for the handle + AdbInterfaceEnumObject* adb_ienum_object = + LookupObject(adb_handle); + if (NULL == adb_ienum_object) + return false; + + // Everything is verified. Pass it down to the object + bool ret = adb_ienum_object->Next(info, size); + + adb_ienum_object->Release(); + + return ret; +} + +bool __cdecl AdbResetInterfaceEnum(ADBAPIHANDLE adb_handle) { + // Lookup AdbInterfaceEnumObject object for the handle + AdbInterfaceEnumObject* adb_ienum_object = + LookupObject(adb_handle); + if (NULL == adb_ienum_object) + return false; + + // Everything is verified. Pass it down to the object + bool ret = adb_ienum_object->Reset(); + + adb_ienum_object->Release(); + + return ret; +} + +ADBAPIHANDLE __cdecl AdbCreateInterfaceByName( + const wchar_t* interface_name) { + AdbInterfaceObject* obj = NULL; + ADBAPIHANDLE ret = NULL; + + try { + // Instantiate object + obj = new AdbInterfaceObject(interface_name); + + // Create handle for it + ret = obj->CreateHandle(); + } catch (...) { + SetLastError(ERROR_OUTOFMEMORY); + } + + if (NULL != obj) + obj->Release(); + + return ret; +} + +ADBAPIHANDLE __cdecl AdbCreateInterface(GUID class_id, + unsigned short vendor_id, + unsigned short product_id, + unsigned char interface_id) { + // Enumerate all active interfaces for the given class + AdbEnumInterfaceArray interfaces; + + if (!EnumerateDeviceInterfaces(class_id, + DIGCF_DEVICEINTERFACE | DIGCF_PRESENT, + true, + true, + &interfaces)) { + return NULL; + } + + if (interfaces.empty()) { + SetLastError(ERROR_DEVICE_NOT_AVAILABLE); + return NULL; + } + + // Now iterate over active interfaces looking for the name match. + // The name is formatted as such: + // "\\\\?\\usb#vid_xxxx&pid_xxxx&mi_xx#123456789abcdef#{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" + // where + // vid_xxxx is for the vendor id (xxxx are hex for the given vendor id), + // pid_xxxx is for the product id (xxxx are hex for the given product id) + // mi_xx is for the interface id (xx are hex for the given interface id) + // EnumerateDeviceInterfaces will guarantee that returned interface names + // will have our class id at the end of the name (those last XXXes in the + // format). So, we only need to match the beginning of the name + wchar_t match_name[64]; + if (0xFF == interface_id) { + // No interface id for the name. + swprintf(match_name, L"\\\\?\\usb#vid_%04x&pid_%04x#", + vendor_id, product_id); + } else { + // With interface id for the name. + swprintf(match_name, L"\\\\?\\usb#vid_%04x&pid_%04x&mi_%02x#", + vendor_id, product_id, interface_id); + } + size_t match_len = wcslen(match_name); + + for (AdbEnumInterfaceArray::iterator it = interfaces.begin(); + it != interfaces.end(); it++) { + const AdbInstanceEnumEntry& next_interface = *it; + if (0 == _wcsnicmp(match_name, + next_interface.device_name().c_str(), + match_len)) { + // Found requested interface among active interfaces. + return AdbCreateInterfaceByName(next_interface.device_name().c_str()); + } + } + + SetLastError(ERROR_DEVICE_NOT_AVAILABLE); + return NULL; +} + +bool __cdecl AdbGetInterfaceName(ADBAPIHANDLE adb_interface, + void* buffer, + unsigned long* buffer_char_size, + bool ansi) { + // Lookup interface object for the handle + AdbInterfaceObject* adb_object = + LookupObject(adb_interface); + + if (NULL != adb_object) { + // Dispatch call to the found object + bool ret = adb_object->GetInterfaceName(buffer, buffer_char_size, ansi); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } +} + +bool __cdecl AdbGetSerialNumber(ADBAPIHANDLE adb_interface, + void* buffer, + unsigned long* buffer_char_size, + bool ansi) { + // Lookup interface object for the handle + AdbInterfaceObject* adb_object = + LookupObject(adb_interface); + + if (NULL != adb_object) { + // Dispatch call to the found object + bool ret = adb_object->GetSerialNumber(buffer, buffer_char_size, ansi); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } +} + +bool __cdecl AdbGetUsbDeviceDescriptor(ADBAPIHANDLE adb_interface, + USB_DEVICE_DESCRIPTOR* desc) { + // Lookup interface object for the handle + AdbInterfaceObject* adb_object = + LookupObject(adb_interface); + + if (NULL != adb_object) { + // Dispatch close to the found object + bool ret = adb_object->GetUsbDeviceDescriptor(desc); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } +} + +bool __cdecl AdbGetUsbConfigurationDescriptor(ADBAPIHANDLE adb_interface, + USB_CONFIGURATION_DESCRIPTOR* desc) { + // Lookup interface object for the handle + AdbInterfaceObject* adb_object = + LookupObject(adb_interface); + + if (NULL != adb_object) { + // Dispatch close to the found object + bool ret = adb_object->GetUsbConfigurationDescriptor(desc); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } +} + +bool __cdecl AdbGetUsbInterfaceDescriptor(ADBAPIHANDLE adb_interface, + USB_INTERFACE_DESCRIPTOR* desc) { + // Lookup interface object for the handle + AdbInterfaceObject* adb_object = + LookupObject(adb_interface); + + if (NULL != adb_object) { + // Dispatch close to the found object + bool ret = adb_object->GetUsbInterfaceDescriptor(desc); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } +} + +bool __cdecl AdbGetEndpointInformation(ADBAPIHANDLE adb_interface, + UCHAR endpoint_index, + AdbEndpointInformation* info) { + // Lookup interface object for the handle + AdbInterfaceObject* adb_object = + LookupObject(adb_interface); + + if (NULL != adb_object) { + // Dispatch close to the found object + bool ret = adb_object->GetEndpointInformation(endpoint_index, info); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } +} + +bool __cdecl AdbGetDefaultBulkReadEndpointInformation(ADBAPIHANDLE adb_interface, + AdbEndpointInformation* info) { + return AdbGetEndpointInformation(adb_interface, + ADB_QUERY_BULK_READ_ENDPOINT_INDEX, + info); +} + +bool __cdecl AdbGetDefaultBulkWriteEndpointInformation(ADBAPIHANDLE adb_interface, + AdbEndpointInformation* info) { + return AdbGetEndpointInformation(adb_interface, + ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX, + info); +} + +ADBAPIHANDLE __cdecl AdbOpenEndpoint(ADBAPIHANDLE adb_interface, + unsigned char endpoint_index, + AdbOpenAccessType access_type, + AdbOpenSharingMode sharing_mode) { + // Lookup interface object for the handle + AdbInterfaceObject* adb_object = + LookupObject(adb_interface); + + if (NULL != adb_object) { + // Dispatch close to the found object + ADBAPIHANDLE ret = + adb_object->OpenEndpoint(endpoint_index, access_type, sharing_mode); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } +} + +ADBAPIHANDLE __cdecl AdbOpenDefaultBulkReadEndpoint(ADBAPIHANDLE adb_interface, + AdbOpenAccessType access_type, + AdbOpenSharingMode sharing_mode) { + return AdbOpenEndpoint(adb_interface, + ADB_QUERY_BULK_READ_ENDPOINT_INDEX, + access_type, + sharing_mode); +} + +ADBAPIHANDLE __cdecl AdbOpenDefaultBulkWriteEndpoint(ADBAPIHANDLE adb_interface, + AdbOpenAccessType access_type, + AdbOpenSharingMode sharing_mode) { + return AdbOpenEndpoint(adb_interface, + ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX, + access_type, + sharing_mode); +} + +ADBAPIHANDLE __cdecl AdbGetEndpointInterface(ADBAPIHANDLE adb_endpoint) { + // Lookup endpoint object for the handle + AdbEndpointObject* adb_object = + LookupObject(adb_endpoint); + + if (NULL != adb_object) { + // Dispatch the call to the found object + ADBAPIHANDLE ret = adb_object->GetParentInterfaceHandle(); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } +} + +bool __cdecl AdbQueryInformationEndpoint(ADBAPIHANDLE adb_endpoint, + AdbEndpointInformation* info) { + // Lookup endpoint object for the handle + AdbEndpointObject* adb_object = + LookupObject(adb_endpoint); + + if (NULL != adb_object) { + // Dispatch the call to the found object + bool ret = adb_object->GetEndpointInformation(info); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } +} + +ADBAPIHANDLE __cdecl AdbReadEndpointAsync(ADBAPIHANDLE adb_endpoint, + void* buffer, + unsigned long bytes_to_read, + unsigned long* bytes_read, + unsigned long time_out, + HANDLE event_handle) { + // Lookup endpoint object for the handle + AdbEndpointObject* adb_object = + LookupObject(adb_endpoint); + + if (NULL != adb_object) { + // Dispatch the call to the found object + ADBAPIHANDLE ret = adb_object->AsyncRead(buffer, + bytes_to_read, + bytes_read, + event_handle, + time_out); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } +} + +ADBAPIHANDLE __cdecl AdbWriteEndpointAsync(ADBAPIHANDLE adb_endpoint, + void* buffer, + unsigned long bytes_to_write, + unsigned long* bytes_written, + unsigned long time_out, + HANDLE event_handle) { + // Lookup endpoint object for the handle + AdbEndpointObject* adb_object = + LookupObject(adb_endpoint); + + if (NULL != adb_object) { + // Dispatch the call to the found object + ADBAPIHANDLE ret = adb_object->AsyncWrite(buffer, + bytes_to_write, + bytes_written, + event_handle, + time_out); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } +} + +bool __cdecl AdbReadEndpointSync(ADBAPIHANDLE adb_endpoint, + void* buffer, + unsigned long bytes_to_read, + unsigned long* bytes_read, + unsigned long time_out) { + // Lookup endpoint object for the handle + AdbEndpointObject* adb_object = + LookupObject(adb_endpoint); + + if (NULL != adb_object) { + // Dispatch the call to the found object + bool ret = + adb_object->SyncRead(buffer, bytes_to_read, bytes_read, time_out); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } +} + +bool __cdecl AdbWriteEndpointSync(ADBAPIHANDLE adb_endpoint, + void* buffer, + unsigned long bytes_to_write, + unsigned long* bytes_written, + unsigned long time_out) { + // Lookup endpoint object for the handle + AdbEndpointObject* adb_object = + LookupObject(adb_endpoint); + + if (NULL != adb_object) { + // Dispatch the call to the found object + bool ret = + adb_object->SyncWrite(buffer, bytes_to_write, bytes_written, time_out); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } +} + +bool __cdecl AdbGetOvelappedIoResult(ADBAPIHANDLE adb_io_completion, + LPOVERLAPPED overlapped, + unsigned long* bytes_transferred, + bool wait) { + // Lookup endpoint object for the handle + AdbIOCompletion* adb_object = + LookupObject(adb_io_completion); + + if (NULL != adb_object) { + // Dispatch the call to the found object + bool ret = + adb_object->GetOvelappedIoResult(overlapped, bytes_transferred, wait); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } +} + +bool __cdecl AdbHasOvelappedIoComplated(ADBAPIHANDLE adb_io_completion) { + // Lookup endpoint object for the handle + AdbIOCompletion* adb_object = + LookupObject(adb_io_completion); + + if (NULL != adb_object) { + // Dispatch the call to the found object + bool ret = + adb_object->IsCompleted(); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return true; + } +} + +bool __cdecl AdbCloseHandle(ADBAPIHANDLE adb_handle) { + // Lookup object for the handle + AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle); + + if (NULL != adb_object) { + // Dispatch close to the found object + bool ret = adb_object->CloseHandle(); + adb_object->Release(); + return ret; + } else { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } +} diff --git a/host/windows/usb/api/adb_api.h b/host/windows/usb/api/adb_api.h index 98a32dcbe..e503238da 100644 --- a/host/windows/usb/api/adb_api.h +++ b/host/windows/usb/api/adb_api.h @@ -1,541 +1,619 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_USB_API_ADBWINAPI_H__ -#define ANDROID_USB_API_ADBWINAPI_H__ -/** \file - This file consists of declarations of routines exported by the API as well - as types, structures, and constants definitions used in the API. - Declarations in this file, combined with definitions found in adb_api_extra.h - comprise ADB API for windows. -*/ - -#include "adb_api_extra.h" - -// Enables compillation for "straight" C -#ifdef __cplusplus - #define EXTERN_C extern "C" -#else - #define EXTERN_C extern - typedef int bool; - #define true 1 - #define false 0 -#endif - -// 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 -// not be defined on any project that uses this DLL. This way any other project -// whose source files include this file see ADBWIN_API functions as being -// imported from a DLL, whereas this DLL sees symbols defined with this macro -// as being exported. -#ifdef ADBWIN_EXPORTS -#define ADBWIN_API EXTERN_C __declspec(dllexport) -#else -#define ADBWIN_API EXTERN_C __declspec(dllimport) -#endif - -/** Handle to an API object - - To access USB interface and its components clients must first obtain a - handle to the required object. API Objects that are represented by a - handle are: - 1. Interface enumerator that provides access to a list of interfaces that - match certain criterias that were specified when interface enumerator - has been created. This handle is created in AdbEnumInterfaces routine. - 2. Interface that is the major object this API deals with. In Windows - model of the USB stack each USB device (that is physical device, - attached to a USB port) exposes one or more interfaces that become the - major entities through which that device gets accessed. Each of these - interfaces are represented as Windows Device Objects on the USB stack. - So, to this extent, at least as this API is concerned, terms "interface" - and "device" are interchangeable, since each interface is represented by - a device object on the Windows USB stack. This handle is created in - either AdbCreateInterface or AdbCreateInterfaceByName routines. - 3. Endpoint object (also called a pipe) represents an endpoint on interface - through which all I/O operations are performed. This handle is created in - one of these routines: AdbOpenEndpoint, AdbOpenDefaultBulkReadEndpoint, - or AdbOpenDefaultBulkWriteEndpoint. - 4. I/O completion object that tracks completion information of asynchronous - I/O performed on an endpoint. When an endpoint object gets opened through - this API it is opened for asynchronous (or overlapped) I/O. And each time - an asynchronous I/O is performed by this API an I/O completion object is - created to track the result of that I/O when it gets completed. Clients - of the API can then use a handle to I/O completion object to query for - the status and result of asynchronous I/O as well as wait for this I/O - completion. This handle is created in one of these routines: - AdbReadEndpointAsync, or AdbWriteEndpointAsync. - After object is no longer needed by the client, its handle must be closed - using AdbCloseHandle routine. -*/ -typedef void* ADBAPIHANDLE; - -/** Enumeration AdbOpenAccessType defines access type with which - an I/O object (endpoint) should be opened. -*/ -typedef enum _AdbOpenAccessType { - /// Opens for read and write access - AdbOpenAccessTypeReadWrite, - - /// Opens for read only access - AdbOpenAccessTypeRead, - - /// Opens for write only access - AdbOpenAccessTypeWrite, - - /// Opens for querying information - AdbOpenAccessTypeQueryInfo, -} AdbOpenAccessType; - -/** Enumeration AdbOpenSharingMode defines sharing mode with which - an I/O object (endpoint) should be opened. -*/ -typedef enum _AdbOpenSharingMode { - /// Shares read and write - AdbOpenSharingModeReadWrite, - - /// Shares only read - AdbOpenSharingModeRead, - - /// Shares only write - AdbOpenSharingModeWrite, - - /// Opens exclusive - AdbOpenSharingModeExclusive, -} AdbOpenSharingMode; - -/** Structure AdbInterfaceInfo provides information about an interface -*/ -typedef struct _AdbInterfaceInfo { - /// Inteface's class id (see SP_DEVICE_INTERFACE_DATA for details) - GUID class_id; - - /// Interface flags (see SP_DEVICE_INTERFACE_DATA for details) - unsigned long flags; - - /// Device name for the interface (see SP_DEVICE_INTERFACE_DETAIL_DATA - /// for details) - wchar_t device_name[1]; -} AdbInterfaceInfo; - -/** \brief Creates USB interface enumerator - - This routine enumerates all USB interfaces that match provided class ID. - This routine uses SetupDiGetClassDevs SDK routine to enumerate devices that - match class ID and then SetupDiEnumDeviceInterfaces SDK routine is called - to enumerate interfaces on the devices. - @param class_id[in] Device class ID, assigned by the driver. - @param exclude_not_present[in] If 'true' enumation will include only those - devices that are currently present. - @param exclude_removed[in] If 'true' interfaces with SPINT_REMOVED flag set - will be not included in the enumeration. - @param active_only[in] If 'true' only active interfaces (with flag - SPINT_ACTIVE set) will be included in the enumeration. - @return Handle to the enumerator object or NULL on failure. If NULL is - returned GetLastError() provides extended error information. -*/ -ADBWIN_API ADBAPIHANDLE AdbEnumInterfaces(GUID class_id, - bool exclude_not_present, - bool exclude_removed, - bool active_only); - -/** \brief Gets next interface information - - @param adb_handle[in] Handle to interface enumerator object obtained via - AdbEnumInterfaces call. - @param info[out] Upon successful completion will receive interface - information. Can be NULL. If it is NULL, upon return from this - routine size parameter will contain memory size required for the - next entry. - @param size[in,out]. On the way in provides size of the memory buffer - addressed by info parameter. On the way out (only if buffer was not - big enough) will provide memory size required for the next entry. - @return true on success, false on error. If false is returned - GetLastError() provides extended error information. - ERROR_INSUFFICIENT_BUFFER indicates that buffer provided in info - parameter was not big enough and size parameter contains memory size - required for the next entry. ERROR_NO_MORE_ITEMS indicates that - enumeration is over and there are no more entries to return. -*/ -ADBWIN_API bool AdbNextInterface(ADBAPIHANDLE adb_handle, - AdbInterfaceInfo* info, - unsigned long* size); - -/** \brief Resets enumerator so next call to AdbNextInterface will start - from the beginning. - - @param adb_handle[in] Handle to interface enumerator object obtained via - AdbEnumInterfaces call. - @return true on success, false on error. If false is returned GetLastError() - provides extended error information. -*/ -ADBWIN_API bool AdbResetInterfaceEnum(ADBAPIHANDLE adb_handle); - -/** \brief Creates USB interface object - - This routine creates an object that represents a USB interface. - @param interface_name[in] Name of the interface. - @return Handle to the interface object or NULL on failure. If NULL is - returned GetLastError() provides extended error information. -*/ -ADBWIN_API ADBAPIHANDLE AdbCreateInterfaceByName(const wchar_t* interface_name); - -/** \brief - Creates USB interface object based on vendor, product and interface IDs. - - This routine creates and object that represents a USB interface on our - device. It uses AdbCreateInterfaceByName to actually do the create. - @param class_id[in] Device class ID, assigned by the driver. - @param vendor_id[in] Device vendor ID - @param product_id[in] Device product ID - @param interface_id[in] Device interface ID. This parameter is optional. - Value 0xFF indicates that interface should be addressed by vendor - and product IDs only. - @return Handle to the interface object or NULL on failure. If NULL is - returned GetLastError() provides extended error information. -*/ -ADBWIN_API ADBAPIHANDLE AdbCreateInterface(GUID class_id, - unsigned short vendor_id, - unsigned short product_id, - unsigned char interface_id); - -/** \brief Gets interface name. - - @param adb_interface[in] A handle to interface object created with - AdbCreateInterface call. - @param buffer[out] Buffer for the name. Can be NULL in which case - buffer_char_size will contain number of characters required for - the name. - @param buffer_char_size[in/out] 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 ansi[in] 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. -*/ -ADBWIN_API bool AdbGetInterfaceName(ADBAPIHANDLE adb_interface, - void* buffer, - unsigned long* buffer_char_size, - bool ansi); - -/** \brief Gets serial number for interface's device. - - @param adb_interface[in] A handle to interface object created with - AdbCreateInterface call. - @param buffer[out] 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 buffer_char_size[in/out] 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 ansi[in] 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. -*/ -ADBWIN_API bool AdbGetSerialNumber(ADBAPIHANDLE adb_interface, - void* buffer, - unsigned long* buffer_char_size, - bool ansi); - -/** \brief Gets device descriptor for the USB device associated with - the given interface. - - @param adb_interface[in] A handle to interface object created with - AdbCreateInterface call. - @param desc[out] Upon successful completion will have usb device - descriptor. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. -*/ -ADBWIN_API bool AdbGetUsbDeviceDescriptor(ADBAPIHANDLE adb_interface, - USB_DEVICE_DESCRIPTOR* desc); - -/** \brief Gets descriptor for the selected USB device configuration. - - @param adb_interface[in] A handle to interface object created with - AdbCreateInterface call. - @param desc[out] Upon successful completion will have usb device - configuration descriptor. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. -*/ -ADBWIN_API bool AdbGetUsbConfigurationDescriptor(ADBAPIHANDLE adb_interface, - USB_CONFIGURATION_DESCRIPTOR* desc); - -/** \brief Gets descriptor for the given interface. - - @param adb_interface[in] A handle to interface object created with - AdbCreateInterface call. - @param desc[out] Upon successful completion will have usb device - configuration descriptor. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. -*/ -ADBWIN_API bool AdbGetUsbInterfaceDescriptor(ADBAPIHANDLE adb_interface, - USB_INTERFACE_DESCRIPTOR* desc); - -/** \brief Gets information about an endpoint on the given interface. - - @param adb_interface[in] A handle to interface object created with - AdbCreateInterface call. - @param endpoint_index[in] 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 information - about bulk write and bulk read endpoints respectively. - @param info[out] Upon successful completion will have endpoint information. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. -*/ -ADBWIN_API bool AdbGetEndpointInformation(ADBAPIHANDLE adb_interface, - unsigned char endpoint_index, - AdbEndpointInformation* info); - -/** \brief - Gets information about default bulk read endpoint on the given interface. - - @param adb_interface[in] A handle to interface object created with - AdbCreateInterface call. - @param info[out] Upon successful completion will have endpoint information. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. -*/ -ADBWIN_API bool AdbGetDefaultBulkReadEndpointInformation(ADBAPIHANDLE adb_interface, - AdbEndpointInformation* info); - -/** \brief - Gets information about default bulk write endpoint on the given interface. - - @param adb_interface[in] A handle to interface object created with - AdbCreateInterface call. - @param info[out] Upon successful completion will have endpoint information. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. -*/ -ADBWIN_API bool AdbGetDefaultBulkWriteEndpointInformation(ADBAPIHANDLE adb_interface, - AdbEndpointInformation* info); - -/** \brief Opens an endpoint on the given interface. - - Endpoints are always opened for overlapped I/O. - @param adb_interface[in] A handle to interface object created with - AdbCreateInterface call. - @param endpoint_index[in] 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 information - about bulk write and bulk read endpoints respectively. - @param access_type[in] 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 sharing_mode[in] 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 error information. -*/ -ADBWIN_API ADBAPIHANDLE AdbOpenEndpoint(ADBAPIHANDLE adb_interface, - unsigned char endpoint_index, - AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode); - -/** \brief Opens default bulk read endpoint on the given interface. - - Endpoints are always opened for overlapped I/O. - @param adb_interface[in] A handle to interface object created with - AdbCreateInterface call. - @param access_type[in] 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 sharing_mode[in] 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 error information. -*/ -ADBWIN_API ADBAPIHANDLE AdbOpenDefaultBulkReadEndpoint(ADBAPIHANDLE adb_interface, - AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode); - -/** \brief Opens default bulk write endpoint on the given interface. - - Endpoints are always opened for overlapped I/O. - @param adb_interface[in] A handle to interface object created with - AdbCreateInterface call. - @param access_type[in] 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 sharing_mode[in] 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 error information. -*/ -ADBWIN_API ADBAPIHANDLE AdbOpenDefaultBulkWriteEndpoint(ADBAPIHANDLE adb_interface, - AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode); - -/** \brief Gets handle to interface object for the given endpoint - - @param adb_endpoint[in] A handle to opened endpoint object, obtained via one - of the AdbOpenXxxEndpoint calls. - @return Handle to the interface for this endpoint or NULL on failure. If NULL - is returned GetLastError() provides extended error information. -*/ -ADBWIN_API ADBAPIHANDLE AdbGetEndpointInterface(ADBAPIHANDLE adb_endpoint); - -/** \brief Gets information about the given endpoint. - - @param adb_endpoint[in] A handle to opened endpoint object, obtained via one - of the AdbOpenXxxEndpoint calls. - @param info[out] Upon successful completion will have endpoint information. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. -*/ -ADBWIN_API bool AdbQueryInformationEndpoint(ADBAPIHANDLE adb_endpoint, - AdbEndpointInformation* info); - -/** \brief Asynchronously reads from the given endpoint. - - @param adb_endpoint[in] A handle to opened endpoint object, obtained via one - of the AdbOpenXxxEndpoint calls. - @param buffer[out] Pointer to the buffer that receives the data. - @param bytes_to_read[in] Number of bytes to be read. - @param bytes_read[out] Number of bytes read. Can be NULL. - @param event_handle[in] 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 time_out[in] A timeout (in milliseconds) required for this I/O to - complete. Zero value for this parameter means that there is no - timeout for this I/O. - @return A handle to IO completion object or NULL on failure. If NULL is - returned GetLastError() provides extended error information. -*/ -ADBWIN_API ADBAPIHANDLE AdbReadEndpointAsync(ADBAPIHANDLE adb_endpoint, - void* buffer, - unsigned long bytes_to_read, - unsigned long* bytes_read, - unsigned long time_out, - HANDLE event_handle); - -/** \brief Asynchronously writes to the given endpoint. - - @param adb_endpoint[in] A handle to opened endpoint object, obtained via one - of the AdbOpenXxxEndpoint calls. - @param buffer[in] Pointer to the buffer containing the data to be written. - @param bytes_to_write[in] Number of bytes to be written. - @param bytes_written[out] Number of bytes written. Can be NULL. - @param event_handle[in] 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 time_out[in] A timeout (in milliseconds) required for this I/O to - complete. Zero value for this parameter means that there is no - timeout for this I/O. - @return A handle to IO completion object or NULL on failure. If NULL is - returned GetLastError() provides extended error information. -*/ -ADBWIN_API ADBAPIHANDLE AdbWriteEndpointAsync(ADBAPIHANDLE adb_endpoint, - void* buffer, - unsigned long bytes_to_write, - unsigned long* bytes_written, - unsigned long time_out, - HANDLE event_handle); - -/** \brief Synchronously reads from the given endpoint. - - @param adb_endpoint[in] A handle to opened endpoint object, obtained via one - of the AdbOpenXxxEndpoint calls. - @param buffer[out] Pointer to the buffer that receives the data. - @param bytes_to_read[in] Number of bytes to be read. - @param bytes_read[out] Number of bytes read. Can be NULL. - @param time_out[in] A timeout (in milliseconds) required for this I/O to - complete. Zero value for this parameter means that there is no - timeout for this I/O. - @return 'true' on success and 'false' on failure. If 'false' is - returned GetLastError() provides extended error information. -*/ -ADBWIN_API bool AdbReadEndpointSync(ADBAPIHANDLE adb_endpoint, - void* buffer, - unsigned long bytes_to_read, - unsigned long* bytes_read, - unsigned long time_out); - -/** \brief Synchronously writes to the given endpoint. - - @param adb_endpoint[in] A handle to opened endpoint object, obtained via one - of the AdbOpenXxxEndpoint calls. - @param buffer[in] Pointer to the buffer containing the data to be written. - @param bytes_to_write[in] Number of bytes to be written. - @param bytes_written[out] Number of bytes written. Can be NULL. - @param time_out[in] A timeout (in milliseconds) required for this I/O to - complete. Zero value for this parameter means that there is no - timeout for this I/O. - @return 'true' on success and 'false' on failure. If 'false' is - returned GetLastError() provides extended error information. -*/ -ADBWIN_API bool AdbWriteEndpointSync(ADBAPIHANDLE adb_endpoint, - void* buffer, - unsigned long bytes_to_write, - unsigned long* bytes_written, - unsigned long time_out); - -/** \brief Gets overlapped I/O result for async I/O performed on the - given endpoint - - @param adb_io_completion[in] A handle to an I/O completion object returned - from AdbRead/WriteAsync routines. - @param ovl_data[out] Buffer for the copy of this object's OVERLAPPED - structure. Can be NULL. - @param bytes_transferred[out] 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 wait[in] 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. -*/ -ADBWIN_API bool AdbGetOvelappedIoResult(ADBAPIHANDLE adb_io_completion, - LPOVERLAPPED overlapped, - unsigned long* bytes_transferred, - bool wait); - -/** \brief Checks if overlapped I/O has been completed. - - @param adb_io_completion[in] A handle to an I/O completion object returned - from AdbRead/WriteAsync routines. - @return 'true' if I/O has been completed or 'false' if it's still - incomplete. Regardless of the returned value, caller should - check GetLastError to validate that handle was OK. -*/ -ADBWIN_API bool AdbHasOvelappedIoComplated(ADBAPIHANDLE adb_io_completion); - -/** \brief Closes handle previously opened with one of the API calls - - @param adb_handle[in] ADB handle previously opened with one of the API calls - @return 'true' on success or 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. -*/ -ADBWIN_API bool AdbCloseHandle(ADBAPIHANDLE adb_handle); - - -#endif // ANDROID_USB_API_ADBWINAPI_H__ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_USB_API_ADBWINAPI_H__ +#define ANDROID_USB_API_ADBWINAPI_H__ +/** \file + This file consists of declarations of routines exported by the API as well + as types, structures, and constants definitions used in the API. +*/ + +// Enables compillation for "straight" C +#ifdef __cplusplus + #define EXTERN_C extern "C" +#else + #define EXTERN_C extern + typedef int bool; + #define true 1 + #define false 0 +#endif + +/** \brief Enumerates ADB endpoint types. + + This enum is taken from WDF_USB_PIPE_TYPE enum found in WDK. +*/ +typedef enum _AdbEndpointType { + /// Unknown (invalid, or not initialized) endpoint type. + AdbEndpointTypeInvalid = 0, + + /// Endpoint is device control pipe. + AdbEndpointTypeControl, + + /// Endpoint is isochronous r/w pipe. + AdbEndpointTypeIsochronous, + + /// Endpoint is a bulk r/w pipe. + AdbEndpointTypeBulk, + + /// Endpoint is an interrupt r/w pipe. + AdbEndpointTypeInterrupt, +} AdbEndpointType; + +/** \brief Endpoint desriptor. + + This structure is based on WDF_USB_PIPE_INFORMATION structure found in WDK. +*/ +typedef struct _AdbEndpointInformation { + /// Maximum packet size this endpoint is capable of. + unsigned long max_packet_size; + + /// Maximum size of one transfer which should be sent to the host controller. + unsigned long max_transfer_size; + + /// ADB endpoint type. + AdbEndpointType endpoint_type; + + /// Raw endpoint address on the device as described by its descriptor. + unsigned char endpoint_address; + + /// Polling interval. + unsigned char polling_interval; + + /// Which alternate setting this structure is relevant for. + unsigned char setting_index; +} AdbEndpointInformation; + +/// Shortcut to default write bulk endpoint in zero-based endpoint index API. +#define ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX 0xFC + +/// Shortcut to default read bulk endpoint in zero-based endpoint index API. +#define ADB_QUERY_BULK_READ_ENDPOINT_INDEX 0xFE + +// {F72FE0D4-CBCB-407d-8814-9ED673D0DD6B} +/// Our USB class id that driver uses to register our device. +#define ANDROID_USB_CLASS_ID \ +{0xf72fe0d4, 0xcbcb, 0x407d, {0x88, 0x14, 0x9e, 0xd6, 0x73, 0xd0, 0xdd, 0x6b}}; + +/// Defines vendor ID for HCT devices. +#define DEVICE_VENDOR_ID 0x0BB4 + +/// Defines product ID for the device with single interface. +#define DEVICE_SINGLE_PRODUCT_ID 0x0C01 + +/// Defines product ID for the Dream composite device. +#define DEVICE_COMPOSITE_PRODUCT_ID 0x0C02 + +/// Defines product ID for the Magic composite device. +#define DEVICE_MAGIC_COMPOSITE_PRODUCT_ID 0x0C03 + +/// Defines interface ID for the device. +#define DEVICE_INTERFACE_ID 0x01 + +/// Defines vendor ID for the device +#define DEVICE_EMULATOR_VENDOR_ID 0x18D1 + +/// Defines product ID for a SoftUSB device simulator that is used to test +/// the driver in isolation from hardware. +#define DEVICE_EMULATOR_PROD_ID 0xDDDD + +// 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 +// not be defined on any project that uses this DLL. This way any other project +// whose source files include this file see ADBWIN_API functions as being +// imported from a DLL, whereas this DLL sees symbols defined with this macro +// as being exported. +#ifdef ADBWIN_EXPORTS +#define ADBWIN_API EXTERN_C __declspec(dllexport) +#else +#define ADBWIN_API EXTERN_C __declspec(dllimport) +#endif + +/** \brief Handle to an API object. + + To access USB interface and its components clients must first obtain a + handle to the required object. API Objects that are represented by a + handle are: + 1. Interface enumerator that provides access to a list of interfaces that + match certain criterias that were specified when interface enumerator + has been created. This handle is created in AdbEnumInterfaces routine. + 2. Interface that is the major object this API deals with. In Windows + model of the USB stack each USB device (that is physical device, + attached to a USB port) exposes one or more interfaces that become the + major entities through which that device gets accessed. Each of these + interfaces are represented as Windows Device Objects on the USB stack. + So, to this extent, at least as this API is concerned, terms "interface" + and "device" are interchangeable, since each interface is represented by + a device object on the Windows USB stack. This handle is created in + either AdbCreateInterface or AdbCreateInterfaceByName routines. + 3. Endpoint object (also called a pipe) represents an endpoint on interface + through which all I/O operations are performed. This handle is created in + one of these routines: AdbOpenEndpoint, AdbOpenDefaultBulkReadEndpoint, + or AdbOpenDefaultBulkWriteEndpoint. + 4. I/O completion object that tracks completion information of asynchronous + I/O performed on an endpoint. When an endpoint object gets opened through + this API it is opened for asynchronous (or overlapped) I/O. And each time + an asynchronous I/O is performed by this API an I/O completion object is + created to track the result of that I/O when it gets completed. Clients + of the API can then use a handle to I/O completion object to query for + the status and result of asynchronous I/O as well as wait for this I/O + completion. This handle is created in one of these routines: + AdbReadEndpointAsync, or AdbWriteEndpointAsync. + After object is no longer needed by the client, its handle must be closed + using AdbCloseHandle routine. +*/ +typedef void* ADBAPIHANDLE; + +/** \brief Defines access type with which an I/O object (endpoint) + should be opened. +*/ +typedef enum _AdbOpenAccessType { + /// Opens for read and write access. + AdbOpenAccessTypeReadWrite, + + /// Opens for read only access. + AdbOpenAccessTypeRead, + + /// Opens for write only access. + AdbOpenAccessTypeWrite, + + /// Opens for querying information. + AdbOpenAccessTypeQueryInfo, +} AdbOpenAccessType; + +/** \brief Defines sharing mode with which an I/O object (endpoint) + should be opened. +*/ +typedef enum _AdbOpenSharingMode { + /// Shares read and write. + AdbOpenSharingModeReadWrite, + + /// Shares only read. + AdbOpenSharingModeRead, + + /// Shares only write. + AdbOpenSharingModeWrite, + + /// Opens exclusive. + AdbOpenSharingModeExclusive, +} AdbOpenSharingMode; + +/** \brief Provides information about an interface. +*/ +typedef struct _AdbInterfaceInfo { + /// Inteface's class id (see SP_DEVICE_INTERFACE_DATA for details) + GUID class_id; + + /// Interface flags (see SP_DEVICE_INTERFACE_DATA for details) + unsigned long flags; + + /// Device name for the interface (see SP_DEVICE_INTERFACE_DETAIL_DATA + /// for details) + wchar_t device_name[1]; +} AdbInterfaceInfo; + +/** \brief Creates USB interface enumerator + + This routine enumerates all USB interfaces that match provided class ID. + This routine uses SetupDiGetClassDevs SDK routine to enumerate devices that + match class ID and then SetupDiEnumDeviceInterfaces SDK routine is called + to enumerate interfaces on the devices. + @param[in] class_id Device class ID, assigned by the driver. + @param[in] exclude_not_present If true enumation will include only those + devices that are currently present. + @param[in] exclude_removed If true interfaces with SPINT_REMOVED flag set + will be not included in the enumeration. + @param[in] active_only If true only active interfaces (with flag + SPINT_ACTIVE set) will be included in the enumeration. + @return Handle to the enumerator object or NULL on failure. If NULL is + returned GetLastError() provides extended error information. +*/ +ADBWIN_API ADBAPIHANDLE __cdecl AdbEnumInterfaces(GUID class_id, + bool exclude_not_present, + bool exclude_removed, + bool active_only); + +/** \brief Gets next interface information + + @param[in] adb_handle Handle to interface enumerator object obtained via + AdbEnumInterfaces call. + @param[out] info Upon successful completion will receive interface + information. Can be NULL. If it is NULL, upon return from this + routine size parameter will contain memory size required for the + next entry. + @param[in,out] size On the way in provides size of the memory buffer + addressed by info parameter. On the way out (only if buffer was not + big enough) will provide memory size required for the next entry. + @return true on success, false on error. If false is returned + GetLastError() provides extended error information. + ERROR_INSUFFICIENT_BUFFER indicates that buffer provided in info + parameter was not big enough and size parameter contains memory size + required for the next entry. ERROR_NO_MORE_ITEMS indicates that + enumeration is over and there are no more entries to return. +*/ +ADBWIN_API bool __cdecl AdbNextInterface(ADBAPIHANDLE adb_handle, + AdbInterfaceInfo* info, + unsigned long* size); + +/** \brief Resets enumerator so next call to AdbNextInterface will start + from the beginning. + + @param[in] adb_handle Handle to interface enumerator object obtained via + AdbEnumInterfaces call. + @return true on success, false on error. If false is returned GetLastError() + provides extended error information. +*/ +ADBWIN_API bool __cdecl AdbResetInterfaceEnum(ADBAPIHANDLE adb_handle); + +/** \brief Creates USB interface object + + This routine creates an object that represents a USB interface. + @param[in] interface_name Name of the interface. + @return Handle to the interface object or NULL on failure. If NULL is + returned GetLastError() provides extended error information. +*/ +ADBWIN_API ADBAPIHANDLE __cdecl AdbCreateInterfaceByName(const wchar_t* interface_name); + +/** \brief Creates USB interface object based on vendor, product and + interface IDs. + + This routine creates and object that represents a USB interface on our + device. It uses AdbCreateInterfaceByName to actually do the create. + @param[in] class_id Device class ID, assigned by the driver. + @param[in] vendor_id Device vendor ID + @param[in] product_id Device product ID + @param[in] interface_id Device interface ID. This parameter is optional. + Value 0xFF indicates that interface should be addressed by vendor + and product IDs only. + @return Handle to the interface object or NULL on failure. If NULL is + returned GetLastError() provides extended error information. +*/ +ADBWIN_API ADBAPIHANDLE __cdecl AdbCreateInterface(GUID class_id, + unsigned short vendor_id, + unsigned short product_id, + unsigned char interface_id); + +/** \brief Gets interface name. + + @param[in] adb_interface A handle to interface object created with + AdbCreateInterface call. + @param[out] buffer Buffer for the name. Can be NULL in which case + buffer_char_size will contain number of characters required for + the name. + @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. +*/ +ADBWIN_API bool __cdecl AdbGetInterfaceName(ADBAPIHANDLE adb_interface, + void* buffer, + unsigned long* buffer_char_size, + bool ansi); + +/** \brief Gets serial number for interface's device. + + @param[in] adb_interface A handle to interface object created with + AdbCreateInterface call. + @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. +*/ +ADBWIN_API bool __cdecl AdbGetSerialNumber(ADBAPIHANDLE adb_interface, + void* buffer, + unsigned long* buffer_char_size, + bool ansi); + +/** \brief Gets device descriptor for the USB device associated with + the given interface. + + @param[in] adb_interface A handle to interface object created with + AdbCreateInterface call. + @param[out] desc Upon successful completion will have usb device + descriptor. + @return true on success, false on failure. If false is returned + GetLastError() provides extended error information. +*/ +ADBWIN_API bool __cdecl AdbGetUsbDeviceDescriptor(ADBAPIHANDLE adb_interface, + USB_DEVICE_DESCRIPTOR* desc); + +/** \brief Gets descriptor for the selected USB device configuration. + + @param[in] adb_interface A handle to interface object created with + AdbCreateInterface call. + @param[out] desc Upon successful completion will have usb device + configuration descriptor. + @return true on success, false on failure. If false is returned + GetLastError() provides extended error information. +*/ +ADBWIN_API bool __cdecl AdbGetUsbConfigurationDescriptor( + ADBAPIHANDLE adb_interface, + USB_CONFIGURATION_DESCRIPTOR* desc); + +/** \brief Gets descriptor for the given interface. + + @param[in] adb_interface A handle to interface object created with + AdbCreateInterface call. + @param[out] desc Upon successful completion will have usb device + configuration descriptor. + @return true on success, false on failure. If false is returned + GetLastError() provides extended error information. +*/ +ADBWIN_API bool __cdecl AdbGetUsbInterfaceDescriptor(ADBAPIHANDLE adb_interface, + USB_INTERFACE_DESCRIPTOR* desc); + +/** \brief Gets information about an endpoint on the given interface. + + @param[in] adb_interface A handle to interface object created with + AdbCreateInterface call. + @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 information + about bulk write and bulk 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. +*/ +ADBWIN_API bool __cdecl AdbGetEndpointInformation(ADBAPIHANDLE adb_interface, + unsigned char endpoint_index, + AdbEndpointInformation* info); + +/** \brief Gets information about default bulk read endpoint on the given + interface. + + @param[in] adb_interface A handle to interface object created with + AdbCreateInterface call. + @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. +*/ +ADBWIN_API bool __cdecl AdbGetDefaultBulkReadEndpointInformation( + ADBAPIHANDLE adb_interface, + AdbEndpointInformation* info); + +/** \brief Gets information about default bulk write endpoint on the given + interface. + + @param[in] adb_interface A handle to interface object created with + AdbCreateInterface call. + @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. +*/ +ADBWIN_API bool __cdecl AdbGetDefaultBulkWriteEndpointInformation( + ADBAPIHANDLE adb_interface, + AdbEndpointInformation* info); + +/** \brief Opens an endpoint on the given interface. + + Endpoints are always opened for overlapped I/O. + @param[in] adb_interface A handle to interface object created with + AdbCreateInterface call. + @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 information + about bulk write and bulk 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 error information. +*/ +ADBWIN_API ADBAPIHANDLE __cdecl AdbOpenEndpoint(ADBAPIHANDLE adb_interface, + unsigned char endpoint_index, + AdbOpenAccessType access_type, + AdbOpenSharingMode sharing_mode); + +/** \brief Opens default bulk read endpoint on the given interface. + + Endpoints are always opened for overlapped I/O. + @param[in] adb_interface A handle to interface object created with + AdbCreateInterface call. + @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 error information. +*/ +ADBWIN_API ADBAPIHANDLE __cdecl AdbOpenDefaultBulkReadEndpoint( + ADBAPIHANDLE adb_interface, + AdbOpenAccessType access_type, + AdbOpenSharingMode sharing_mode); + +/** \brief Opens default bulk write endpoint on the given interface. + + Endpoints are always opened for overlapped I/O. + @param[in] adb_interface A handle to interface object created with + AdbCreateInterface call. + @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 error information. +*/ +ADBWIN_API ADBAPIHANDLE __cdecl AdbOpenDefaultBulkWriteEndpoint( + ADBAPIHANDLE adb_interface, + AdbOpenAccessType access_type, + AdbOpenSharingMode sharing_mode); + +/** \brief Gets handle to interface object for the given endpoint + + @param[in] adb_endpoint A handle to opened endpoint object, obtained via one + of the AdbOpenXxxEndpoint calls. + @return Handle to the interface for this endpoint or NULL on failure. If NULL + is returned GetLastError() provides extended error information. +*/ +ADBWIN_API ADBAPIHANDLE __cdecl AdbGetEndpointInterface(ADBAPIHANDLE adb_endpoint); + +/** \brief Gets information about the given endpoint. + + @param[in] adb_endpoint A handle to opened endpoint object, obtained via one + of the AdbOpenXxxEndpoint calls. + @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. +*/ +ADBWIN_API bool __cdecl AdbQueryInformationEndpoint(ADBAPIHANDLE adb_endpoint, + AdbEndpointInformation* info); + +/** \brief Asynchronously reads from the given endpoint. + + @param[in] adb_endpoint A handle to opened endpoint object, obtained via one + of the AdbOpenXxxEndpoint calls. + @param[out] buffer Pointer to the buffer that receives the data. + @param[in] bytes_to_read Number of bytes to be read. + @param[out] bytes_read Number of bytes read. 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 for this parameter means that there is no + timeout for this I/O. + @return A handle to IO completion object or NULL on failure. If NULL is + returned GetLastError() provides extended error information. +*/ +ADBWIN_API ADBAPIHANDLE __cdecl AdbReadEndpointAsync(ADBAPIHANDLE adb_endpoint, + void* buffer, + unsigned long bytes_to_read, + unsigned long* bytes_read, + unsigned long time_out, + HANDLE event_handle); + +/** \brief Asynchronously writes to the given endpoint. + + @param[in] adb_endpoint A handle to opened endpoint object, obtained via one + of the AdbOpenXxxEndpoint calls. + @param[in] buffer Pointer to the buffer containing the data to be written. + @param[in] bytes_to_write Number of bytes to be written. + @param[out] bytes_written Number of bytes 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 for this parameter means that there is no + timeout for this I/O. + @return A handle to IO completion object or NULL on failure. If NULL is + returned GetLastError() provides extended error information. +*/ +ADBWIN_API ADBAPIHANDLE __cdecl AdbWriteEndpointAsync(ADBAPIHANDLE adb_endpoint, + void* buffer, + unsigned long bytes_to_write, + unsigned long* bytes_written, + unsigned long time_out, + HANDLE event_handle); + +/** \brief Synchronously reads from the given endpoint. + + @param[in] adb_endpoint A handle to opened endpoint object, obtained via one + of the AdbOpenXxxEndpoint calls. + @param[out] buffer Pointer to the buffer that receives the data. + @param[in] bytes_to_read Number of bytes to be read. + @param[out] bytes_read Number of bytes read. Can be NULL. + @param[in] time_out A timeout (in milliseconds) required for this I/O to + complete. Zero value for this parameter means that there is no + timeout for this I/O. + @return true on success and false on failure. If false is + returned GetLastError() provides extended error information. +*/ +ADBWIN_API bool __cdecl AdbReadEndpointSync(ADBAPIHANDLE adb_endpoint, + void* buffer, + unsigned long bytes_to_read, + unsigned long* bytes_read, + unsigned long time_out); + +/** \brief Synchronously writes to the given endpoint. + + @param[in] adb_endpoint A handle to opened endpoint object, obtained via one + of the AdbOpenXxxEndpoint calls. + @param[in] buffer Pointer to the buffer containing the data to be written. + @param[in] bytes_to_write Number of bytes to be written. + @param[out] bytes_written Number of bytes written. Can be NULL. + @param[in] time_out A timeout (in milliseconds) required for this I/O to + complete. Zero value for this parameter means that there is no + timeout for this I/O. + @return true on success and false on failure. If false is + returned GetLastError() provides extended error information. +*/ +ADBWIN_API bool __cdecl AdbWriteEndpointSync(ADBAPIHANDLE adb_endpoint, + void* buffer, + unsigned long bytes_to_write, + unsigned long* bytes_written, + unsigned long time_out); + +/** \brief Gets overlapped I/O result for async I/O performed on the + given endpoint. + + @param[in] adb_io_completion A handle to an I/O completion object returned + from AdbRead/WriteAsync routines. + @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. +*/ +ADBWIN_API bool __cdecl AdbGetOvelappedIoResult(ADBAPIHANDLE adb_io_completion, + LPOVERLAPPED overlapped, + unsigned long* bytes_transferred, + bool wait); + +/** \brief Checks if overlapped I/O has been completed. + + @param[in] adb_io_completion A handle to an I/O completion object returned + from AdbRead/WriteAsync routines. + @return true if I/O has been completed or false if it's still + incomplete. Regardless of the returned value, caller should + check GetLastError to validate that handle was OK. +*/ +ADBWIN_API bool __cdecl AdbHasOvelappedIoComplated(ADBAPIHANDLE adb_io_completion); + +/** \brief Closes handle previously opened with one of the API calls + + @param[in] adb_handle ADB handle previously opened with one of the API calls + @return true on success or false on failure. If false is returned + GetLastError() provides extended error information. +*/ +ADBWIN_API bool __cdecl AdbCloseHandle(ADBAPIHANDLE adb_handle); + +#endif // ANDROID_USB_API_ADBWINAPI_H__ diff --git a/host/windows/usb/api/adb_api_extra.h b/host/windows/usb/api/adb_api_extra.h deleted file mode 100644 index e644b015f..000000000 --- a/host/windows/usb/api/adb_api_extra.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_USB_API_ADB_API_EXTRA_H__ -#define ANDROID_USB_API_ADB_API_EXTRA_H__ -/** \file - This file consists of public API declarations that are also used by the - driver and as such cannot be declared in adb_api.h -*/ - -/** AdbEndpointType enumerates endpoint types. It enum is taken from - WDF_USB_PIPE_TYPE enum found in WDK. -*/ -typedef enum _AdbEndpointType { - AdbEndpointTypeInvalid = 0, - AdbEndpointTypeControl, - AdbEndpointTypeIsochronous, - AdbEndpointTypeBulk, - AdbEndpointTypeInterrupt, -} AdbEndpointType; - -/** Structure AdbEndpointInformation describes an endpoint. It is - based on WDF_USB_PIPE_INFORMATION structure found in WDK. -*/ -typedef struct _AdbEndpointInformation { - /// Maximum packet size this endpoint is capable of - unsigned long max_packet_size; - - // Maximum size of one transfer which should be sent to the host controller - unsigned long max_transfer_size; - - // The type of the endpoint - AdbEndpointType endpoint_type; - - /// Raw endpoint address of the device as described by its descriptor - unsigned char endpoint_address; - - /// Polling interval - unsigned char polling_interval; - - /// Which alternate setting this structure is relevant for - unsigned char setting_index; -} AdbEndpointInformation; - -/// Shortcut to default write bulk endpoint in zero-based endpoint index API -#define ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX 0xFC - -/// Shortcut to default read bulk endpoint in zero-based endpoint index API -#define ADB_QUERY_BULK_READ_ENDPOINT_INDEX 0xFE - -// {F72FE0D4-CBCB-407d-8814-9ED673D0DD6B} -/// Our USB class id that driver uses to register our device -#define ANDROID_USB_CLASS_ID \ -{0xf72fe0d4, 0xcbcb, 0x407d, {0x88, 0x14, 0x9e, 0xd6, 0x73, 0xd0, 0xdd, 0x6b}}; - -/// Defines vendor ID for the device -#define DEVICE_VENDOR_ID 0x0BB4 - -/// Defines product ID for the device with single interface. -#define DEVICE_SINGLE_PRODUCT_ID 0x0C01 - -/// Defines product ID for the composite device. -#define DEVICE_COMPOSITE_PRODUCT_ID 0x0C02 - -/// Defines interface ID for the device. -#define DEVICE_INTERFACE_ID 0x01 - -/// Defines vendor ID for the device -#define DEVICE_EMULATOR_VENDOR_ID 0x18D1 - -/// Defines product ID for a SoftUSB device simulator that is used to test -/// the driver in isolation from hardware. -#define DEVICE_EMULATOR_PROD_ID 0xDDDD - -#endif // ANDROID_USB_API_ADB_API_EXTRA_H__ diff --git a/host/windows/usb/api/adb_api_instance.cpp b/host/windows/usb/api/adb_api_instance.cpp index 4f66b981b..63d1d5d20 100644 --- a/host/windows/usb/api/adb_api_instance.cpp +++ b/host/windows/usb/api/adb_api_instance.cpp @@ -1,47 +1,47 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - This file consists of implementation of class AdbApiInstance that is a main - API object representing a device interface that is in the interest of - the API client. All device (interface) related operations go through this - class first. -*/ - -#include "stdafx.h" -#include "adb_api_instance.h" -#include "adb_helper_routines.h" - -/// Map that holds all instances of this object -AdbApiInstanceMap adb_app_instance_map; -ULONG_PTR adb_app_instance_id = 0; -CComAutoCriticalSection adb_app_instance_map_locker; - -AdbApiInstance::AdbApiInstance() - : ref_count_(1) { - // Generate inteface handle - adb_app_instance_map_locker.Lock(); - adb_app_instance_id++; - adb_app_instance_map_locker.Unlock(); - instance_handle_ = - reinterpret_cast(adb_app_instance_id); -} - -AdbApiInstance::~AdbApiInstance() { -} - -void AdbApiInstance::LastReferenceReleased() { -} +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \file + This file consists of implementation of class AdbApiInstance that is a main + API object representing a device interface that is in the interest of + the API client. All device (interface) related operations go through this + class first. +*/ + +#include "stdafx.h" +#include "adb_api_instance.h" +#include "adb_helper_routines.h" + +/// Map that holds all instances of this object +AdbApiInstanceMap adb_app_instance_map; +ULONG_PTR adb_app_instance_id = 0; +CComAutoCriticalSection adb_app_instance_map_locker; + +AdbApiInstance::AdbApiInstance() + : ref_count_(1) { + // Generate inteface handle + adb_app_instance_map_locker.Lock(); + adb_app_instance_id++; + adb_app_instance_map_locker.Unlock(); + instance_handle_ = + reinterpret_cast(adb_app_instance_id); +} + +AdbApiInstance::~AdbApiInstance() { +} + +void AdbApiInstance::LastReferenceReleased() { +} diff --git a/host/windows/usb/api/adb_api_instance.h b/host/windows/usb/api/adb_api_instance.h index 9bc80b8bb..d5e7ef142 100644 --- a/host/windows/usb/api/adb_api_instance.h +++ b/host/windows/usb/api/adb_api_instance.h @@ -1,113 +1,113 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_USB_API_ADB_API_INSTANCE_H__ -#define ANDROID_USB_API_ADB_API_INSTANCE_H__ -/** \file - This file consists of declaration of class AdbApiInstance that is a main - API object representing a device interface that is in the interest of - the API client. All device (interface) related operations go through this - class first. -*/ - -#include "adb_api.h" -#include "adb_api_private_defines.h" - -/** Class AdbApiInstance is the main API interbal object representing a device - interface that is in the interest of the API client. All device (interface) - related operations go through this class first. So, before doing anything - meaningfull with the API a client must first create instance of the API - via CreateAdbApiInstance, select a device interface for that instance and - then do everything else. - Objects of this class are globally stored in the map that matches - ADBAPIINSTANCEHANDLE to the corresponded object. - This class is self-referenced with the following reference model: - 1. When object of this class is created and added to the map, its recount - is set to 1. - 2. Every time the client makes an API call that uses ADBAPIINSTANCEHANDLE - a corresponded AdbApiInstance object is looked up in the table and its - refcount is incremented. Upon return from the API call that incremented - the refcount refcount gets decremented. - 3. When the client closes ADBAPIINSTANCEHANDLE via DeleteAdbApiInstance call - corresponded object gets deleted from the map and its refcount is - decremented. - So, at the end, this object destroys itself when refcount drops to zero. -*/ -class AdbApiInstance { - public: - /** \brief Constructs the object - - @param handle[in] Instance handle associated with this object - */ - AdbApiInstance(); - - private: - /// Destructs the object - ~AdbApiInstance(); - - /** \brief - This method is called when last reference to this object has been released - - In this method object is uninitialized and deleted (that is "delete this" - is called). - */ - void LastReferenceReleased(); - - public: - /// Gets name of the USB interface (device name) for this instance - const std::wstring& interface_name() const { - return interface_name_; - } - - /// References the object and returns number of references - LONG AddRef() { - return InterlockedIncrement(&ref_count_); - } - - /** \brief Dereferences the object and returns number of references - - Object may be deleted in this method, so you cannot touch it after - this method returns, even if returned value is not zero, because object - can be deleted in another thread. - */ - LONG Release() { - LONG ret = InterlockedDecrement(&ref_count_); - if (0 == ret) - LastReferenceReleased(); - - return ret; - } - - /// Checks if instance has been initialized - bool IsInitialized() const { - return !interface_name_.empty(); - } - -private: - /// Name of the USB interface (device name) for this instance - std::wstring interface_name_; - - /// Instance handle for this object - ADBAPIINSTANCEHANDLE instance_handle_; - - /// Reference counter for this instance - LONG ref_count_; -}; - -/// Defines map that matches ADBAPIINSTANCEHANDLE with AdbApiInstance object -typedef std::map< ADBAPIINSTANCEHANDLE, AdbApiInstance* > AdbApiInstanceMap; - -#endif // ANDROID_USB_API_ADB_API_INSTANCE_H__ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_USB_API_ADB_API_INSTANCE_H__ +#define ANDROID_USB_API_ADB_API_INSTANCE_H__ +/** \file + This file consists of declaration of class AdbApiInstance that is a main + API object representing a device interface that is in the interest of + the API client. All device (interface) related operations go through this + class first. +*/ + +#include "adb_api.h" +#include "adb_api_private_defines.h" + +/** Class AdbApiInstance is the main API interbal object representing a device + interface that is in the interest of the API client. All device (interface) + related operations go through this class first. So, before doing anything + meaningfull with the API a client must first create instance of the API + via CreateAdbApiInstance, select a device interface for that instance and + then do everything else. + Objects of this class are globally stored in the map that matches + ADBAPIINSTANCEHANDLE to the corresponded object. + This class is self-referenced with the following reference model: + 1. When object of this class is created and added to the map, its recount + is set to 1. + 2. Every time the client makes an API call that uses ADBAPIINSTANCEHANDLE + a corresponded AdbApiInstance object is looked up in the table and its + refcount is incremented. Upon return from the API call that incremented + the refcount refcount gets decremented. + 3. When the client closes ADBAPIINSTANCEHANDLE via DeleteAdbApiInstance call + corresponded object gets deleted from the map and its refcount is + decremented. + So, at the end, this object destroys itself when refcount drops to zero. +*/ +class AdbApiInstance { + public: + /** \brief Constructs the object + + @param handle[in] Instance handle associated with this object + */ + AdbApiInstance(); + + private: + /// Destructs the object + ~AdbApiInstance(); + + /** \brief + This method is called when last reference to this object has been released + + In this method object is uninitialized and deleted (that is "delete this" + is called). + */ + void LastReferenceReleased(); + + public: + /// Gets name of the USB interface (device name) for this instance + const std::wstring& interface_name() const { + return interface_name_; + } + + /// References the object and returns number of references + LONG AddRef() { + return InterlockedIncrement(&ref_count_); + } + + /** \brief Dereferences the object and returns number of references + + Object may be deleted in this method, so you cannot touch it after + this method returns, even if returned value is not zero, because object + can be deleted in another thread. + */ + LONG Release() { + LONG ret = InterlockedDecrement(&ref_count_); + if (0 == ret) + LastReferenceReleased(); + + return ret; + } + + /// Checks if instance has been initialized + bool IsInitialized() const { + return !interface_name_.empty(); + } + +private: + /// Name of the USB interface (device name) for this instance + std::wstring interface_name_; + + /// Instance handle for this object + ADBAPIINSTANCEHANDLE instance_handle_; + + /// Reference counter for this instance + LONG ref_count_; +}; + +/// Defines map that matches ADBAPIINSTANCEHANDLE with AdbApiInstance object +typedef std::map< ADBAPIINSTANCEHANDLE, AdbApiInstance* > AdbApiInstanceMap; + +#endif // ANDROID_USB_API_ADB_API_INSTANCE_H__ diff --git a/host/windows/usb/api/adb_api_private_defines.h b/host/windows/usb/api/adb_api_private_defines.h index e1da7fe47..3b830b2ff 100644 --- a/host/windows/usb/api/adb_api_private_defines.h +++ b/host/windows/usb/api/adb_api_private_defines.h @@ -1,115 +1,114 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__ -#define ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__ -/** \file - This file consists of private definitions used inside the API -*/ - -#include "adb_api.h" - -/** Class AdbInstanceEnumEntry encapsulates an entry in the array of - enumerated interfaces. -*/ -class AdbInstanceEnumEntry { - public: - /** \brief Constructs an empty object. - */ - AdbInstanceEnumEntry() - : flags_(0) { - ZeroMemory(&class_id_, sizeof(class_id_)); - } - - /** \brief Copy constructor - */ - AdbInstanceEnumEntry(const AdbInstanceEnumEntry& proto) { - Set(proto.device_name().c_str(), proto.class_id(), proto.flags()); - } - - /** \brief Constructs the object with parameters. - */ - AdbInstanceEnumEntry(const wchar_t* dev_name, GUID cls_id, DWORD flgs) { - Set(dev_name, cls_id, flgs); - } - - /** \brief Destructs the object. - */ - ~AdbInstanceEnumEntry() { - } - - /// Operator = - AdbInstanceEnumEntry& operator=(const AdbInstanceEnumEntry& proto) { - Set(proto.device_name().c_str(), proto.class_id(), proto.flags()); - return *this; - } - - /// Initializes instance with parameters - void Set(const wchar_t* dev_name, GUID cls_id, DWORD flgs) { - device_name_ = dev_name; - class_id_ = cls_id; - flags_ = flgs; - } - - /// Calculates memory size needed to save this entry into AdbInterfaceInfo - /// structure - ULONG GetFlatSize() const { - return static_cast(FIELD_OFFSET(AdbInterfaceInfo, device_name) + - (device_name_.length() + 1) * sizeof(wchar_t)); - } - - /** \brief Saves this entry into AdbInterfaceInfo structure. - - @param info[in] Buffer to save this entry to. Must be big enough to fit it. - Use GetFlatSize() method to get buffer size needed for that. - - */ - void Save(AdbInterfaceInfo* info) const { - info->class_id = class_id(); - info->flags = flags(); - wcscpy(info->device_name, device_name().c_str()); - } - - /// Gets interface's device name - const std::wstring& device_name() const { - return device_name_; - } - - /// Gets inteface's class id - GUID class_id() const { - return class_id_; - } - - /// Gets interface flags - DWORD flags() const { - return flags_; - } - - private: - /// Inteface's class id (see SP_DEVICE_INTERFACE_DATA) - GUID class_id_; - - /// Interface's device name - std::wstring device_name_; - - /// Interface flags (see SP_DEVICE_INTERFACE_DATA) - DWORD flags_; -}; - -/// Defines array of enumerated interface entries -typedef std::vector< AdbInstanceEnumEntry > AdbEnumInterfaceArray; - -#endif // ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__ +#define ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__ +/** \file + This file consists of private definitions used inside the API +*/ + +#include "adb_api.h" + +/** \brief Encapsulates an entry in the array of enumerated interfaces. +*/ +class AdbInstanceEnumEntry { + public: + /** \brief Constructs an empty object. + */ + AdbInstanceEnumEntry() + : flags_(0) { + ZeroMemory(&class_id_, sizeof(class_id_)); + } + + /** \brief Copy constructor + */ + AdbInstanceEnumEntry(const AdbInstanceEnumEntry& proto) { + Set(proto.device_name().c_str(), proto.class_id(), proto.flags()); + } + + /** \brief Constructs the object with parameters. + */ + AdbInstanceEnumEntry(const wchar_t* dev_name, GUID cls_id, DWORD flgs) { + Set(dev_name, cls_id, flgs); + } + + /** \brief Destructs the object. + */ + ~AdbInstanceEnumEntry() { + } + + /// Operator = + AdbInstanceEnumEntry& operator=(const AdbInstanceEnumEntry& proto) { + Set(proto.device_name().c_str(), proto.class_id(), proto.flags()); + return *this; + } + + /// Initializes instance with parameters + void Set(const wchar_t* dev_name, GUID cls_id, DWORD flgs) { + device_name_ = dev_name; + class_id_ = cls_id; + flags_ = flgs; + } + + /// Calculates memory size needed to save this entry into AdbInterfaceInfo + /// structure + ULONG GetFlatSize() const { + return static_cast(FIELD_OFFSET(AdbInterfaceInfo, device_name) + + (device_name_.length() + 1) * sizeof(wchar_t)); + } + + /** \brief Saves this entry into AdbInterfaceInfo structure. + + @param[in] info Buffer to save this entry to. Must be big enough to fit it. + Use GetFlatSize() method to get buffer size needed for that. + + */ + void Save(AdbInterfaceInfo* info) const { + info->class_id = class_id(); + info->flags = flags(); + wcscpy(info->device_name, device_name().c_str()); + } + + /// Gets interface's device name + const std::wstring& device_name() const { + return device_name_; + } + + /// Gets inteface's class id + GUID class_id() const { + return class_id_; + } + + /// Gets interface flags + DWORD flags() const { + return flags_; + } + + private: + /// Inteface's class id (see SP_DEVICE_INTERFACE_DATA) + GUID class_id_; + + /// Interface's device name + std::wstring device_name_; + + /// Interface flags (see SP_DEVICE_INTERFACE_DATA) + DWORD flags_; +}; + +/// Defines array of enumerated interface entries +typedef std::vector< AdbInstanceEnumEntry > AdbEnumInterfaceArray; + +#endif // ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__ diff --git a/host/windows/usb/api/adb_endpoint_object.cpp b/host/windows/usb/api/adb_endpoint_object.cpp index 90f698f1d..9237a6021 100644 --- a/host/windows/usb/api/adb_endpoint_object.cpp +++ b/host/windows/usb/api/adb_endpoint_object.cpp @@ -1,54 +1,221 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - This file consists of implementation of class AdbIOObject that - encapsulates an interface on our USB device. -*/ - -#include "stdafx.h" -#include "adb_endpoint_object.h" - -AdbEndpointObject::AdbEndpointObject(AdbInterfaceObject* parent_interf) - : AdbIOObject(parent_interf, AdbObjectTypeEndpoint) { -} - -AdbEndpointObject::~AdbEndpointObject() { -} - -bool AdbEndpointObject::IsObjectOfType(AdbObjectType obj_type) const { - return ((obj_type == AdbObjectTypeEndpoint) || - (obj_type == AdbObjectTypeIo)); -} - -bool AdbEndpointObject::GetEndpointInformation(AdbEndpointInformation* info) { - if (!IsOpened() || !IsUsbOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - // Send IOCTL - DWORD ret_bytes = 0; - BOOL ret = DeviceIoControl(usb_handle(), - ADB_IOCTL_GET_ENDPOINT_INFORMATION, - NULL, 0, - info, sizeof(AdbEndpointInformation), - &ret_bytes, - NULL); - ATLASSERT(!ret || (sizeof(AdbEndpointInformation) == ret_bytes)); - - return ret ? true : false; -} +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \file + This file consists of implementation of class AdbIOObject that + encapsulates an interface on our USB device. +*/ + +#include "stdafx.h" +#include "adb_endpoint_object.h" +#include "adb_io_completion.h" +#include "adb_helper_routines.h" + +AdbEndpointObject::AdbEndpointObject(AdbInterfaceObject* parent_interf, + UCHAR endpoint_id, + UCHAR endpoint_index) + : AdbObjectHandle(AdbObjectTypeEndpoint), + parent_interface_(parent_interf), + endpoint_id_(endpoint_id), + endpoint_index_(endpoint_index) { + if (NULL != parent_interface_) + parent_interface_->AddRef(); +} + +AdbEndpointObject::~AdbEndpointObject() { + if (NULL != parent_interface_) + parent_interface_->Release(); +} + +bool AdbEndpointObject::GetEndpointInformation(AdbEndpointInformation* info) { + if (!IsOpened()) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + return parent_interface()->GetEndpointInformation(endpoint_index(), info); +} + +ADBAPIHANDLE AdbEndpointObject::AsyncRead(void* buffer, + ULONG bytes_to_read, + ULONG* bytes_read, + HANDLE event_handle, + ULONG time_out) { + return CommonAsyncReadWrite(true, + buffer, + bytes_to_read, + bytes_read, + event_handle, + time_out); +} + +ADBAPIHANDLE AdbEndpointObject::AsyncWrite(void* buffer, + ULONG bytes_to_write, + ULONG* bytes_written, + HANDLE event_handle, + ULONG time_out) { + return CommonAsyncReadWrite(false, + buffer, + bytes_to_write, + bytes_written, + event_handle, + time_out); +} + +bool AdbEndpointObject::SyncRead(void* buffer, + ULONG bytes_to_read, + ULONG* bytes_read, + ULONG time_out) { + return CommonSyncReadWrite(true, + buffer, + bytes_to_read, + bytes_read, + time_out); +} + +bool AdbEndpointObject::SyncWrite(void* buffer, + ULONG bytes_to_write, + ULONG* bytes_written, + ULONG time_out) { + return CommonSyncReadWrite(false, + buffer, + bytes_to_write, + bytes_written, + time_out); +} + +ADBAPIHANDLE AdbEndpointObject::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 AdbIOCompletion(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_interface()->winusb_handle(), + endpoint_id(), + reinterpret_cast(buffer), + bytes_to_transfer, + &transferred, + adb_io_completion->overlapped()) : + WinUsb_WritePipe(parent_interface()->winusb_handle(), + endpoint_id(), + reinterpret_cast(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 AdbEndpointObject::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_interface()->winusb_handle(), + endpoint_id(), + reinterpret_cast(buffer), + bytes_to_transfer, + &transferred, + &overlapped) : + WinUsb_WritePipe(parent_interface()->winusb_handle(), + endpoint_id(), + reinterpret_cast(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_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 AdbEndpointObject::SetTimeout(ULONG timeout) { + if (!WinUsb_SetPipePolicy(parent_interface()->winusb_handle(), + endpoint_id(), PIPE_TRANSFER_TIMEOUT, + sizeof(ULONG), &timeout)) { + return false; + } + + return true; +} diff --git a/host/windows/usb/api/adb_endpoint_object.h b/host/windows/usb/api/adb_endpoint_object.h index eda8ffafd..d4d1a6a08 100644 --- a/host/windows/usb/api/adb_endpoint_object.h +++ b/host/windows/usb/api/adb_endpoint_object.h @@ -1,71 +1,233 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_USB_API_ADB_ENDPOINT_OBJECT_H__ -#define ANDROID_USB_API_ADB_ENDPOINT_OBJECT_H__ -/** \file - This file consists of declaration of class AdbIOObject that encapsulates a - handle opened to an endpoint on our device. -*/ - -#include "adb_io_object.h" - -/** Class AdbEndpointObject encapsulates a handle opened to an endpoint on - our device. -*/ -class AdbEndpointObject : public AdbIOObject { - public: - /** \brief Constructs the object - - @param interface[in] Parent interface for this object. Interface will be - referenced in this object's constructur and released in the - destructor. - @param obj_type[in] Object type from AdbObjectType enum - */ - AdbEndpointObject(AdbInterfaceObject* parent_interf); - - protected: - /** \brief Destructs the object. - - parent_interface_ will be dereferenced here. - We hide destructor in order to prevent ourseves from accidentaly allocating - instances on the stack. If such attemp occur, compiler will error. - */ - virtual ~AdbEndpointObject(); - - public: - /** \brief Gets information about this endpoint. - - @param info[out] Upon successful completion will have endpoint information. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. - */ - bool GetEndpointInformation(AdbEndpointInformation* info); - - /** \brief Checks if this object is of the given type - - @param obj_type[in] One of the AdbObjectType types to check - @return 'true' is this object type matches obj_type and 'false' otherwise. - */ - virtual bool IsObjectOfType(AdbObjectType obj_type) const; - - // This is a helper for extracting object from the AdbObjectHandleMap - static AdbObjectType Type() { - return AdbObjectTypeEndpoint; - } -}; - -#endif // ANDROID_USB_API_ADB_ENDPOINT_OBJECT_H__ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_USB_API_ADB_ENDPOINT_OBJECT_H__ +#define ANDROID_USB_API_ADB_ENDPOINT_OBJECT_H__ +/** \file + This file consists of declaration of class AdbIOObject that encapsulates a + handle opened to an endpoint on our device. +*/ + +#include "adb_interface.h" + +/** Class AdbEndpointObject encapsulates a handle opened to an endpoint on + our device. +*/ +class AdbEndpointObject : public AdbObjectHandle { + public: + /** \brief Constructs the object + + @param[in] interface Parent interface for this object. Interface will be + referenced in this object's constructur and released in the + destructor. + @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. + */ + AdbEndpointObject(AdbInterfaceObject* 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 ~AdbEndpointObject(); + + public: + /** \brief Gets information about this endpoint. + + @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. + */ + bool GetEndpointInformation(AdbEndpointInformation* info); + + /** \brief Reads from opened I/O object asynchronously + + @param[out] buffer Pointer to the buffer that receives the data. + @param[in] bytes_to_read Number of bytes to be read. + @param[out] bytes_read Number of bytes read. 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 AsyncRead(void* buffer, + ULONG bytes_to_read, + ULONG* bytes_read, + HANDLE event_handle, + ULONG time_out); + + /** \brief Writes to opened I/O object asynchronously + + @param[in] buffer Pointer to the buffer containing the data to be written. + @param[in] bytes_to_write Number of bytes to be written. + @param[out] bytes_written Number of bytes 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 AsyncWrite(void* buffer, + ULONG bytes_to_write, + ULONG* bytes_written, + HANDLE event_handle, + ULONG time_out); + + /** \brief Reads from opened I/O object synchronously + + @param[out] buffer Pointer to the buffer that receives the data. + @param[in] bytes_to_read Number of bytes to be read. + @param[out] bytes_read Number of bytes read. 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 and false on failure. If false is + returned GetLastError() provides extended error information. + */ + virtual bool SyncRead(void* buffer, + ULONG bytes_to_read, + ULONG* bytes_read, + ULONG time_out); + + /** \brief Writes to opened I/O object synchronously + + @param[in] buffer Pointer to the buffer containing the data to be written. + @param[in] bytes_to_write Number of bytes to be written. + @param[out] bytes_written Number of bytes 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 and false on failure. If false is + returned GetLastError() provides extended error information. + */ + virtual bool SyncWrite(void* buffer, + ULONG bytes_to_write, + ULONG* bytes_written, + ULONG time_out); + + 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); + /** \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: + /// This is a helper for extracting object from the AdbObjectHandleMap + static AdbObjectType Type() { + return AdbObjectTypeEndpoint; + } + + /// Gets parent interface + AdbInterfaceObject* parent_interface() const { + return parent_interface_; + } + /// Gets this endpoint ID + UCHAR endpoint_id() const { + return endpoint_id_; + } + + /// Gets this endpoint index on the interface + UCHAR endpoint_index() const { + return endpoint_index_; + } + + /// Gets parent interface handle + ADBAPIHANDLE GetParentInterfaceHandle() const { + return (NULL != parent_interface()) ? parent_interface()->adb_handle() : + NULL; + } + + /// Gets parent interface WinUsb handle + WINUSB_INTERFACE_HANDLE winusb_handle() const { + return parent_interface()->winusb_handle(); + } + + protected: + /// Parent interface + AdbInterfaceObject* parent_interface_; + + /// This endpoint id + UCHAR endpoint_id_; + + /// This endpoint index on the interface + UCHAR endpoint_index_; +}; + +#endif // ANDROID_USB_API_ADB_ENDPOINT_OBJECT_H__ diff --git a/host/windows/usb/api/adb_helper_routines.cpp b/host/windows/usb/api/adb_helper_routines.cpp index f2cd93852..3a7748bbc 100644 --- a/host/windows/usb/api/adb_helper_routines.cpp +++ b/host/windows/usb/api/adb_helper_routines.cpp @@ -1,248 +1,189 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - This file consists of implementation of helper routines used - in the API. -*/ - -#include "stdafx.h" -#include "adb_api.h" -#include "adb_helper_routines.h" -#include "adb_interface_enum.h" - -bool GetSDKComplientParam(AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode, - ULONG* desired_access, - ULONG* desired_sharing) { - if (NULL != desired_access) { - switch (access_type) { - case AdbOpenAccessTypeReadWrite: - *desired_access = GENERIC_READ | GENERIC_WRITE; - break; - - case AdbOpenAccessTypeRead: - *desired_access = GENERIC_READ; - break; - - case AdbOpenAccessTypeWrite: - *desired_access = GENERIC_WRITE; - break; - - case AdbOpenAccessTypeQueryInfo: - *desired_access = FILE_READ_ATTRIBUTES | FILE_READ_EA; - break; - - default: - AtlTrace("\n!!!!! ADB API -> GetSDKComplientParam %u is unknown access type", - access_type); - SetLastError(ERROR_INVALID_ACCESS); - return false; - } - } - - if (NULL != desired_sharing) { - switch (sharing_mode) { - case AdbOpenSharingModeReadWrite: - *desired_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; - break; - - case AdbOpenSharingModeRead: - *desired_sharing = FILE_SHARE_READ; - break; - - case AdbOpenSharingModeWrite: - *desired_sharing = FILE_SHARE_WRITE; - break; - - case AdbOpenSharingModeExclusive: - *desired_sharing = 0; - break; - - default: - AtlTrace("\n!!!!! ADB API -> GetSDKComplientParam %u is unknown share mode", - sharing_mode); - SetLastError(ERROR_INVALID_PARAMETER); - return false; - } - } - - return true; -} - -bool EnumerateDeviceInterfaces(HDEVINFO hardware_dev_info, - GUID class_id, - bool exclude_removed, - bool active_only, - AdbEnumInterfaceArray* interfaces) { - AdbEnumInterfaceArray tmp; - bool ret = false; - - // Enumerate interfaces on this device - for (ULONG index = 0; ; index++) { - SP_DEVICE_INTERFACE_DATA interface_data; - interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - - // SetupDiEnumDeviceInterfaces() returns information about device - // interfaces exposed by one or more devices defined by our interface - // class. Each call returns information about one interface. The routine - // can be called repeatedly to get information about several interfaces - // exposed by one or more devices. - if (SetupDiEnumDeviceInterfaces(hardware_dev_info, - 0, - &class_id, - index, - &interface_data)) { - // Satisfy "exclude removed" and "active only" filters. - if ((!exclude_removed || (0 == (interface_data.Flags & SPINT_REMOVED))) && - (!active_only || (interface_data.Flags & SPINT_ACTIVE))) { - std::wstring dev_name; - - if (GetUsbDeviceName(hardware_dev_info, &interface_data, &dev_name)) { - try { - // Add new entry to the array - tmp.push_back(AdbInstanceEnumEntry(dev_name.c_str(), - interface_data.InterfaceClassGuid, - interface_data.Flags)); - } catch (... ) { - SetLastError(ERROR_OUTOFMEMORY); - break; - } - } else { - // Something went wrong in getting device name - break; - } - } - } else { - if (ERROR_NO_MORE_ITEMS == GetLastError()) { - // There are no more items in the list. Enum is completed. - ret = true; - break; - } else { - // Something went wrong in SDK enum - break; - } - } - } - - // On success, swap temp array with the returning one - if (ret) - interfaces->swap(tmp); - - return ret; -} - -bool EnumerateDeviceInterfaces(GUID class_id, - ULONG flags, - bool exclude_removed, - bool active_only, - AdbEnumInterfaceArray* interfaces) { - // Open a handle to the plug and play dev node. - // SetupDiGetClassDevs() returns a device information set that - // contains info on all installed devices of a specified class. - HDEVINFO hardware_dev_info = - SetupDiGetClassDevs(&class_id, NULL, NULL, flags); - - bool ret = false; - - if (INVALID_HANDLE_VALUE != hardware_dev_info) { - // Do the enum - ret = EnumerateDeviceInterfaces(hardware_dev_info, - class_id, - exclude_removed, - active_only, - interfaces); - - // Preserve last error accross hardware_dev_info destruction - ULONG error_to_report = ret ? NO_ERROR : GetLastError(); - - SetupDiDestroyDeviceInfoList(hardware_dev_info); - - if (NO_ERROR != error_to_report) - SetLastError(error_to_report); - } - - return ret; -} - -bool GetUsbDeviceDetails( - HDEVINFO hardware_dev_info, - PSP_DEVICE_INTERFACE_DATA dev_info_data, - PSP_DEVICE_INTERFACE_DETAIL_DATA* dev_info_detail_data) { - ULONG required_len = 0; - - // First query for the structure size. At this point we expect this call - // to fail with ERROR_INSUFFICIENT_BUFFER error code. - if (SetupDiGetDeviceInterfaceDetail(hardware_dev_info, - dev_info_data, - NULL, - 0, - &required_len, - NULL)) { - return false; - } - - if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) - return false; - - // Allocate buffer for the structure - PSP_DEVICE_INTERFACE_DETAIL_DATA buffer = - reinterpret_cast(malloc(required_len)); - - if (NULL == buffer) { - SetLastError(ERROR_OUTOFMEMORY); - return false; - } - - buffer->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); - - // Retrieve the information from Plug and Play. - if (SetupDiGetDeviceInterfaceDetail(hardware_dev_info, - dev_info_data, - buffer, - required_len, - &required_len, - NULL)) { - *dev_info_detail_data = buffer; - return true; - } else { - // Free the buffer if this call failed - free(buffer); - - return false; - } -} - -bool GetUsbDeviceName(HDEVINFO hardware_dev_info, - PSP_DEVICE_INTERFACE_DATA dev_info_data, - std::wstring* name) { - PSP_DEVICE_INTERFACE_DETAIL_DATA func_class_dev_data = NULL; - if (!GetUsbDeviceDetails(hardware_dev_info, - dev_info_data, - &func_class_dev_data)) { - return false; - } - - try { - *name = func_class_dev_data->DevicePath; - } catch (...) { - SetLastError(ERROR_OUTOFMEMORY); - } - - free(func_class_dev_data); - - return !name->empty(); -} +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \file + This file consists of implementation of helper routines used + in the API. +*/ + +#include "stdafx.h" +#include "adb_api.h" +#include "adb_helper_routines.h" +#include "adb_interface_enum.h" + +bool EnumerateDeviceInterfaces(HDEVINFO hardware_dev_info, + GUID class_id, + bool exclude_removed, + bool active_only, + AdbEnumInterfaceArray* interfaces) { + AdbEnumInterfaceArray tmp; + bool ret = false; + + // Enumerate interfaces on this device + for (ULONG index = 0; ; index++) { + SP_DEVICE_INTERFACE_DATA interface_data; + interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + // SetupDiEnumDeviceInterfaces() returns information about device + // interfaces exposed by one or more devices defined by our interface + // class. Each call returns information about one interface. The routine + // can be called repeatedly to get information about several interfaces + // exposed by one or more devices. + if (SetupDiEnumDeviceInterfaces(hardware_dev_info, + 0, + &class_id, + index, + &interface_data)) { + // Satisfy "exclude removed" and "active only" filters. + if ((!exclude_removed || (0 == (interface_data.Flags & SPINT_REMOVED))) && + (!active_only || (interface_data.Flags & SPINT_ACTIVE))) { + std::wstring dev_name; + + if (GetUsbDeviceName(hardware_dev_info, &interface_data, &dev_name)) { + try { + // Add new entry to the array + tmp.push_back(AdbInstanceEnumEntry(dev_name.c_str(), + interface_data.InterfaceClassGuid, + interface_data.Flags)); + } catch (... ) { + SetLastError(ERROR_OUTOFMEMORY); + break; + } + } else { + // Something went wrong in getting device name + break; + } + } + } else { + if (ERROR_NO_MORE_ITEMS == GetLastError()) { + // There are no more items in the list. Enum is completed. + ret = true; + break; + } else { + // Something went wrong in SDK enum + break; + } + } + } + + // On success, swap temp array with the returning one + if (ret) + interfaces->swap(tmp); + + return ret; +} + +bool EnumerateDeviceInterfaces(GUID class_id, + ULONG flags, + bool exclude_removed, + bool active_only, + AdbEnumInterfaceArray* interfaces) { + // Open a handle to the plug and play dev node. + // SetupDiGetClassDevs() returns a device information set that + // contains info on all installed devices of a specified class. + HDEVINFO hardware_dev_info = + SetupDiGetClassDevs(&class_id, NULL, NULL, flags); + + bool ret = false; + + if (INVALID_HANDLE_VALUE != hardware_dev_info) { + // Do the enum + ret = EnumerateDeviceInterfaces(hardware_dev_info, + class_id, + exclude_removed, + active_only, + interfaces); + + // Preserve last error accross hardware_dev_info destruction + ULONG error_to_report = ret ? NO_ERROR : GetLastError(); + + SetupDiDestroyDeviceInfoList(hardware_dev_info); + + if (NO_ERROR != error_to_report) + SetLastError(error_to_report); + } + + return ret; +} + +bool GetUsbDeviceDetails( + HDEVINFO hardware_dev_info, + PSP_DEVICE_INTERFACE_DATA dev_info_data, + PSP_DEVICE_INTERFACE_DETAIL_DATA* dev_info_detail_data) { + ULONG required_len = 0; + + // First query for the structure size. At this point we expect this call + // to fail with ERROR_INSUFFICIENT_BUFFER error code. + if (SetupDiGetDeviceInterfaceDetail(hardware_dev_info, + dev_info_data, + NULL, + 0, + &required_len, + NULL)) { + return false; + } + + if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) + return false; + + // Allocate buffer for the structure + PSP_DEVICE_INTERFACE_DETAIL_DATA buffer = + reinterpret_cast(malloc(required_len)); + + if (NULL == buffer) { + SetLastError(ERROR_OUTOFMEMORY); + return false; + } + + buffer->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + // Retrieve the information from Plug and Play. + if (SetupDiGetDeviceInterfaceDetail(hardware_dev_info, + dev_info_data, + buffer, + required_len, + &required_len, + NULL)) { + *dev_info_detail_data = buffer; + return true; + } else { + // Free the buffer if this call failed + free(buffer); + + return false; + } +} + +bool GetUsbDeviceName(HDEVINFO hardware_dev_info, + PSP_DEVICE_INTERFACE_DATA dev_info_data, + std::wstring* name) { + PSP_DEVICE_INTERFACE_DETAIL_DATA func_class_dev_data = NULL; + if (!GetUsbDeviceDetails(hardware_dev_info, + dev_info_data, + &func_class_dev_data)) { + return false; + } + + try { + *name = func_class_dev_data->DevicePath; + } catch (...) { + SetLastError(ERROR_OUTOFMEMORY); + } + + free(func_class_dev_data); + + return !name->empty(); +} diff --git a/host/windows/usb/api/adb_helper_routines.h b/host/windows/usb/api/adb_helper_routines.h index 18709f045..68a20a9b7 100644 --- a/host/windows/usb/api/adb_helper_routines.h +++ b/host/windows/usb/api/adb_helper_routines.h @@ -1,126 +1,109 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_USB_API_ADB_HELPER_ROUTINES_H__ -#define ANDROID_USB_API_ADB_HELPER_ROUTINES_H__ -/** \file - This file consists of declarations of helper routines used - in the API. -*/ - -#include "adb_api_private_defines.h" - -/** \brief Converts access type and share mode from our enum into - SDK - complient values. - - @param access_type[in] Enumerated access type - @param sharing_mode[in] Enumerated share mode - @param desired_access[out] Will receive SDK - complient desired access - flags. This parameter can be NULL. - @param desired_sharing[out] Will receive SDK - complient share mode. - This parameter can be NULL. - @return True on success, false on failure, in which case GetLastError() - provides extended information about the error that occurred. -*/ -bool GetSDKComplientParam(AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode, - ULONG* desired_access, - ULONG* desired_sharing); - -/** \brief - Given the hardware device information enumerates interfaces for this device - - @param hardware_dev_info[in] A handle to hardware device information obtained - from PnP manager via SetupDiGetClassDevs() - @param class_id[in] Device class ID how it is specified by our USB driver - @param exclude_removed[in] If true interfaces with SPINT_REMOVED flag set - will be not included in the enumeration. - @param active_only[in] If 'true' only active interfaces (with flag - SPINT_ACTIVE set) will be included in the enumeration. - @param interfaces[out] Upon successfull completion will consist of array of - all interfaces found for this device (matching all filters). - @return True on success, false on failure, in which case GetLastError() - provides extended information about the error that occurred. -*/ -bool EnumerateDeviceInterfaces(HDEVINFO hardware_dev_info, - GUID class_id, - bool exclude_removed, - bool active_only, - AdbEnumInterfaceArray* interfaces); - -/** \brief Enumerates all interfaces for our device class - - This routine uses SetupDiGetClassDevs to get our device info and calls - EnumerateDeviceInterfaces to perform the enumeration. - @param class_id[in] Device class ID how it is specified by our USB driver - @param flags[in] Flags to pass to SetupDiGetClassDevs to filter devices. See - SetupDiGetClassDevs() in SDK for more info on these flags. - @param exclude_removed[in] If true interfaces with SPINT_REMOVED flag set - will be not included in the enumeration. - @param active_only[in] If 'true' only active interfaces (with flag - SPINT_ACTIVE set) will be included in the enumeration. - @param interfaces[out] Upon successfull completion will consist of array of - all interfaces found for this device (matching all filters). - @return True on success, false on failure, in which case GetLastError() - provides extended information about the error that occurred. -*/ -bool EnumerateDeviceInterfaces(GUID class_id, - ULONG flags, - bool exclude_removed, - bool active_only, - AdbEnumInterfaceArray* interfaces); - -/** \brief Given the hardware device information and data gets data details - - Given the hardware_dev_info, representing a handle to the plug and - play information, and dev_info_data, representing a specific usb device, - gets detailed data about the device (interface). - @param hardware_dev_info[in] A handle to hardware device information obtained - from PnP manager via SetupDiGetClassDevs() - @param dev_info_data[in] Device information data obtained via call to - SetupDiEnumDeviceInterfaces() - @param dev_info_detail_data[out] Upon successfull completion will consist of - the detailed data about device interface. This routine always - allocates memory for the output structure so content of this pointer - doesn't matter and will be overwritten by this routine. The caller - of this method is responsible for freeing allocated data using free() - routine. - @return True on success, false on failure, in which case GetLastError() - provides extended information about the error that occurred. -*/ -bool GetUsbDeviceDetails(HDEVINFO hardware_dev_info, - PSP_DEVICE_INTERFACE_DATA dev_info_data, - PSP_DEVICE_INTERFACE_DETAIL_DATA* dev_info_detail_data); - -/** \brief Given the hardware device information and data gets device name. - - Given the hardware_dev_info, representing a handle to the plug and - play information, and dev_info_data, representing a specific usb device, - gets device name. This routine uses GetUsbDeviceDetails to extract device - name. - @param hardware_dev_info[in] A handle to hardware device information obtained - from PnP manager via SetupDiGetClassDevs() - @param dev_info_data[in] Device information data obtained via call to - SetupDiEnumDeviceInterfaces() - @param name[out] Upon successfull completion will have name for the device. - @return True on success, false on failure, in which case GetLastError() - provides extended information about the error that occurred. -*/ -bool GetUsbDeviceName(HDEVINFO hardware_dev_info, - PSP_DEVICE_INTERFACE_DATA dev_info_data, - std::wstring* name); - -#endif // ANDROID_USB_API_ADB_HELPER_ROUTINES_H__ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_USB_API_ADB_HELPER_ROUTINES_H__ +#define ANDROID_USB_API_ADB_HELPER_ROUTINES_H__ +/** \file + This file consists of declarations of helper routines used + in the API. +*/ + +#include "adb_api_private_defines.h" + +/** \brief Given the hardware device information enumerates interfaces for + this device. + + @param[in] hardware_dev_info A handle to hardware device information obtained + from PnP manager via SetupDiGetClassDevs() + @param[in] class_id Device class ID how it is specified by our USB driver. + @param[in] exclude_removed If true interfaces with SPINT_REMOVED flag set + will be not included in the enumeration. + @param[in] active_only If true only active interfaces (with flag + SPINT_ACTIVE set) will be included in the enumeration. + @param[out] interfaces Upon successfull completion will consist of array of + all interfaces found for this device (matching all filters). + @return True on success, false on failure, in which case GetLastError() + provides extended information about the error that occurred. +*/ +bool EnumerateDeviceInterfaces(HDEVINFO hardware_dev_info, + GUID class_id, + bool exclude_removed, + bool active_only, + AdbEnumInterfaceArray* interfaces); + +/** \brief Enumerates all interfaces for our device class. + + This routine uses SetupDiGetClassDevs to get our device info and calls + EnumerateDeviceInterfaces to perform the enumeration. + @param[in] class_id Device class ID how it is specified by our USB driver + @param[in] flags Flags to pass to SetupDiGetClassDevs to filter devices. See + SetupDiGetClassDevs() in SDK for more info on these flags. + @param[in] exclude_removed If true interfaces with SPINT_REMOVED flag set + will be not included in the enumeration. + @param[in] active_only If true only active interfaces (with flag + SPINT_ACTIVE set) will be included in the enumeration. + @param[out] interfaces Upon successfull completion will consist of array of + all interfaces found for this device (matching all filters). + @return True on success, false on failure, in which case GetLastError() + provides extended information about the error that occurred. +*/ +bool EnumerateDeviceInterfaces(GUID class_id, + ULONG flags, + bool exclude_removed, + bool active_only, + AdbEnumInterfaceArray* interfaces); + +/** \brief Given the hardware device information and data gets data details. + + Given the hardware_dev_info, representing a handle to the plug and + play information, and dev_info_data, representing a specific usb device, + gets detailed data about the device (interface). + @param[in] hardware_dev_info A handle to hardware device information obtained + from PnP manager via SetupDiGetClassDevs() + @param[in] dev_info_data Device information data obtained via call to + SetupDiEnumDeviceInterfaces() + @param[out] dev_info_detail_data Upon successfull completion will consist of + the detailed data about device interface. This routine always + allocates memory for the output structure so content of this pointer + doesn't matter and will be overwritten by this routine. The caller + of this method is responsible for freeing allocated data using free() + routine. + @return True on success, false on failure, in which case GetLastError() + provides extended information about the error that occurred. +*/ +bool GetUsbDeviceDetails(HDEVINFO hardware_dev_info, + PSP_DEVICE_INTERFACE_DATA dev_info_data, + PSP_DEVICE_INTERFACE_DETAIL_DATA* dev_info_detail_data); + +/** \brief Given the hardware device information and data gets device name. + + Given the hardware_dev_info, representing a handle to the plug and + play information, and dev_info_data, representing a specific usb device, + gets device name. This routine uses GetUsbDeviceDetails to extract device + name. + @param[in] hardware_dev_info A handle to hardware device information obtained + from PnP manager via SetupDiGetClassDevs() + @param[in] dev_info_data Device information data obtained via call to + SetupDiEnumDeviceInterfaces() + @param[out] name Upon successfull completion will have name for the device. + @return True on success, false on failure, in which case GetLastError() + provides extended information about the error that occurred. +*/ +bool GetUsbDeviceName(HDEVINFO hardware_dev_info, + PSP_DEVICE_INTERFACE_DATA dev_info_data, + std::wstring* name); + +#endif // ANDROID_USB_API_ADB_HELPER_ROUTINES_H__ diff --git a/host/windows/usb/api/adb_interface.cpp b/host/windows/usb/api/adb_interface.cpp index 9369e13e9..9b073a4df 100644 --- a/host/windows/usb/api/adb_interface.cpp +++ b/host/windows/usb/api/adb_interface.cpp @@ -1,344 +1,413 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - This file consists of implementation of class AdbInterfaceObject that - encapsulates an interface on our USB device. -*/ - -#include "stdafx.h" -#include "adb_interface.h" -#include "adb_endpoint_object.h" - -AdbInterfaceObject::AdbInterfaceObject(const wchar_t* interf_name) - : AdbObjectHandle(AdbObjectTypeInterface), - interface_name_(interf_name) { - ATLASSERT(NULL != interf_name); -} - -AdbInterfaceObject::~AdbInterfaceObject() { -} - -ADBAPIHANDLE AdbInterfaceObject::CreateHandle() { - // Open USB device for this intefface - HANDLE usb_device_handle = CreateFile(interface_name().c_str(), - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - 0, - NULL); - if (INVALID_HANDLE_VALUE == usb_device_handle) - return NULL; - - // Now, we ensured that our usb device / interface is up and running. - // Lets collect device, interface and pipe information - bool ok = true; - if (!CacheUsbDeviceDescriptor(usb_device_handle) || - !CacheUsbConfigurationDescriptor(usb_device_handle) || - !CacheUsbInterfaceDescriptor(usb_device_handle)) { - ok = false; - } - - // Preserve error accross handle close - ULONG error = ok ? NO_ERROR : GetLastError(); - - ::CloseHandle(usb_device_handle); - - if (NO_ERROR != error) - SetLastError(error); - - if (!ok) - return false; - - return AdbObjectHandle::CreateHandle(); -} - -bool AdbInterfaceObject::GetInterfaceName(void* buffer, - unsigned long* buffer_char_size, - bool ansi) { - // Lets see if buffer is big enough - ULONG name_len = static_cast(interface_name_.length() + 1); - if ((NULL == buffer) || (*buffer_char_size < name_len)) { - *buffer_char_size = name_len; - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return false; - } - - if (!ansi) { - // If user asked for wide char name just return it - wcscpy(reinterpret_cast(buffer), interface_name().c_str()); - return true; - } - - // We need to convert name from wide char to ansi string - int res = WideCharToMultiByte(CP_ACP, - 0, - interface_name().c_str(), - static_cast(name_len), - reinterpret_cast(buffer), - static_cast(*buffer_char_size), - NULL, - NULL); - return (res != 0); -} - -bool AdbInterfaceObject::GetSerialNumber(void* buffer, - unsigned long* buffer_char_size, - bool ansi) { - if (!IsOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - // Open USB device for this intefface - HANDLE usb_device_handle = CreateFile(interface_name().c_str(), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - 0, - NULL); - if (INVALID_HANDLE_VALUE == usb_device_handle) - return NULL; - - WCHAR serial_number[512]; - - // Send IOCTL - DWORD ret_bytes = 0; - BOOL ret = DeviceIoControl(usb_device_handle, - ADB_IOCTL_GET_SERIAL_NUMBER, - NULL, 0, - serial_number, sizeof(serial_number), - &ret_bytes, - NULL); - - // Preserve error accross CloseHandle - ULONG error = ret ? NO_ERROR : GetLastError(); - - ::CloseHandle(usb_device_handle); - - if (NO_ERROR != error) { - SetLastError(error); - return false; - } - - unsigned long str_len = - static_cast(wcslen(serial_number) + 1); - - if ((NULL == buffer) || (*buffer_char_size < str_len)) { - *buffer_char_size = str_len; - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return false; - } - - if (!ansi) { - // If user asked for wide char name just return it - wcscpy(reinterpret_cast(buffer), serial_number); - return true; - } - - // We need to convert name from wide char to ansi string - int res = WideCharToMultiByte(CP_ACP, - 0, - serial_number, - static_cast(str_len), - reinterpret_cast(buffer), - static_cast(*buffer_char_size), - NULL, - NULL); - return (res != 0); -} - -bool AdbInterfaceObject::GetUsbDeviceDescriptor(USB_DEVICE_DESCRIPTOR* desc) { - if (!IsOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - CopyMemory(desc, usb_device_descriptor(), sizeof(USB_DEVICE_DESCRIPTOR)); - - return true; -} - -bool AdbInterfaceObject::GetUsbConfigurationDescriptor( - USB_CONFIGURATION_DESCRIPTOR* desc) { - if (!IsOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - CopyMemory(desc, usb_config_descriptor(), - sizeof(USB_CONFIGURATION_DESCRIPTOR)); - - return true; -} - -bool AdbInterfaceObject::GetUsbInterfaceDescriptor( - USB_INTERFACE_DESCRIPTOR* desc) { - if (!IsOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - CopyMemory(desc, usb_interface_descriptor(), sizeof(USB_INTERFACE_DESCRIPTOR)); - - return true; -} - -bool AdbInterfaceObject::GetEndpointInformation(UCHAR endpoint_index, - AdbEndpointInformation* info) { - if (!IsOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - // Open USB device for this intefface - HANDLE usb_device_handle = CreateFile(interface_name().c_str(), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - 0, - NULL); - if (INVALID_HANDLE_VALUE == usb_device_handle) - return NULL; - - // Init ICTL param - AdbQueryEndpointInformation param; - param.endpoint_index = endpoint_index; - - // Send IOCTL - DWORD ret_bytes = 0; - BOOL ret = DeviceIoControl(usb_device_handle, - ADB_IOCTL_GET_ENDPOINT_INFORMATION, - ¶m, sizeof(param), - info, sizeof(AdbEndpointInformation), - &ret_bytes, - NULL); - ATLASSERT(!ret || (sizeof(AdbEndpointInformation) == ret_bytes)); - - // Preserve error accross CloseHandle - ULONG error = ret ? NO_ERROR : GetLastError(); - - ::CloseHandle(usb_device_handle); - - if (NO_ERROR != error) - SetLastError(error); - - return ret ? true : false; -} - -ADBAPIHANDLE AdbInterfaceObject::OpenEndpoint( - UCHAR endpoint_index, - AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode) { - // Convert index into name - std::wstring endpoint_name; - - try { - if (ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index) { - endpoint_name = DEVICE_BULK_READ_PIPE_NAME; - } else if (ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX == endpoint_index) { - endpoint_name = DEVICE_BULK_WRITE_PIPE_NAME; - } else { - wchar_t fmt[265]; - swprintf(fmt, L"%ws%u", DEVICE_PIPE_NAME_PREFIX, endpoint_index); - endpoint_name = fmt; - } - } catch (...) { - SetLastError(ERROR_OUTOFMEMORY); - return NULL; - } - - return OpenEndpoint(endpoint_name.c_str(), access_type, sharing_mode); -} - -ADBAPIHANDLE AdbInterfaceObject::OpenEndpoint( - const wchar_t* endpoint_name, - AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode) { - if (!IsOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - AdbEndpointObject* adb_endpoint = NULL; - - try { - adb_endpoint = new AdbEndpointObject(this); - } catch (...) { - SetLastError(ERROR_OUTOFMEMORY); - return NULL; - } - - // Build full path to the object - std::wstring endpoint_path = interface_name(); - endpoint_path += L"\\"; - endpoint_path += endpoint_name; - - ADBAPIHANDLE ret = adb_endpoint->CreateHandle(endpoint_path.c_str(), - access_type, - sharing_mode); - - adb_endpoint->Release(); - - return ret; -} - -bool AdbInterfaceObject::CacheUsbDeviceDescriptor(HANDLE usb_device_handle) { - DWORD ret_bytes = 0; - BOOL ret = DeviceIoControl(usb_device_handle, - ADB_IOCTL_GET_USB_DEVICE_DESCRIPTOR, - NULL, 0, - &usb_device_descriptor_, - sizeof(usb_device_descriptor_), - &ret_bytes, - NULL); - ATLASSERT(!ret || (sizeof(USB_DEVICE_DESCRIPTOR) == ret_bytes)); - - return ret ? true : false; -} - -bool AdbInterfaceObject::CacheUsbConfigurationDescriptor( - HANDLE usb_device_handle) { - DWORD ret_bytes = 0; - BOOL ret = DeviceIoControl(usb_device_handle, - ADB_IOCTL_GET_USB_CONFIGURATION_DESCRIPTOR, - NULL, 0, - &usb_config_descriptor_, - sizeof(usb_config_descriptor_), - &ret_bytes, - NULL); - ATLASSERT(!ret || (sizeof(USB_CONFIGURATION_DESCRIPTOR) == ret_bytes)); - - return ret ? true : false; -} - -bool AdbInterfaceObject::CacheUsbInterfaceDescriptor( - HANDLE usb_device_handle) { - DWORD ret_bytes = 0; - BOOL ret = DeviceIoControl(usb_device_handle, - ADB_IOCTL_GET_USB_INTERFACE_DESCRIPTOR, - NULL, 0, - &usb_interface_descriptor_, - sizeof(usb_interface_descriptor_), - &ret_bytes, - NULL); - ATLASSERT(!ret || (sizeof(USB_INTERFACE_DESCRIPTOR) == ret_bytes)); - - return ret ? true : false; -} +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \file + This file consists of implementation of class AdbInterfaceObject that + encapsulates an interface on our USB device. +*/ + +#include "stdafx.h" +#include "adb_interface.h" +#include "adb_endpoint_object.h" + +AdbInterfaceObject::AdbInterfaceObject(const wchar_t* interf_name) + : AdbObjectHandle(AdbObjectTypeInterface), + interface_name_(interf_name), + usb_device_handle_(INVALID_HANDLE_VALUE), + winusb_handle_(NULL), + interface_number_(0xFF), + def_read_endpoint_(0xFF), + read_endpoint_id_(0xFF), + def_write_endpoint_(0xFF), + write_endpoint_id_(0xFF) { + ATLASSERT(NULL != interf_name); +} + +AdbInterfaceObject::~AdbInterfaceObject() { + ATLASSERT(NULL == winusb_handle_); + ATLASSERT(INVALID_HANDLE_VALUE == usb_device_handle_); +} + +ADBAPIHANDLE AdbInterfaceObject::CreateHandle() { + // Open USB device for this inteface Note that WinUsb API + // requires the handle to be opened for overlapped I/O. + usb_device_handle_ = CreateFile(interface_name().c_str(), + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); + if (INVALID_HANDLE_VALUE == usb_device_handle_) + return NULL; + + // Initialize WinUSB API for this interface + if (!WinUsb_Initialize(usb_device_handle_, &winusb_handle_)) + return NULL; + + // Cache current interface number that will be used in + // WinUsb_Xxx calls performed on this interface. + if (!WinUsb_GetCurrentAlternateSetting(winusb_handle(), &interface_number_)) + return false; + + // Cache interface properties + unsigned long bytes_written; + + // Cache USB device descriptor + if (!WinUsb_GetDescriptor(winusb_handle(), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, + reinterpret_cast(&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(&usb_config_descriptor_), + sizeof(usb_config_descriptor_), &bytes_written)) { + return false; + } + + // Cache USB interface descriptor + if (!WinUsb_QueryInterfaceSettings(winusb_handle(), interface_number(), + &usb_interface_descriptor_)) { + return false; + } + + // Save indexes and IDs for bulk read / write endpoints. We will use them to + // convert ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX and + // ADB_QUERY_BULK_READ_ENDPOINT_INDEX into actual endpoint indexes and IDs. + for (UCHAR endpoint = 0; endpoint < usb_interface_descriptor_.bNumEndpoints; + endpoint++) { + // Get endpoint information + WINUSB_PIPE_INFORMATION pipe_info; + if (!WinUsb_QueryPipe(winusb_handle(), interface_number(), endpoint, + &pipe_info)) { + return false; + } + + if (UsbdPipeTypeBulk == pipe_info.PipeType) { + // This is a bulk endpoint. Cache its index and ID. + if (0 != (pipe_info.PipeId & USB_ENDPOINT_DIRECTION_MASK)) { + // Use this endpoint as default bulk read endpoint + ATLASSERT(0xFF == def_read_endpoint_); + def_read_endpoint_ = endpoint; + read_endpoint_id_ = pipe_info.PipeId; + } else { + // Use this endpoint as default bulk write endpoint + ATLASSERT(0xFF == def_write_endpoint_); + def_write_endpoint_ = endpoint; + write_endpoint_id_ = pipe_info.PipeId; + } + } + } + + return AdbObjectHandle::CreateHandle(); +} + +bool AdbInterfaceObject::CloseHandle() { + if (NULL != winusb_handle_) { + WinUsb_Free(winusb_handle_); + winusb_handle_ = NULL; + } + if (INVALID_HANDLE_VALUE != usb_device_handle_) { + ::CloseHandle(usb_device_handle_); + usb_device_handle_ = INVALID_HANDLE_VALUE; + } + + return AdbObjectHandle::CloseHandle(); +} + +bool AdbInterfaceObject::GetInterfaceName(void* buffer, + unsigned long* buffer_char_size, + bool ansi) { + if (NULL == buffer_char_size) { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // Lets see if buffer is big enough + ULONG name_len = static_cast(interface_name_.length() + 1); + if ((NULL == buffer) || (*buffer_char_size < name_len)) { + *buffer_char_size = name_len; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return false; + } + + if (!ansi) { + // If user asked for wide char name just return it + wcscpy(reinterpret_cast(buffer), interface_name().c_str()); + return true; + } + + // We need to convert name from wide char to ansi string + int res = WideCharToMultiByte(CP_ACP, + 0, + interface_name().c_str(), + static_cast(name_len), + reinterpret_cast(buffer), + static_cast(*buffer_char_size), + NULL, + NULL); + return (res != 0); +} + +bool AdbInterfaceObject::GetSerialNumber(void* buffer, + unsigned long* buffer_char_size, + bool ansi) { + if (!IsOpened()) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + if (NULL == buffer_char_size) { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // Calculate serial number string size. Note that WinUsb_GetDescriptor + // API will not return number of bytes needed to store serial number + // string. So we will have to start with a reasonably large preallocated + // buffer and then loop through WinUsb_GetDescriptor calls, doubling up + // string buffer size every time ERROR_INSUFFICIENT_BUFFER is returned. + union { + // Preallocate reasonably sized buffer on the stack. + char small_buffer[64]; + USB_STRING_DESCRIPTOR initial_ser_num; + }; + USB_STRING_DESCRIPTOR* ser_num = &initial_ser_num; + // Buffer byte size + unsigned long ser_num_size = sizeof(small_buffer); + // After successful call to WinUsb_GetDescriptor will contain serial + // number descriptor size. + unsigned long bytes_written; + while (!WinUsb_GetDescriptor(winusb_handle(), USB_STRING_DESCRIPTOR_TYPE, + usb_device_descriptor_.iSerialNumber, + 0x0409, // English (US) + reinterpret_cast(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(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(ser_num); + try { + ser_num = + reinterpret_cast(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(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(str_len), + reinterpret_cast(buffer), + static_cast(*buffer_char_size), + NULL, NULL)) { + // Zero-terminate output string. + reinterpret_cast(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(buffer)[str_len] = L'\0'; + } + + if (ser_num != &initial_ser_num) + delete[] reinterpret_cast(ser_num); + + return ret; +} + +bool AdbInterfaceObject::GetUsbDeviceDescriptor(USB_DEVICE_DESCRIPTOR* desc) { + if (!IsOpened()) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + if (NULL == desc) { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + CopyMemory(desc, usb_device_descriptor(), sizeof(USB_DEVICE_DESCRIPTOR)); + + return true; +} + +bool AdbInterfaceObject::GetUsbConfigurationDescriptor( + USB_CONFIGURATION_DESCRIPTOR* desc) { + if (!IsOpened()) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + if (NULL == desc) { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + CopyMemory(desc, usb_config_descriptor(), + sizeof(USB_CONFIGURATION_DESCRIPTOR)); + + return true; +} + +bool AdbInterfaceObject::GetUsbInterfaceDescriptor( + USB_INTERFACE_DESCRIPTOR* desc) { + if (!IsOpened()) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + if (NULL == desc) { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + CopyMemory(desc, usb_interface_descriptor(), sizeof(USB_INTERFACE_DESCRIPTOR)); + + return true; +} + +bool AdbInterfaceObject::GetEndpointInformation(UCHAR endpoint_index, + AdbEndpointInformation* info) { + if (!IsOpened()) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + if (NULL == info) { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // Get actual endpoint index for predefined read / write endpoints. + if (ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index) { + endpoint_index = def_read_endpoint_; + } else if (ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX == endpoint_index) { + endpoint_index = def_write_endpoint_; + } + + // Query endpoint information + WINUSB_PIPE_INFORMATION pipe_info; + if (!WinUsb_QueryPipe(winusb_handle(), interface_number(), endpoint_index, + &pipe_info)) { + return false; + } + + // Save endpoint information into output. + info->max_packet_size = pipe_info.MaximumPacketSize; + info->max_transfer_size = 0xFFFFFFFF; + info->endpoint_address = pipe_info.PipeId; + info->polling_interval = pipe_info.Interval; + info->setting_index = interface_number(); + switch (pipe_info.PipeType) { + case UsbdPipeTypeControl: + info->endpoint_type = AdbEndpointTypeControl; + break; + + case UsbdPipeTypeIsochronous: + info->endpoint_type = AdbEndpointTypeIsochronous; + break; + + case UsbdPipeTypeBulk: + info->endpoint_type = AdbEndpointTypeBulk; + break; + + case UsbdPipeTypeInterrupt: + info->endpoint_type = AdbEndpointTypeInterrupt; + break; + + default: + info->endpoint_type = AdbEndpointTypeInvalid; + break; + } + + return true; +} + +ADBAPIHANDLE AdbInterfaceObject::OpenEndpoint( + UCHAR endpoint_index, + AdbOpenAccessType access_type, + AdbOpenSharingMode sharing_mode) { + // Convert index into id + UCHAR endpoint_id; + + if ((ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index) || + (def_read_endpoint_ == endpoint_index)) { + endpoint_id = read_endpoint_id_; + endpoint_index = def_read_endpoint_; + } else if ((ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX == endpoint_index) || + (def_write_endpoint_ == endpoint_index)) { + endpoint_id = write_endpoint_id_; + endpoint_index = def_write_endpoint_; + } else { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + return OpenEndpoint(endpoint_id, endpoint_index); +} + +ADBAPIHANDLE AdbInterfaceObject::OpenEndpoint(UCHAR endpoint_id, + UCHAR endpoint_index) { + if (!IsOpened()) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + AdbEndpointObject* adb_endpoint = NULL; + + try { + adb_endpoint = new AdbEndpointObject(this, endpoint_id, endpoint_index); + } catch (...) { + SetLastError(ERROR_OUTOFMEMORY); + return NULL; + } + + ADBAPIHANDLE ret = adb_endpoint->CreateHandle(); + + adb_endpoint->Release(); + + return ret; +} diff --git a/host/windows/usb/api/adb_interface.h b/host/windows/usb/api/adb_interface.h index cead45415..d428d12af 100644 --- a/host/windows/usb/api/adb_interface.h +++ b/host/windows/usb/api/adb_interface.h @@ -1,244 +1,258 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_USB_API_ADB_INTERFACE_H__ -#define ANDROID_USB_API_ADB_INTERFACE_H__ -/** \file - This file consists of declaration of class AdbInterfaceObject that - encapsulates an interface on our USB device. -*/ - -#include "adb_object_handle.h" - -/** Class AdbInterfaceObject encapsulates an interface on our USB device. -*/ -class AdbInterfaceObject : public AdbObjectHandle { - public: - /** \brief Constructs the object - - @param interf_name[in] Name of the interface - */ - explicit AdbInterfaceObject(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 ~AdbInterfaceObject(); - - 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 verify that - interface indeed exists and gather device, interface and pipe properties. - If this step succeeds then and only then AdbObjectHandle::CreateHandle - will be called. - @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 Gets interface device name. - - @param buffer[out] Buffer for the name. Can be NULL in which case - buffer_char_size will contain number of characters required to fit - the name. - @param buffer_char_size[in/out] 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 to fit the name. - @param ansi[in] 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. - */ - bool GetInterfaceName(void* buffer, - unsigned long* buffer_char_size, - bool ansi); - - /** \brief Gets serial number for interface's device. - - @param buffer[out] 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 buffer_char_size[in/out] 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 ansi[in] 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. - */ - bool GetSerialNumber(void* buffer, - unsigned long* buffer_char_size, - bool ansi); - - /** \brief Gets device descriptor for the USB device associated with - this interface. - - @param desc[out] Upon successful completion will have usb device - descriptor. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. - */ - bool GetUsbDeviceDescriptor(USB_DEVICE_DESCRIPTOR* desc); - - /** \brief Gets descriptor for the selected USB device configuration. - - @param desc[out] Upon successful completion will have usb device - configuration descriptor. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. - */ - bool GetUsbConfigurationDescriptor(USB_CONFIGURATION_DESCRIPTOR* desc); - - /** \brief Gets descriptor for this interface. - - @param desc[out] Upon successful completion will have interface - descriptor. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. - */ - bool GetUsbInterfaceDescriptor(USB_INTERFACE_DESCRIPTOR* desc); - - /** \brief Gets information about an endpoint on this interface. - - @param endpoint_index[in] 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 info[out] Upon successful completion will have endpoint information. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. - */ - bool GetEndpointInformation(UCHAR endpoint_index, AdbEndpointInformation* info); - - /** \brief Opens an endpoint on this interface. - - @param endpoint_index[in] 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 access_type[in] 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 sharing_mode[in] Desired share mode. In the current implementation - this parameter has no effect on the way endpoint is opened. It's - always shared for read / write. - @return Handle to the opened endpoint object or NULL on failure. - If NULL is returned GetLastError() provides extended information - about the error that occurred. - */ - ADBAPIHANDLE OpenEndpoint(UCHAR endpoint_index, - AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode); - - /** \brief Opens an endpoint on this interface. - - @param endpoint_name[in] Endpoint file name. - @param access_type[in] 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 sharing_mode[in] Desired share mode. In the current implementation - this parameter has no effect on the way endpoint is opened. It's - always shared for read / write. - @return Handle to the opened endpoint object or NULL on failure. - If NULL is returned GetLastError() provides extended information - about the error that occurred. - */ - ADBAPIHANDLE OpenEndpoint(const wchar_t* endpoint_name, - AdbOpenAccessType access_type, - AdbOpenSharingMode sharing_mode); - - private: - /** \brief Caches device descriptor for the USB device associated with - this interface. - - This method is called from CreateHandle method to cache some interface - information. - @param usb_device_handle[in] Handle to USB device. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. - */ - bool CacheUsbDeviceDescriptor(HANDLE usb_device_handle); - - /** \brief Caches descriptor for the selected USB device configuration. - - This method is called from CreateHandle method to cache some interface - information. - @param usb_device_handle[in] Handle to USB device. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. - */ - bool CacheUsbConfigurationDescriptor(HANDLE usb_device_handle); - - /** \brief Caches descriptor for this interface. - - This method is called from CreateHandle method to cache some interface - information. - @param usb_device_handle[in] Handle to USB device. - @return 'true' on success, 'false' on failure. If 'false' is returned - GetLastError() provides extended error information. - */ - bool CacheUsbInterfaceDescriptor(HANDLE usb_device_handle); - - public: - /// Gets name of the USB interface (device name) for this object - const std::wstring& interface_name() const { - return interface_name_; - } - - // This is a helper for extracting object from the AdbObjectHandleMap - static AdbObjectType Type() { - return AdbObjectTypeInterface; - } - - /// Gets cached usb device descriptor - const USB_DEVICE_DESCRIPTOR* usb_device_descriptor() const { - return &usb_device_descriptor_; - } - - /// Gets cached usb configuration descriptor - const USB_CONFIGURATION_DESCRIPTOR* usb_config_descriptor() const { - return &usb_config_descriptor_; - } - - /// Gets cached usb interface descriptor - const USB_INTERFACE_DESCRIPTOR* usb_interface_descriptor() const { - return &usb_interface_descriptor_; - } - -private: - /// Name of the USB interface (device name) for this object - std::wstring interface_name_; - - /// Cached usb device descriptor - USB_DEVICE_DESCRIPTOR usb_device_descriptor_; - - /// Cached usb configuration descriptor - USB_CONFIGURATION_DESCRIPTOR usb_config_descriptor_; - - /// Cached usb interface descriptor - USB_INTERFACE_DESCRIPTOR usb_interface_descriptor_; -}; - -#endif // ANDROID_USB_API_ADB_INTERFACE_H__ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_USB_API_ADB_INTERFACE_H__ +#define ANDROID_USB_API_ADB_INTERFACE_H__ +/** \file + This file consists of declaration of class AdbInterfaceObject that + encapsulates an interface on our USB device. +*/ + +#include "adb_object_handle.h" + +/** \brief Encapsulates an interface on our USB device. +*/ +class AdbInterfaceObject : public AdbObjectHandle { + public: + /** \brief Constructs the object. + + @param[in] interf_name Name of the interface + */ + explicit AdbInterfaceObject(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 ~AdbInterfaceObject(); + + 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 verify that + interface indeed exists and gather device, interface and pipe properties. + If this step succeeds then and only then AdbObjectHandle::CreateHandle + will be called. Note that in this method we will open a handle to the + USB device (saved in usb_device_handle_). The handle will be opened for + read and write access, and for read and write sharing mode. The handle + will be closed in CloseHandle method of this class. + @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 device and WinUsb handles 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(); + + /** \brief Gets interface device name. + + @param[out] buffer Buffer for the name. Can be NULL in which case + buffer_char_size will contain number of characters required to fit + the name. + @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 to fit 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. + */ + bool GetInterfaceName(void* buffer, + unsigned long* buffer_char_size, + bool ansi); + + /** \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. + */ + bool GetSerialNumber(void* buffer, + unsigned long* buffer_char_size, + bool ansi); + + /** \brief Gets device descriptor for the USB device associated with + this interface. + + @param[out] desc Upon successful completion will have usb device + descriptor. + @return true on success, false on failure. If false is returned + GetLastError() provides extended error information. + */ + bool GetUsbDeviceDescriptor(USB_DEVICE_DESCRIPTOR* desc); + + /** \brief Gets descriptor for the selected USB device configuration. + + @param[out] desc Upon successful completion will have usb device + configuration descriptor. + @return true on success, false on failure. If false is returned + GetLastError() provides extended error information. + */ + bool GetUsbConfigurationDescriptor(USB_CONFIGURATION_DESCRIPTOR* desc); + + /** \brief Gets descriptor for this interface. + + @param[out] desc Upon successful completion will have interface + descriptor. + @return true on success, false on failure. If false is returned + GetLastError() provides extended error information. + */ + bool GetUsbInterfaceDescriptor(USB_INTERFACE_DESCRIPTOR* desc); + + /** \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. + */ + 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. + */ + ADBAPIHANDLE OpenEndpoint(UCHAR endpoint_index, + AdbOpenAccessType access_type, + AdbOpenSharingMode sharing_mode); + + /** \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 name of the USB interface (device name) for this object + const std::wstring& interface_name() const { + return interface_name_; + } + + /// This is a helper for extracting object from the AdbObjectHandleMap + static AdbObjectType Type() { + return AdbObjectTypeInterface; + } + + /// Gets cached usb device descriptor + const USB_DEVICE_DESCRIPTOR* usb_device_descriptor() const { + return &usb_device_descriptor_; + } + + /// Gets cached usb configuration descriptor + const USB_CONFIGURATION_DESCRIPTOR* usb_config_descriptor() const { + return &usb_config_descriptor_; + } + + /// Gets cached usb interface descriptor + const USB_INTERFACE_DESCRIPTOR* usb_interface_descriptor() const { + return &usb_interface_descriptor_; + } + + /// 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_; + } + +private: + /// Name of the USB interface (device name) for this object + std::wstring interface_name_; + + /// Cached usb device descriptor + USB_DEVICE_DESCRIPTOR usb_device_descriptor_; + + /// Cached usb configuration descriptor + USB_CONFIGURATION_DESCRIPTOR usb_config_descriptor_; + + /// Cached usb interface descriptor + USB_INTERFACE_DESCRIPTOR usb_interface_descriptor_; + + /// 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_INTERFACE_H__ diff --git a/host/windows/usb/api/adb_interface_enum.cpp b/host/windows/usb/api/adb_interface_enum.cpp index 6e2808cc8..094cd3ea7 100644 --- a/host/windows/usb/api/adb_interface_enum.cpp +++ b/host/windows/usb/api/adb_interface_enum.cpp @@ -1,103 +1,103 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - This file consists of implementation of AdbInterfaceEnumObject class that - encapsulates enumerator of USB interfaces available through this API. -*/ - -#include "stdafx.h" -#include "adb_api.h" -#include "adb_interface_enum.h" -#include "adb_helper_routines.h" - -AdbInterfaceEnumObject::AdbInterfaceEnumObject() - : AdbObjectHandle(AdbObjectTypeInterfaceEnumerator) { - current_interface_ = interfaces_.begin(); -} - -AdbInterfaceEnumObject::~AdbInterfaceEnumObject() { -} - -bool AdbInterfaceEnumObject::InitializeEnum(GUID class_id, - bool exclude_not_present, - bool exclude_removed, - bool active_only) { - // Calc flags for SetupDiGetClassDevs - DWORD flags = DIGCF_DEVICEINTERFACE; - if (exclude_not_present) - flags |= DIGCF_PRESENT; - - // Do the enum - bool ret = EnumerateDeviceInterfaces(class_id, - flags, - exclude_removed, - active_only, - &interfaces_); - - // If enum was successfull set current enum pointer - // to the beginning of the array - if (ret) - current_interface_ = interfaces_.begin(); - - return ret; -} - -bool AdbInterfaceEnumObject::Next(AdbInterfaceInfo* info, ULONG* size) { - // Make sure that it's opened - if (!IsOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - ATLASSERT(NULL != size); - if (NULL == size) { - SetLastError(ERROR_INVALID_PARAMETER); - return false; - } - - // Lets see if enum is over - if (interfaces_.end() == current_interface_) { - SetLastError(ERROR_NO_MORE_ITEMS); - return false; - } - - AdbInstanceEnumEntry& entry = *current_interface_; - - // Big enough? - if ((NULL == info) || (*size < entry.GetFlatSize())) { - *size = entry.GetFlatSize(); - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return false; - } - - // All checks passed - entry.Save(info); - current_interface_++; - return true; -} - -bool AdbInterfaceEnumObject::Reset() { - // Make sure that it's opened - if (!IsOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - current_interface_ = interfaces_.begin(); - - return true; -} +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \file + This file consists of implementation of AdbInterfaceEnumObject class that + encapsulates enumerator of USB interfaces available through this API. +*/ + +#include "stdafx.h" +#include "adb_api.h" +#include "adb_interface_enum.h" +#include "adb_helper_routines.h" + +AdbInterfaceEnumObject::AdbInterfaceEnumObject() + : AdbObjectHandle(AdbObjectTypeInterfaceEnumerator) { + current_interface_ = interfaces_.begin(); +} + +AdbInterfaceEnumObject::~AdbInterfaceEnumObject() { +} + +bool AdbInterfaceEnumObject::InitializeEnum(GUID class_id, + bool exclude_not_present, + bool exclude_removed, + bool active_only) { + // Calc flags for SetupDiGetClassDevs + DWORD flags = DIGCF_DEVICEINTERFACE; + if (exclude_not_present) + flags |= DIGCF_PRESENT; + + // Do the enum + bool ret = EnumerateDeviceInterfaces(class_id, + flags, + exclude_removed, + active_only, + &interfaces_); + + // If enum was successfull set current enum pointer + // to the beginning of the array + if (ret) + current_interface_ = interfaces_.begin(); + + return ret; +} + +bool AdbInterfaceEnumObject::Next(AdbInterfaceInfo* info, ULONG* size) { + // Make sure that it's opened + if (!IsOpened()) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + ATLASSERT(NULL != size); + if (NULL == size) { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // Lets see if enum is over + if (interfaces_.end() == current_interface_) { + SetLastError(ERROR_NO_MORE_ITEMS); + return false; + } + + AdbInstanceEnumEntry& entry = *current_interface_; + + // Big enough? + if ((NULL == info) || (*size < entry.GetFlatSize())) { + *size = entry.GetFlatSize(); + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return false; + } + + // All checks passed + entry.Save(info); + current_interface_++; + return true; +} + +bool AdbInterfaceEnumObject::Reset() { + // Make sure that it's opened + if (!IsOpened()) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + current_interface_ = interfaces_.begin(); + + return true; +} diff --git a/host/windows/usb/api/adb_interface_enum.h b/host/windows/usb/api/adb_interface_enum.h index f46b31b3a..3dda0b11d 100644 --- a/host/windows/usb/api/adb_interface_enum.h +++ b/host/windows/usb/api/adb_interface_enum.h @@ -1,101 +1,98 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_USB_API_ADB_INTERFACE_ENUM_H__ -#define ANDROID_USB_API_ADB_INTERFACE_ENUM_H__ -/** \file - This file consists of declaration of AdbInterfaceEnumObject class that - encapsulates enumerator of USB interfaces available through this API. -*/ - -#include "adb_object_handle.h" - -/** Class AdbInterfaceEnumObject encapsulates enumerator of USB - interfaces available through this API. -*/ -class AdbInterfaceEnumObject : public AdbObjectHandle { - public: - /** \brief Constructs the object. - */ - AdbInterfaceEnumObject(); - - 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 ~AdbInterfaceEnumObject(); - - public: - /** \brief Enumerates all interfaces for our device class - - This routine uses SetupDiGetClassDevs to get our device info and calls - EnumerateDeviceInterfaces to perform the enumeration. - @param class_id[in] Device class ID that is specified by our USB driver - @param exclude_not_present[in] If set include only those devices that are - currently present. - @param exclude_removed[in] If true interfaces with SPINT_REMOVED flag set - will be not included in the enumeration. - @param active_only[in] If 'true' only active interfaces (with flag - SPINT_ACTIVE set) will be included in the enumeration. - @return True on success, false on failure, in which case GetLastError() - provides extended information about the error that occurred. - */ - bool InitializeEnum(GUID class_id, - bool exclude_not_present, - bool exclude_removed, - bool active_only); - - /** \brief Gets next enumerated interface information - - @param info[out] Upon successful completion will receive interface - information. Can be NULL. If it is NULL, upon return from this - method *size will have memory size required to fit this entry. - @param size[in,out]. On the way in provides size of the memory buffer - addressed by info param. On the way out (only if buffer is not - big enough) will provide memory size required to fit this entry. - @return true on success, false on error. If false is returned - GetLastError() provides extended information about the error that - occurred. ERROR_INSUFFICIENT_BUFFER indicates that buffer provided - in info param was not big enough and *size specifies memory size - required to fit this entry. ERROR_NO_MORE_ITEMS indicates that - enumeration is over and there are no more entries to return. - */ - bool Next(AdbInterfaceInfo* info, ULONG* size); - - /** \brief Makes enumerator to start from the beginning. - - @return true on success, false on error. If false is returned - GetLastError() provides extended information about the error that - occurred. - */ - bool Reset(); - - // This is a helper for extracting object from the AdbObjectHandleMap - static AdbObjectType Type() { - return AdbObjectTypeInterfaceEnumerator; - } - - protected: - /// Array of interfaces enumerated with this object - AdbEnumInterfaceArray interfaces_; - - /// Current enumerator - AdbEnumInterfaceArray::iterator current_interface_; -}; - -#endif // ANDROID_USB_API_ADB_INTERFACE_ENUM_H__ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_USB_API_ADB_INTERFACE_ENUM_H__ +#define ANDROID_USB_API_ADB_INTERFACE_ENUM_H__ +/** \file + This file consists of declaration of AdbInterfaceEnumObject class that + encapsulates enumerator of USB interfaces available through this API. +*/ + +#include "adb_object_handle.h" + +/** \brief Enumerator of USB interfaces available through this API. +*/ +class AdbInterfaceEnumObject : public AdbObjectHandle { + public: + /** \brief Constructs the object. + */ + AdbInterfaceEnumObject(); + + 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 ~AdbInterfaceEnumObject(); + + public: + /** \brief Enumerates all interfaces for the given device class. + + This routine uses SetupDiGetClassDevs to get our device info and calls + EnumerateDeviceInterfaces to perform the enumeration. + @param[in] class_id Device class ID that is specified by our USB driver + @param[in] exclude_not_present If set include only those devices that are + currently present. + @param[in] exclude_removed If true interfaces with SPINT_REMOVED flag set + will be not included in the enumeration. + @param[in] active_only If true only active interfaces (with flag + SPINT_ACTIVE set) will be included in the enumeration. + @return True on success, false on failure, in which case GetLastError() + provides extended information about the error that occurred. + */ + bool InitializeEnum(GUID class_id, + bool exclude_not_present, + bool exclude_removed, + bool active_only); + + /** \brief Gets next enumerated interface information + @param[out] info Upon successful completion will receive interface + information. Can be NULL. If it is NULL, upon return from this + method *size will have memory size required to fit this entry. + @param[in,out] size On the way in provides size of the memory buffer + addressed by info param. On the way out (only if buffer is not + big enough) will provide memory size required to fit this entry. + @return true on success, false on error. If false is returned + GetLastError() provides extended information about the error that + occurred. ERROR_INSUFFICIENT_BUFFER indicates that buffer provided + in info param was not big enough and *size specifies memory size + required to fit this entry. ERROR_NO_MORE_ITEMS indicates that + enumeration is over and there are no more entries to return. + */ + bool Next(AdbInterfaceInfo* info, ULONG* size); + + /** \brief Makes enumerator to start from the beginning. + @return true on success, false on error. If false is returned + GetLastError() provides extended information about the error that + occurred. + */ + bool Reset(); + + // This is a helper for extracting object from the AdbObjectHandleMap + static AdbObjectType Type() { + return AdbObjectTypeInterfaceEnumerator; + } + + protected: + /// Array of interfaces enumerated with this object + AdbEnumInterfaceArray interfaces_; + + /// Current enumerator + AdbEnumInterfaceArray::iterator current_interface_; +}; + +#endif // ANDROID_USB_API_ADB_INTERFACE_ENUM_H__ diff --git a/host/windows/usb/api/adb_io_completion.cpp b/host/windows/usb/api/adb_io_completion.cpp index 02519c910..64f97fd7d 100644 --- a/host/windows/usb/api/adb_io_completion.cpp +++ b/host/windows/usb/api/adb_io_completion.cpp @@ -1,103 +1,98 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - This file consists of implementation of class AdbIOCompletion that - encapsulates a wrapper around OVERLAPPED Win32 structure returned - from asynchronous I/O requests. -*/ - -#include "stdafx.h" -#include "adb_io_completion.h" - -AdbIOCompletion::AdbIOCompletion(AdbIOObject* parent_io_obj, - bool is_write_ctl, - ULONG expected_trans_size, - HANDLE event_hndl) - : AdbObjectHandle(AdbObjectTypeIoCompletion), - transferred_bytes_(0), - expected_transfer_size_(expected_trans_size), - is_write_ioctl_(is_write_ctl), - parent_io_object_(parent_io_obj) { - ATLASSERT(NULL != parent_io_obj); - parent_io_obj->AddRef(); - ZeroMemory(&overlapped_, sizeof(overlapped_)); - overlapped_.hEvent = event_hndl; -} - -AdbIOCompletion::~AdbIOCompletion() { - parent_io_object_->Release(); -} - -bool AdbIOCompletion::GetOvelappedIoResult(LPOVERLAPPED ovl_data, - ULONG* bytes_transferred, - bool wait) { - if (NULL != bytes_transferred) - *bytes_transferred = 0; - - if (!IsOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - ULONG transfer; - bool ret = GetOverlappedResult(parent_io_object()->usb_handle(), - overlapped(), - &transfer, - wait) ? true : - false; - - // TODO: This is bizzare but I've seen it happening - // that GetOverlappedResult with wait set to true returns "prematurely", - // with wrong transferred bytes value and GetLastError reporting - // ERROR_IO_PENDING. So, lets give it an up to a 20 ms loop! - ULONG error = GetLastError(); - - if (wait && ret && (0 == transfer) && (0 != expected_transfer_size_) && - ((ERROR_IO_INCOMPLETE == error) || (ERROR_IO_PENDING == error))) { - for (int trying = 0; trying < 10; trying++) { - Sleep(2); - ret = GetOverlappedResult(parent_io_object()->usb_handle(), - overlapped(), - &transfer, - wait) ? true : - false; - error = GetLastError(); - if (!ret || (0 != transfer) || - ((ERROR_IO_INCOMPLETE != error) && (ERROR_IO_PENDING != error))) { - break; - } - } - } - - if (NULL != ovl_data) - CopyMemory(ovl_data, overlapped(), sizeof(OVERLAPPED)); - - if (NULL != bytes_transferred) - *bytes_transferred = is_write_ioctl() ? transferred_bytes_ : transfer; - - return ret; -} - -bool AdbIOCompletion::IsCompleted() { - SetLastError(NO_ERROR); - if (!IsOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return true; - } - - return HasOverlappedIoCompleted(overlapped()) ? true : false; -} +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \file + This file consists of implementation of class AdbIOCompletion that + encapsulates a wrapper around OVERLAPPED Win32 structure returned + from asynchronous I/O requests. +*/ + +#include "stdafx.h" +#include "adb_io_completion.h" + +AdbIOCompletion::AdbIOCompletion(AdbEndpointObject* parent_io_obj, + ULONG expected_trans_size, + HANDLE event_hndl) + : AdbObjectHandle(AdbObjectTypeIoCompletion), + expected_transfer_size_(expected_trans_size), + parent_io_object_(parent_io_obj) { + ATLASSERT(NULL != parent_io_obj); + parent_io_obj->AddRef(); + ZeroMemory(&overlapped_, sizeof(overlapped_)); + overlapped_.hEvent = event_hndl; +} + +AdbIOCompletion::~AdbIOCompletion() { + parent_io_object_->Release(); +} + +bool AdbIOCompletion::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_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_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; +} + +bool AdbIOCompletion::IsCompleted() { + SetLastError(NO_ERROR); + if (!IsOpened()) { + SetLastError(ERROR_INVALID_HANDLE); + return true; + } + + return HasOverlappedIoCompleted(overlapped()) ? true : false; +} diff --git a/host/windows/usb/api/adb_io_completion.h b/host/windows/usb/api/adb_io_completion.h index d29f5e1e4..3fea0e89b 100644 --- a/host/windows/usb/api/adb_io_completion.h +++ b/host/windows/usb/api/adb_io_completion.h @@ -1,140 +1,122 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_USB_API_ADB_IO_COMPLETION_H__ -#define ANDROID_USB_API_ADB_IO_COMPLETION_H__ -/** \file - This file consists of declaration of class AdbIOCompletion that encapsulates - a wrapper around OVERLAPPED Win32 structure returned from asynchronous I/O - requests. -*/ - -#include "adb_io_object.h" - -/** Class AdbIOCompletion encapsulates encapsulates a wrapper around - OVERLAPPED Win32 structure returned from asynchronous I/O requests. - 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 AdbIOCompletion : public AdbObjectHandle { - public: - /** \brief Constructs the object - - @param parent_io_obj[in] Parent I/O object that created this instance. - Parent object will be referenced in this object's constructur and - released in the destructor. - @param is_write_ctl[in] Flag indicating whether or not this completion - object is created for ADB_IOCTL_BULK_WRITE I/O. - @param event_hndl[in] 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. - */ - AdbIOCompletion(AdbIOObject* parent_io_obj, - bool is_write_ctl, - ULONG expected_trans_size, - HANDLE event_hndl); - - protected: - /** \brief Destructs the object. - - parent_io_object_ will be dereferenced here. - We hide destructor in order to prevent ourseves from accidentaly allocating - instances on the stack. If such attemp occur, compiler will error. - */ - virtual ~AdbIOCompletion(); - - public: - /** \brief Gets overlapped I/O result - - @param ovl_data[out] Buffer for the copy of this object's OVERLAPPED - structure. Can be NULL. - @param bytes_transferred[out] 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 wait[in] 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); - - /** \brief Checks if I/O that this object represents has completed. - - @return 'true' if I/O has been completed or 'false' if it's still - incomplete. Regardless of the returned value, caller should - check GetLastError to validate that handle was OK. - */ - virtual bool IsCompleted(); - - public: - /// Gets overlapped structure for this I/O - LPOVERLAPPED overlapped() { - return &overlapped_; - } - - /// Gets parent object - AdbIOObject* parent_io_object() const { - return parent_io_object_; - } - - /// Gets parent object handle - ADBAPIHANDLE GetParentObjectHandle() const { - return (NULL != parent_io_object()) ? parent_io_object()->adb_handle() : - NULL; - } - - /// Gets address for ADB_IOCTL_BULK_WRITE output buffer - ULONG* transferred_bytes_ptr() { - ATLASSERT(is_write_ioctl()); - return &transferred_bytes_; - } - - /// Gets write IOCTL flag - bool is_write_ioctl() const { - return is_write_ioctl_; - } - - // This is a helper for extracting object from the AdbObjectHandleMap - static AdbObjectType Type() { - return AdbObjectTypeIoCompletion; - } - - protected: - /// Overlapped structure for this I/O - OVERLAPPED overlapped_; - - /// Parent I/O object - AdbIOObject* parent_io_object_; - - /// Recepient for number of transferred bytes in write IOCTL - ULONG transferred_bytes_; - - /// Expected number of bytes transferred in thi I/O - ULONG expected_transfer_size_; - - /// Write IOCTL flag - bool is_write_ioctl_; -}; - -#endif // ANDROID_USB_API_ADB_IO_COMPLETION_H__ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_USB_API_ADB_IO_COMPLETION_H__ +#define ANDROID_USB_API_ADB_IO_COMPLETION_H__ +/** \file + This file consists of declaration of class AdbIOCompletion that encapsulates + a wrapper around OVERLAPPED Win32 structure returned from asynchronous I/O + requests. +*/ + +#include "adb_endpoint_object.h" + +/** \brief Encapsulates encapsulates a wrapper around OVERLAPPED Win32 + structure returned from asynchronous I/O requests. + + 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 AdbIOCompletion : public AdbObjectHandle { + public: + /** \brief Constructs the object + + @param[in] parent_io_obj Parent I/O object that created this instance. + Parent object will be referenced in this object's constructor and + released in the destructor. + @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. + */ + AdbIOCompletion(AdbEndpointObject* 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 ~AdbIOCompletion(); + + public: + /** \brief Gets overlapped I/O result + + @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); + + /** \brief Checks if I/O that this object represents has completed. + + @return true if I/O has been completed or false if it's still + incomplete. Regardless of the returned value, caller should + check GetLastError to validate that handle was OK. + */ + virtual bool IsCompleted(); + + public: + /// Gets overlapped structure for this I/O + LPOVERLAPPED overlapped() { + return &overlapped_; + } + + /// Gets parent object + AdbEndpointObject* parent_io_object() const { + return parent_io_object_; + } + + /// Gets parent object handle + ADBAPIHANDLE GetParentObjectHandle() const { + return (NULL != parent_io_object()) ? parent_io_object()->adb_handle() : + NULL; + } + + // This is a helper for extracting object from the AdbObjectHandleMap + static AdbObjectType Type() { + return AdbObjectTypeIoCompletion; + } + + protected: + /// Overlapped structure for this I/O + OVERLAPPED overlapped_; + + /// Parent I/O object + AdbEndpointObject* parent_io_object_; + + /// Expected number of bytes transferred in thi I/O + ULONG expected_transfer_size_; +}; + +#endif // ANDROID_USB_API_ADB_IO_COMPLETION_H__ diff --git a/host/windows/usb/api/adb_io_object.cpp b/host/windows/usb/api/adb_io_object.cpp deleted file mode 100644 index 732dc22b6..000000000 --- a/host/windows/usb/api/adb_io_object.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - This file consists of implementation of class AdbIOObject that encapsulates - an item on our device that is opened for read / write / IOCTL I/O. -*/ - -#include "stdafx.h" -#include "adb_io_object.h" -#include "adb_io_completion.h" -#include "adb_helper_routines.h" - -AdbIOObject::AdbIOObject(AdbInterfaceObject* parent_interf, - AdbObjectType obj_type) - : AdbObjectHandle(obj_type), - usb_handle_(INVALID_HANDLE_VALUE), - parent_interface_(parent_interf) { - ATLASSERT(NULL != parent_interf); - parent_interf->AddRef(); -} - -AdbIOObject::~AdbIOObject() { - if (INVALID_HANDLE_VALUE != usb_handle_) - ::CloseHandle(usb_handle_); - parent_interface_->Release(); -} - -ADBAPIHANDLE AdbIOObject::CreateHandle(const wchar_t* item_path, - AdbOpenAccessType access_type, - AdbOpenSharingMode share_mode) { - // Make sure that we don't have USB handle here - if (IsUsbOpened()) { - SetLastError(ERROR_GEN_FAILURE); - return NULL; - } - - // Convert access / share parameters into CreateFile - compatible - ULONG desired_access; - ULONG desired_sharing; - - if (!GetSDKComplientParam(access_type, share_mode, - &desired_access, &desired_sharing)) { - return NULL; - } - - // Open USB handle - usb_handle_ = CreateFile(item_path, - desired_access, - share_mode, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, // Always overlapped! - NULL); - if (INVALID_HANDLE_VALUE == usb_handle_) - return NULL; - - // Create ADB handle - ADBAPIHANDLE ret = AdbObjectHandle::CreateHandle(); - - if (NULL == ret) { - // If creation of ADB handle failed we have to close USB handle too. - ULONG error = GetLastError(); - ::CloseHandle(usb_handle()); - usb_handle_ = INVALID_HANDLE_VALUE; - SetLastError(error); - } - - return ret; -} - -bool AdbIOObject::CloseHandle() { - // Lets close USB item first - if (IsUsbOpened()) { - ::CloseHandle(usb_handle()); - usb_handle_ = INVALID_HANDLE_VALUE; - } - - return AdbObjectHandle::CloseHandle(); -} - -ADBAPIHANDLE AdbIOObject::AsyncRead(void* buffer, - ULONG bytes_to_read, - ULONG* bytes_read, - HANDLE event_handle, - ULONG time_out) { - return CommonAsyncReadWrite(true, - buffer, - bytes_to_read, - bytes_read, - event_handle, - time_out); -} - -ADBAPIHANDLE AdbIOObject::AsyncWrite(void* buffer, - ULONG bytes_to_write, - ULONG* bytes_written, - HANDLE event_handle, - ULONG time_out) { - return CommonAsyncReadWrite(false, - buffer, - bytes_to_write, - bytes_written, - event_handle, - time_out); -} - -bool AdbIOObject::SyncRead(void* buffer, - ULONG bytes_to_read, - ULONG* bytes_read, - ULONG time_out) { - return CommonSyncReadWrite(true, - buffer, - bytes_to_read, - bytes_read, - time_out); -} - -bool AdbIOObject::SyncWrite(void* buffer, - ULONG bytes_to_write, - ULONG* bytes_written, - ULONG time_out) { - return CommonSyncReadWrite(false, - buffer, - bytes_to_write, - bytes_written, - time_out); -} - -ADBAPIHANDLE AdbIOObject::CommonAsyncReadWrite(bool is_read, - void* buffer, - ULONG bytes_to_transfer, - ULONG* bytes_transferred, - HANDLE event_handle, - ULONG time_out) { - if (NULL != bytes_transferred) - *bytes_transferred = 0; - - if (!IsOpened() || !IsUsbOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - bool is_ioctl_write = is_read ? false : (0 != time_out); - - // Create completion i/o object - AdbIOCompletion* adb_io_completion = NULL; - - try { - adb_io_completion = new AdbIOCompletion(this, - is_ioctl_write, - 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; - if (0 == time_out) { - // Go the read / write file way - res = is_read ? ReadFile(usb_handle(), - buffer, - bytes_to_transfer, - &transferred, - adb_io_completion->overlapped()) : - WriteFile(usb_handle(), - buffer, - bytes_to_transfer, - &transferred, - adb_io_completion->overlapped()); - } else { - // Go IOCTL way - AdbBulkTransfer transfer_param; - transfer_param.time_out = time_out; - transfer_param.transfer_size = is_read ? 0 : bytes_to_transfer; - transfer_param.SetWriteBuffer(is_read ? NULL : buffer); - - res = DeviceIoControl(usb_handle(), - is_read ? ADB_IOCTL_BULK_READ : ADB_IOCTL_BULK_WRITE, - &transfer_param, sizeof(transfer_param), - is_read ? buffer : adb_io_completion->transferred_bytes_ptr(), - is_read ? bytes_to_transfer : sizeof(ULONG), - &transferred, - adb_io_completion->overlapped()); - } - - if (NULL != bytes_transferred) - *bytes_transferred = transferred; - - ULONG error = GetLastError(); - if (!res && (ERROR_IO_PENDING != error)) { - // I/O failed immediatelly. We need to close i/o completion object - // before we return NULL to the caller. - adb_io_completion->CloseHandle(); - ret = NULL; - SetLastError(error); - } - } - - // Offseting 'new' - adb_io_completion->Release(); - - return ret; -} - -bool AdbIOObject::CommonSyncReadWrite(bool is_read, - void* buffer, - ULONG bytes_to_transfer, - ULONG* bytes_transferred, - ULONG time_out) { - if (NULL != bytes_transferred) - *bytes_transferred = 0; - - if (!IsOpened() || !IsUsbOpened()) { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - bool is_ioctl_write = is_read ? false : (0 != time_out); - - // This is synchronous I/O. Since we always open I/O items for - // overlapped I/O we're obligated to always provide OVERLAPPED - // structure to read / write routines. Prepare it now. - OVERLAPPED overlapped; - ZeroMemory(&overlapped, sizeof(overlapped)); - - BOOL ret = TRUE; - ULONG ioctl_write_transferred = 0; - if (0 == time_out) { - // Go the read / write file way - ret = is_read ? - ReadFile(usb_handle(), buffer, bytes_to_transfer, bytes_transferred, &overlapped) : - WriteFile(usb_handle(), buffer, bytes_to_transfer, bytes_transferred, &overlapped); - } else { - // Go IOCTL way - AdbBulkTransfer transfer_param; - transfer_param.time_out = time_out; - transfer_param.transfer_size = is_read ? 0 : bytes_to_transfer; - transfer_param.SetWriteBuffer(is_read ? NULL : buffer); - - ULONG tmp; - ret = DeviceIoControl(usb_handle(), - is_read ? ADB_IOCTL_BULK_READ : ADB_IOCTL_BULK_WRITE, - &transfer_param, sizeof(transfer_param), - is_read ? buffer : &ioctl_write_transferred, - is_read ? bytes_to_transfer : sizeof(ULONG), - &tmp, - &overlapped); - } - - // Lets see the result - if (!ret && (ERROR_IO_PENDING != GetLastError())) { - // I/O failed. - return false; - } - - // Lets wait till I/O completes - ULONG transferred = 0; - ret = GetOverlappedResult(usb_handle(), &overlapped, &transferred, TRUE); - if (ret && (NULL != bytes_transferred)) { - *bytes_transferred = is_ioctl_write ? ioctl_write_transferred : - transferred; - } - - return ret ? true : false; -} diff --git a/host/windows/usb/api/adb_io_object.h b/host/windows/usb/api/adb_io_object.h deleted file mode 100644 index 7161b6749..000000000 --- a/host/windows/usb/api/adb_io_object.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_USB_API_ADB_IO_OBJECT_H__ -#define ANDROID_USB_API_ADB_IO_OBJECT_H__ -/** \file - This file consists of declaration of class AdbIOObject that encapsulates an - item on our device that is opened for read / write / IOCTL I/O. -*/ - -#include "adb_interface.h" - -/** Class AdbIOObject encapsulates an item on our device that is opened for - read / write / IOCTL I/O.. All I/O items (currently only endpoints) are - always opened for overlapped I/O (i.e. FILE_OVERLAPPED flag is set in - create attributes). This way each object of the derived class automatically - supports both, synchronous as well as asynchronous I/O. Since async I/O - requires "giving out" some I/O context, we have to provide async I/O caller - with some safe handle to this context. This is done wia allocating - AdbIOCompletion object that holds async I/O context and returning handle to - this object to the caller of async I/O. -*/ -class AdbIOObject : public AdbObjectHandle { - public: - /** \brief Constructs the object - - @param interface[in] Parent interface for this object. Interface will be - referenced in this object's constructur and released in the - destructor. - @param obj_type[in] Object type from AdbObjectType enum - */ - AdbIOObject(AdbInterfaceObject* parent_interf, AdbObjectType obj_type); - - protected: - /** \brief Destructs the object. - - parent_interface_ will be dereferenced here. - We hide destructor in order to prevent ourseves from accidentaly allocating - instances on the stack. If such attemp occur, compiler will error. - */ - virtual ~AdbIOObject(); - - public: - /** \brief Opens USB item and creates a handle to this object - - We combine in this method ADB handle association and opening required - object on our USB device. The sequence is to open USB item first and if - (and only if) this open succeedes we proceed to creating ADB handle by - calling AdbObjectHandle::CreateHandle(). We always open USB handle for - overlapped I/O. - @param item_path[in] Path to the item on our USB device. - @param access_type[in] Desired access type. In the current implementation - this parameter has no effect on the way item is opened. It's - always read / write access. - @param sharing_mode[in] Desired share mode. In the current implementation - this parameter has no effect on the way item is opened. It's - always shared for read / write. - @return A handle to this object on success or NULL on an error. - If NULL is returned GetLastError() provides extended error - information. ERROR_GEN_FAILURE is set if an attempt was - made to create already opened object. - */ - virtual ADBAPIHANDLE CreateHandle(const wchar_t* item_path, - AdbOpenAccessType access_type, - AdbOpenSharingMode share_mode); - - /** \brief This method is called when handle to this object gets closed - - We overwrite this method in order to close USB handle along with this - object handle. - @return 'true' on success or 'false' if object is already closed. If - 'false' is returned GetLastError() provides extended error - information. - */ - virtual bool CloseHandle(); - - /** \brief Reads from opened I/O object asynchronously - - @param buffer[out] Pointer to the buffer that receives the data. - @param bytes_to_read[in] Number of bytes to be read. - @param bytes_read[out] Number of bytes read. Can be NULL. - @param event_handle[in] 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 time_out[in] 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 AsyncRead(void* buffer, - ULONG bytes_to_read, - ULONG* bytes_read, - HANDLE event_handle, - ULONG time_out); - - /** \brief Writes to opened I/O object asynchronously - - @param buffer[in] Pointer to the buffer containing the data to be written. - @param bytes_to_write[in] Number of bytes to be written. - @param bytes_written[out] Number of bytes written. Can be NULL. - @param event_handle[in] 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 time_out[in] 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 AsyncWrite(void* buffer, - ULONG bytes_to_write, - ULONG* bytes_written, - HANDLE event_handle, - ULONG time_out); - - /** \brief Reads from opened I/O object synchronously - - @param buffer[out] Pointer to the buffer that receives the data. - @param bytes_to_read[in] Number of bytes to be read. - @param bytes_read[out] Number of bytes read. Can be NULL. - @param time_out[in] 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 and 'false' on failure. If 'false' is - returned GetLastError() provides extended error information. - */ - virtual bool SyncRead(void* buffer, - ULONG bytes_to_read, - ULONG* bytes_read, - ULONG time_out); - - /** \brief Writes to opened I/O object synchronously - - @param buffer[in] Pointer to the buffer containing the data to be written. - @param bytes_to_write[in] Number of bytes to be written. - @param bytes_written[out] Number of bytes written. Can be NULL. - @param time_out[in] 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 and 'false' on failure. If 'false' is - returned GetLastError() provides extended error information. - */ - virtual bool SyncWrite(void* buffer, - ULONG bytes_to_write, - ULONG* bytes_written, - ULONG time_out); - - protected: - /** \brief Common code for async read / write - - @param is_read[in] Read or write selector. - @param buffer[in,out] Pointer to the buffer for read / write. - @param bytes_to_transfer[in] Number of bytes to be read / written. - @param bytes_transferred[out] Number of bytes read / written. Can be NULL. - @param event_handle[in] 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 time_out[in] 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 is_read[in] Read or write selector. - @param buffer[in,out] Pointer to the buffer for read / write. - @param bytes_to_transfer[in] Number of bytes to be read / written. - @param bytes_transferred[out] Number of bytes read / written. Can be NULL. - @param time_out[in] 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); - - public: - /// Gets parent interface - AdbInterfaceObject* parent_interface() const { - return parent_interface_; - } - - /// Gets parent interface handle - ADBAPIHANDLE GetParentInterfaceHandle() const { - return (NULL != parent_interface()) ? parent_interface()->adb_handle() : - NULL; - } - - /// Gets handle to an item opened on our USB device - HANDLE usb_handle() const { - return usb_handle_; - } - - /// Checks if USB item is opened - bool IsUsbOpened() const { - return (INVALID_HANDLE_VALUE != usb_handle()); - } - - // This is a helper for extracting object from the AdbObjectHandleMap - static AdbObjectType Type() { - return AdbObjectTypeIo; - } - - protected: - /// Parent interface - AdbInterfaceObject* parent_interface_; - - /// Handle to an item opened on our USB device - HANDLE usb_handle_; -}; - -#endif // ANDROID_USB_API_ADB_IO_OBJECT_H__ diff --git a/host/windows/usb/api/adb_object_handle.cpp b/host/windows/usb/api/adb_object_handle.cpp index 8c643b446..751a0e24a 100644 --- a/host/windows/usb/api/adb_object_handle.cpp +++ b/host/windows/usb/api/adb_object_handle.cpp @@ -1,167 +1,167 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - This file consists of implementation of a class AdbObjectHandle that - encapsulates an internal API object that is visible to the outside - of the API through a handle. -*/ - -#include "stdafx.h" -#include "adb_api.h" -#include "adb_object_handle.h" - -/// Global ADBAPIHANDLE -> AdbObjectHandle* map -AdbObjectHandleMap the_map; - -/// Locker for the AdbObjectHandleMap instance -CComAutoCriticalSection the_map_locker; - -/// Next adb handle value generator -ULONG_PTR next_adb_handle_value = 0; - -AdbObjectHandle::AdbObjectHandle(AdbObjectType obj_type) - : adb_handle_(NULL), - object_type_(obj_type), - ref_count_(1) { - ATLASSERT(obj_type < AdbObjectTypeMax); -} - -AdbObjectHandle::~AdbObjectHandle() { - ATLASSERT(0 == ref_count_); - ATLASSERT(NULL == adb_handle_); -} - -LONG AdbObjectHandle::AddRef() { - ATLASSERT(ref_count_ > 0); - return InterlockedIncrement(&ref_count_); -} - -LONG AdbObjectHandle::Release() { - ATLASSERT(ref_count_ > 0); - LONG ret = InterlockedDecrement(&ref_count_); - ATLASSERT(ret >= 0); - if (0 == ret) { - LastReferenceReleased(); - delete this; - } - return ret; -} - -ADBAPIHANDLE AdbObjectHandle::CreateHandle() { - ADBAPIHANDLE ret = NULL; - - // We have to hold this lock while we're dealing with the handle - // and the table - the_map_locker.Lock(); - - ATLASSERT(!IsOpened()); - - if (!IsOpened()) { - try { - // Generate next handle value - next_adb_handle_value++; - ret = reinterpret_cast(next_adb_handle_value); - - // Add ourselves to the map - the_map[ret] = this; - - // Save handle, addref and return - adb_handle_ = ret; - AddRef(); - } catch (...) { - ret = NULL; - SetLastError(ERROR_OUTOFMEMORY); - } - } else { - // Signaling that this object is already opened - SetLastError(ERROR_GEN_FAILURE); - } - - the_map_locker.Unlock(); - - return ret; -} - -bool AdbObjectHandle::CloseHandle() { - bool ret = false; - - // Addref just in case that last reference to this object is being - // held in the map - AddRef(); - - the_map_locker.Lock(); - - ATLASSERT(IsOpened()); - - if (IsOpened()) { - try { - // Look us up in the map. - AdbObjectHandleMap::iterator found = the_map.find(adb_handle()); - ATLASSERT((found != the_map.end()) && (this == found->second)); - - if ((found != the_map.end()) && (this == found->second)) { - // Remove ourselves from the map, close and release the object - the_map.erase(found); - adb_handle_ = NULL; - Release(); - ret = true; - } else { - SetLastError(ERROR_INVALID_HANDLE); - } - } catch (...) { - ret = false; - SetLastError(ERROR_OUTOFMEMORY); - } - } else { - SetLastError(ERROR_INVALID_HANDLE); - } - - the_map_locker.Unlock(); - - Release(); - - return ret; -} - -bool AdbObjectHandle::IsObjectOfType(AdbObjectType obj_type) const { - return (obj_type == object_type()); -} - -void AdbObjectHandle::LastReferenceReleased() { - ATLASSERT(!IsOpened()); -} - -AdbObjectHandle* AdbObjectHandle::Lookup(ADBAPIHANDLE adb_hndl) { - AdbObjectHandle* ret = NULL; - - the_map_locker.Lock(); - - try { - // Look us up in the map. - AdbObjectHandleMap::iterator found = the_map.find(adb_hndl); - if (found != the_map.end()) { - ret = found->second; - ret->AddRef(); - } - } catch (...) { - SetLastError(ERROR_OUTOFMEMORY); - } - - the_map_locker.Unlock(); - - return ret; -} +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \file + This file consists of implementation of a class AdbObjectHandle that + encapsulates an internal API object that is visible to the outside + of the API through a handle. +*/ + +#include "stdafx.h" +#include "adb_api.h" +#include "adb_object_handle.h" + +/// Global ADBAPIHANDLE -> AdbObjectHandle* map +AdbObjectHandleMap the_map; + +/// Locker for the AdbObjectHandleMap instance +CComAutoCriticalSection the_map_locker; + +/// Next adb handle value generator +ULONG_PTR next_adb_handle_value = 0; + +AdbObjectHandle::AdbObjectHandle(AdbObjectType obj_type) + : adb_handle_(NULL), + object_type_(obj_type), + ref_count_(1) { + ATLASSERT(obj_type < AdbObjectTypeMax); +} + +AdbObjectHandle::~AdbObjectHandle() { + ATLASSERT(0 == ref_count_); + ATLASSERT(NULL == adb_handle_); +} + +LONG AdbObjectHandle::AddRef() { + ATLASSERT(ref_count_ > 0); + return InterlockedIncrement(&ref_count_); +} + +LONG AdbObjectHandle::Release() { + ATLASSERT(ref_count_ > 0); + LONG ret = InterlockedDecrement(&ref_count_); + ATLASSERT(ret >= 0); + if (0 == ret) { + LastReferenceReleased(); + delete this; + } + return ret; +} + +ADBAPIHANDLE AdbObjectHandle::CreateHandle() { + ADBAPIHANDLE ret = NULL; + + // We have to hold this lock while we're dealing with the handle + // and the table + the_map_locker.Lock(); + + ATLASSERT(!IsOpened()); + + if (!IsOpened()) { + try { + // Generate next handle value + next_adb_handle_value++; + ret = reinterpret_cast(next_adb_handle_value); + + // Add ourselves to the map + the_map[ret] = this; + + // Save handle, addref and return + adb_handle_ = ret; + AddRef(); + } catch (...) { + ret = NULL; + SetLastError(ERROR_OUTOFMEMORY); + } + } else { + // Signaling that this object is already opened + SetLastError(ERROR_GEN_FAILURE); + } + + the_map_locker.Unlock(); + + return ret; +} + +bool AdbObjectHandle::CloseHandle() { + bool ret = false; + + // Addref just in case that last reference to this object is being + // held in the map + AddRef(); + + the_map_locker.Lock(); + + ATLASSERT(IsOpened()); + + if (IsOpened()) { + try { + // Look us up in the map. + AdbObjectHandleMap::iterator found = the_map.find(adb_handle()); + ATLASSERT((found != the_map.end()) && (this == found->second)); + + if ((found != the_map.end()) && (this == found->second)) { + // Remove ourselves from the map, close and release the object + the_map.erase(found); + adb_handle_ = NULL; + Release(); + ret = true; + } else { + SetLastError(ERROR_INVALID_HANDLE); + } + } catch (...) { + ret = false; + SetLastError(ERROR_OUTOFMEMORY); + } + } else { + SetLastError(ERROR_INVALID_HANDLE); + } + + the_map_locker.Unlock(); + + Release(); + + return ret; +} + +bool AdbObjectHandle::IsObjectOfType(AdbObjectType obj_type) const { + return (obj_type == object_type()); +} + +void AdbObjectHandle::LastReferenceReleased() { + ATLASSERT(!IsOpened()); +} + +AdbObjectHandle* AdbObjectHandle::Lookup(ADBAPIHANDLE adb_hndl) { + AdbObjectHandle* ret = NULL; + + the_map_locker.Lock(); + + try { + // Look us up in the map. + AdbObjectHandleMap::iterator found = the_map.find(adb_hndl); + if (found != the_map.end()) { + ret = found->second; + ret->AddRef(); + } + } catch (...) { + SetLastError(ERROR_OUTOFMEMORY); + } + + the_map_locker.Unlock(); + + return ret; +} diff --git a/host/windows/usb/api/adb_object_handle.h b/host/windows/usb/api/adb_object_handle.h index 088971c10..29ac5e2f2 100644 --- a/host/windows/usb/api/adb_object_handle.h +++ b/host/windows/usb/api/adb_object_handle.h @@ -1,213 +1,211 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_USB_API_ADB_OBJECT_HANDLE_H__ -#define ANDROID_USB_API_ADB_OBJECT_HANDLE_H__ -/** \file - This file consists of declaration of a class AdbObjectHandle that - encapsulates an internal API object that is visible to the outside - of the API through a handle. -*/ - -#include "adb_api_private_defines.h" - -/** AdbObjectType enum defines types of internal API objects -*/ -enum AdbObjectType { - /// Object is AdbInterfaceEnumObject - AdbObjectTypeInterfaceEnumerator, - - /// Object is AdbInterfaceObject - AdbObjectTypeInterface, - - /// Object is derived from AdbIOObject - AdbObjectTypeIo, - - /// Object is AdbEndpointObject - AdbObjectTypeEndpoint, - - /// Object is AdbIOCompletion - AdbObjectTypeIoCompletion, - - AdbObjectTypeMax -}; - -/** Class AdbObjectHandle encapsulates an internal API basic object that is - visible to the outside of the API through a handle. In order to prevent - crashes when API client tries to access an object through an invalid or - already closed handle, we keep track of all opened handles in - AdbObjectHandleMap that maps association between valid ADBAPIHANDLE and - an object that this handle represents. All objects that are exposed to the - outside of API via ADBAPIHANDLE are self-destructing referenced objects. - The reference model for these objects is as such: - 1. When CreateHandle() method is called on an object, a handle (ADBAPIHANDLE - that is) is assigned to it, a pair is added to the global - AdbObjectHandleMap instance, object is referenced and then handle is - returned to the API client. - 2. Every time API is called with a handle, a lookup is performed in - AdbObjectHandleMap to find an object that is associated with the handle. - If object is not found then ERROR_INVALID_HANDLE is immediatelly returned - (via SetLastError() call). If object is found then it is referenced and - API call is dispatched to appropriate method of the found object. Upon - return from this method, just before returning from the API call, object - is dereferenced back to match lookup reference. - 3. When object handle gets closed, assuming object is found in the map, that - pair is deleted from the map and object's refcount is - decremented to match refcount increment performed when object has been - added to the map. - 4. When object's refcount drops to zero, the object commits suicide by - calling "delete this". - All API objects that have handles that are sent back to API client must be - derived from this class. -*/ -class AdbObjectHandle { - public: - /** \brief Constructs the object - - Refernce counter is set to 1 in the constructor. - @param obj_type[in] Object type from AdbObjectType enum - */ - explicit AdbObjectHandle(AdbObjectType obj_type); - - protected: - /** \brief Destructs the object. - - We hide destructor in order to prevent ourseves from accidentaly allocating - instances on the stack. If such attempt occurs, compiler will error. - */ - virtual ~AdbObjectHandle(); - - public: - /** \brief References the object - - @return Value of the reference counter after object is referenced in this - method. - */ - virtual LONG AddRef(); - - /** \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. - @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 - to the AdbObjectHandleMap. - @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. - @return 'true' on success or 'false' if object is already closed. If - 'false' is returned GetLastError() provides extended error - information. - */ - virtual bool CloseHandle(); - - /** \brief Checks if this object is of the given type - - @param obj_type[in] One of the AdbObjectType types to check - @return 'true' is this object type matches obj_type, or 'false' otherwise. - */ - virtual bool IsObjectOfType(AdbObjectType obj_type) const; - - /** \brief Looks up AdbObjectHandle instance associated with the given handle - in the AdbObjectHandleMap. - - This method increments reference counter for the returned found object. - @param adb_handle[in] ADB handle to the object - @return API object associated with the handle or NULL if object is not - found. If NULL is returned GetLastError() provides extended error - information. - */ - static AdbObjectHandle* Lookup(ADBAPIHANDLE adb_handle); - - protected: - /** \brief Called when last reference to this object is released. - - Derived object should override this method to perform cleanup that is not - suitable for destructors. - */ - virtual void LastReferenceReleased(); - - public: - /// Gets ADB handle associated with this object - ADBAPIHANDLE adb_handle() const { - return adb_handle_; - } - - /// Gets type of this object - AdbObjectType object_type() const { - return object_type_; - } - - /// Checks if object is still opened. Note that it is not guaranteed that - /// object remains opened when this method returns. - bool IsOpened() const { - return (NULL != adb_handle()); - } - - protected: - /// API handle associated with this object - ADBAPIHANDLE adb_handle_; - - /// Type of this object - AdbObjectType object_type_; - - /// This object's reference counter - LONG ref_count_; -}; - -/// Maps ADBAPIHANDLE to associated AdbObjectHandle object -typedef std::map< ADBAPIHANDLE, AdbObjectHandle* > AdbObjectHandleMap; - -/** \brief Template routine that unifies extracting of objects of different - types from the AdbObjectHandleMap - - @param adb_handle[in] API handle for the object - @return Object associated with the handle or NULL on error. If NULL is - returned GetLastError() provides extended error information. -*/ -template -obj_class* LookupObject(ADBAPIHANDLE adb_handle) { - // Lookup object for the handle in the map - AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle); - if (NULL != adb_object) { - // Make sure it's of the correct type - if (!adb_object->IsObjectOfType(obj_class::Type())) { - adb_object->Release(); - adb_object = NULL; - SetLastError(ERROR_INVALID_HANDLE); - } - } else { - SetLastError(ERROR_INVALID_HANDLE); - } - return (adb_object != NULL) ? reinterpret_cast(adb_object) : - NULL; -} - -#endif // ANDROID_USB_API_ADB_OBJECT_HANDLE_H__ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_USB_API_ADB_OBJECT_HANDLE_H__ +#define ANDROID_USB_API_ADB_OBJECT_HANDLE_H__ +/** \file + This file consists of declaration of a class AdbObjectHandle that + encapsulates an internal API object that is visible to the outside + of the API through a handle. +*/ + +#include "adb_api_private_defines.h" + +/** \brief Defines types of internal API objects +*/ +enum AdbObjectType { + /// Object is AdbInterfaceEnumObject. + AdbObjectTypeInterfaceEnumerator, + + /// Object is AdbInterfaceObject. + AdbObjectTypeInterface, + + /// Object is AdbEndpointObject. + AdbObjectTypeEndpoint, + + /// Object is AdbIOCompletion. + AdbObjectTypeIoCompletion, + + AdbObjectTypeMax +}; + +/** \brief Encapsulates an internal API basic object that is visible to the + outside of the API through a handle. + + In order to prevent crashes when API client tries to access an object through + an invalid or already closed handle, we keep track of all opened handles in + AdbObjectHandleMap that maps association between valid ADBAPIHANDLE and + an object that this handle represents. All objects that are exposed to the + outside of API via ADBAPIHANDLE are self-destructing referenced objects. + The reference model for these objects is as such: + 1. When CreateHandle() method is called on an object, a handle (ADBAPIHANDLE + that is) is assigned to it, a pair is added to the global + AdbObjectHandleMap instance, object is referenced and then handle is + returned to the API client. + 2. Every time API is called with a handle, a lookup is performed in + AdbObjectHandleMap to find an object that is associated with the handle. + If object is not found then ERROR_INVALID_HANDLE is immediatelly returned + (via SetLastError() call). If object is found then it is referenced and + API call is dispatched to appropriate method of the found object. Upon + return from this method, just before returning from the API call, object + is dereferenced back to match lookup reference. + 3. When object handle gets closed, assuming object is found in the map, that + pair is deleted from the map and object's refcount is + decremented to match refcount increment performed when object has been + added to the map. + 4. When object's refcount drops to zero, the object commits suicide by + calling "delete this". + All API objects that have handles that are sent back to API client must be + derived from this class. +*/ +class AdbObjectHandle { + public: + /** \brief Constructs the object + + Refernce counter is set to 1 in the constructor. + @param[in] obj_type Object type from AdbObjectType enum + */ + explicit AdbObjectHandle(AdbObjectType obj_type); + + protected: + /** \brief Destructs the object. + + We hide destructor in order to prevent ourseves from accidentaly allocating + instances on the stack. If such attempt occurs, compiler will error. + */ + virtual ~AdbObjectHandle(); + + public: + /** \brief References the object. + + @return Value of the reference counter after object is referenced in this + method. + */ + virtual LONG AddRef(); + + /** \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. + @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 + to the AdbObjectHandleMap. + @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. + @return true on success or false if object is already closed. If + false is returned GetLastError() provides extended error + information. + */ + virtual bool CloseHandle(); + + /** \brief Checks if this object is of the given type. + + @param[in] obj_type One of the AdbObjectType types to check + @return true is this object type matches obj_type, or false otherwise. + */ + virtual bool IsObjectOfType(AdbObjectType obj_type) const; + + /** \brief Looks up AdbObjectHandle instance associated with the given handle + in the AdbObjectHandleMap. + + This method increments reference counter for the returned found object. + @param[in] adb_handle ADB handle to the object + @return API object associated with the handle or NULL if object is not + found. If NULL is returned GetLastError() provides extended error + information. + */ + static AdbObjectHandle* Lookup(ADBAPIHANDLE adb_handle); + + protected: + /** \brief Called when last reference to this object is released. + + Derived object should override this method to perform cleanup that is not + suitable for destructors. + */ + virtual void LastReferenceReleased(); + + public: + /// Gets ADB handle associated with this object + ADBAPIHANDLE adb_handle() const { + return adb_handle_; + } + + /// Gets type of this object + AdbObjectType object_type() const { + return object_type_; + } + + /// Checks if object is still opened. Note that it is not guaranteed that + /// object remains opened when this method returns. + bool IsOpened() const { + return (NULL != adb_handle()); + } + + protected: + /// API handle associated with this object + ADBAPIHANDLE adb_handle_; + + /// Type of this object + AdbObjectType object_type_; + + /// This object's reference counter + LONG ref_count_; +}; + +/// Maps ADBAPIHANDLE to associated AdbObjectHandle object +typedef std::map< ADBAPIHANDLE, AdbObjectHandle* > AdbObjectHandleMap; + +/** \brief Template routine that unifies extracting of objects of different + types from the AdbObjectHandleMap + + @param[in] adb_handle API handle for the object + @return Object associated with the handle or NULL on error. If NULL is + returned GetLastError() provides extended error information. +*/ +template +obj_class* LookupObject(ADBAPIHANDLE adb_handle) { + // Lookup object for the handle in the map + AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle); + if (NULL != adb_object) { + // Make sure it's of the correct type + if (!adb_object->IsObjectOfType(obj_class::Type())) { + adb_object->Release(); + adb_object = NULL; + SetLastError(ERROR_INVALID_HANDLE); + } + } else { + SetLastError(ERROR_INVALID_HANDLE); + } + return (adb_object != NULL) ? reinterpret_cast(adb_object) : + NULL; +} + +#endif // ANDROID_USB_API_ADB_OBJECT_HANDLE_H__ diff --git a/host/windows/usb/api/stdafx.cpp b/host/windows/usb/api/stdafx.cpp index 87db2cdb9..eb9b26151 100644 --- a/host/windows/usb/api/stdafx.cpp +++ b/host/windows/usb/api/stdafx.cpp @@ -1,21 +1,21 @@ -/* - * Copyright (C) 2008 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 -// AdbWinApi.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" +/* + * Copyright (C) 2008 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 +// AdbWinApi.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/api/stdafx.h b/host/windows/usb/api/stdafx.h index f47936f8a..92b2652ea 100644 --- a/host/windows/usb/api/stdafx.h +++ b/host/windows/usb/api/stdafx.h @@ -1,71 +1,82 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - 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 - -#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 - -#pragma warning(disable: 4702) -#include "resource.h" -#include -#include -#include -#include -#include -#include -#include -#pragma warning(disable: 4200) -extern "C" { -#include -} - -#include "android_usb_common_defines.h" - -using namespace ATL; +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \file + 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 +#pragma warning(disable: 4702) +#pragma warning(disable: 4201) +#include +#include +#include +#include +#include +#include +#pragma warning(default: 4201) +#pragma warning(disable: 4200) +extern "C" { +#include +#include +#include +} + +#include "resource.h" + +using namespace ATL; -- cgit v1.2.3