Refactor ADB API dll to support WinUsb

This commit is contained in:
vchtchetkine
2009-07-22 13:34:53 -07:00
parent 8c78ba6438
commit dceaaa52ce
30 changed files with 4032 additions and 4433 deletions

View File

@@ -1,32 +1,38 @@
/* /*
* Copyright (C) 2008 The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
// AdbWinApi.cpp : Implementation of DLL Exports. // AdbWinApi.cpp : Implementation of DLL Exports.
#include "stdafx.h" #include "stdafx.h"
class CAdbWinApiModule : public CAtlDllModuleT< CAdbWinApiModule > { extern "C" {
public: int _forceCRTManifest;
}; int _forceMFCManifest;
int _forceAtlDllManifest;
CAdbWinApiModule _AtlModule; };
// DLL Entry Point class CAdbWinApiModule : public CAtlDllModuleT< CAdbWinApiModule > {
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, public:
DWORD reason, };
LPVOID reserved) {
return _AtlModule.DllMain(reason, reserved); CAdbWinApiModule _AtlModule;
}
// DLL Entry Point
extern "C" BOOL WINAPI DllMain(HINSTANCE instance,
DWORD reason,
LPVOID reserved) {
return _AtlModule.DllMain(reason, reserved);
}

View File

@@ -1,5 +1,5 @@
; AdbWinApi.def : Declares the module parameters. ; AdbWinApi.def : Declares the module parameters.
LIBRARY "AdbWinApi.DLL" LIBRARY "AdbWinApi.DLL"
EXPORTS EXPORTS

View File

@@ -1,111 +1,111 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
//Microsoft Visual C++ generated resource script. //Microsoft Visual C++ generated resource script.
// //
#include "resource.h" #include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS #define APSTUDIO_READONLY_SYMBOLS
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
// Generated from the TEXTINCLUDE 2 resource. // Generated from the TEXTINCLUDE 2 resource.
// //
#include "winres.h" #include "winres.h"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS #undef APSTUDIO_READONLY_SYMBOLS
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE 9, 1 LANGUAGE 9, 1
#pragma code_page(1252) #pragma code_page(1252)
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
// TEXTINCLUDE // TEXTINCLUDE
// //
1 TEXTINCLUDE 1 TEXTINCLUDE
BEGIN BEGIN
"resource.h\0" "resource.h\0"
END END
2 TEXTINCLUDE 2 TEXTINCLUDE
BEGIN BEGIN
"#include ""winres.h""\r\n" "#include ""winres.h""\r\n"
"\0" "\0"
END END
#endif // APSTUDIO_INVOKED #endif // APSTUDIO_INVOKED
#ifndef _MAC #ifndef _MAC
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
// Version // Version
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1 FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1 PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
#else #else
FILEFLAGS 0x0L FILEFLAGS 0x0L
#endif #endif
FILEOS 0x4L FILEOS 0x4L
FILETYPE 0x2L FILETYPE 0x2L
FILESUBTYPE 0x0L FILESUBTYPE 0x0L
BEGIN BEGIN
BLOCK "StringFileInfo" BLOCK "StringFileInfo"
BEGIN BEGIN
BLOCK "040904e4" BLOCK "040904e4"
BEGIN BEGIN
VALUE "CompanyName", "Google, inc" VALUE "CompanyName", "Google, inc"
VALUE "FileDescription", "TODO: <File description>" VALUE "FileDescription", "TODO: <File description>"
VALUE "FileVersion", "1.0.0.1" VALUE "FileVersion", "1.0.0.1"
VALUE "LegalCopyright", "Copyright (C) 2006 The Android Open Source Project" VALUE "LegalCopyright", "Copyright (C) 2006 The Android Open Source Project"
VALUE "InternalName", "AdbWinApi.dll" VALUE "InternalName", "AdbWinApi.dll"
VALUE "OriginalFilename", "AdbWinApi.dll" VALUE "OriginalFilename", "AdbWinApi.dll"
VALUE "ProductName", "TODO: <Product name>" VALUE "ProductName", "TODO: <Product name>"
VALUE "ProductVersion", "1.0.0.1" VALUE "ProductVersion", "1.0.0.1"
VALUE "OLESelfRegister", "" VALUE "OLESelfRegister", ""
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
BEGIN BEGIN
VALUE "Translation", 0x0409, 1252 VALUE "Translation", 0x0409, 1252
END END
END END
#endif // !_MAC #endif // !_MAC
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
// String Table // String Table
// //
STRINGTABLE STRINGTABLE
BEGIN BEGIN
IDS_PROJNAME "AdbWinApi" IDS_PROJNAME "AdbWinApi"
END END
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
#endif #endif
#ifndef APSTUDIO_INVOKED #ifndef APSTUDIO_INVOKED
#endif // not APSTUDIO_INVOKED #endif // not APSTUDIO_INVOKED

View File

@@ -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

View File

@@ -1,290 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="AdbWinApi"
ProjectGUID="{C0A471E9-6892-4270-96DE-DB5F8D526FB1}"
Keyword="AtlProj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="2"
UseOfATL="1"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="1">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="c:\winddk\6000\inc\api;..\common"
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_USRDLL;ADBWIN_EXPORTS"
MinimalRebuild="FALSE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
BufferSecurityCheck="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
UsePrecompiledHeader="3"
ProgramDataBaseFileName="..\build\$(OutDir)\i386\$(TargetName).pdb"
WarningLevel="4"
WarnAsError="TRUE"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"
DisableSpecificWarnings="4100;4200;4702"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
IgnoreImportLibrary="TRUE"
AdditionalDependencies="c:\winddk\6000\lib\wxp\i386\usbd.lib setupapi.lib"
OutputFile="..\build\$(OutDir)\i386/AdbWinApi.dll"
LinkIncremental="2"
AdditionalLibraryDirectories=""
ModuleDefinitionFile=".\AdbWinApi.def"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="..\build\$(OutDir)\i386/$(ProjectName).pdb"
SubSystem="2"
ImportLibrary="..\build\$(OutDir)\i386/AdbWinApi.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="FALSE"
TargetEnvironment="1"
GenerateStublessProxies="TRUE"
TypeLibraryName="$(IntDir)/AdbWinApi.tlb"
HeaderFileName="AdbWinApi.h"
DLLDataFileName=""
InterfaceIdentifierFileName="AdbWinApi_i.c"
ProxyFileName="AdbWinApi_p.c"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
AdditionalIncludeDirectories="$(IntDir)"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="2"
UseOfATL="1"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="1">
<Tool
Name="VCCLCompilerTool"
Optimization="4"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="c:\winddk\6000\inc\api;..\common"
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;_USRDLL;ADBWIN_EXPORTS"
MinimalRebuild="FALSE"
RuntimeLibrary="0"
BufferSecurityCheck="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
UsePrecompiledHeader="3"
ProgramDataBaseFileName="..\build\$(OutDir)\i386\$(TargetName).pdb"
WarningLevel="4"
WarnAsError="TRUE"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"
DisableSpecificWarnings="4100;4200;4702"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
IgnoreImportLibrary="TRUE"
AdditionalDependencies="c:\winddk\6000\lib\wxp\i386\usbd.lib setupapi.lib"
OutputFile="..\build\$(OutDir)\i386/AdbWinApi.dll"
LinkIncremental="1"
AdditionalLibraryDirectories=""
ModuleDefinitionFile=".\AdbWinApi.def"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="..\build\$(OutDir)\i386/$(ProjectName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="..\build\$(OutDir)\i386/AdbWinApi.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="FALSE"
TargetEnvironment="1"
GenerateStublessProxies="TRUE"
TypeLibraryName="$(IntDir)/AdbWinApi.tlb"
HeaderFileName="AdbWinApi.h"
DLLDataFileName=""
InterfaceIdentifierFileName="AdbWinApi_i.c"
ProxyFileName="AdbWinApi_p.c"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
AdditionalIncludeDirectories="$(IntDir)"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\adb_api.cpp">
</File>
<File
RelativePath=".\adb_endpoint_object.cpp">
</File>
<File
RelativePath=".\adb_helper_routines.cpp">
</File>
<File
RelativePath=".\adb_interface.cpp">
</File>
<File
RelativePath=".\adb_interface_enum.cpp">
</File>
<File
RelativePath=".\adb_io_completion.cpp">
</File>
<File
RelativePath=".\adb_io_object.cpp">
</File>
<File
RelativePath=".\adb_object_handle.cpp">
</File>
<File
RelativePath=".\AdbWinApi.cpp">
</File>
<File
RelativePath=".\AdbWinApi.def">
</File>
<File
RelativePath=".\stdafx.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\adb_api.h">
</File>
<File
RelativePath=".\adb_api_private_defines.h">
</File>
<File
RelativePath=".\adb_endpoint_object.h">
</File>
<File
RelativePath=".\adb_helper_routines.h">
</File>
<File
RelativePath=".\adb_interface.h">
</File>
<File
RelativePath=".\adb_interface_enum.h">
</File>
<File
RelativePath=".\adb_io_completion.h">
</File>
<File
RelativePath=".\adb_io_object.h">
</File>
<File
RelativePath=".\adb_object_handle.h">
</File>
<File
RelativePath=".\Resource.h">
</File>
<File
RelativePath=".\stdafx.h">
</File>
<Filter
Name="common"
Filter="">
<File
RelativePath=".\adb_api_extra.h">
</File>
<File
RelativePath="..\common\android_usb_common_defines.h">
</File>
</Filter>
<Filter
Name="USB"
Filter="">
<File
RelativePath="..\..\..\..\..\..\..\..\Winddk\6000\inc\api\usb.h">
</File>
<File
RelativePath="..\..\..\..\..\..\..\..\Winddk\6000\inc\api\usb100.h">
</File>
<File
RelativePath="..\..\..\..\..\..\..\..\Winddk\6000\inc\api\usb200.h">
</File>
<File
RelativePath="..\..\..\..\..\..\..\..\Winddk\6000\inc\api\usbdi.h">
</File>
</Filter>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
<File
RelativePath=".\AdbWinApi.rc">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

22
host/windows/usb/api/MAKEFILE Executable file
View File

@@ -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

View File

@@ -1,34 +1,34 @@
/* /*
* Copyright (C) 2008 The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
//{{NO_DEPENDENCIES}} //{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file. // Microsoft Visual C++ generated include file.
// Used by AdbWinApi.rc // Used by AdbWinApi.rc
// //
#define IDS_PROJNAME 100 #define IDS_PROJNAME 100
#define IDR_ADBWINAPI 101 #define IDR_ADBWINAPI 101
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 201 #define _APS_NEXT_RESOURCE_VALUE 201
#define _APS_NEXT_COMMAND_VALUE 32768 #define _APS_NEXT_COMMAND_VALUE 32768
#define _APS_NEXT_CONTROL_VALUE 201 #define _APS_NEXT_CONTROL_VALUE 201
#define _APS_NEXT_SYMED_VALUE 102 #define _APS_NEXT_SYMED_VALUE 102
#endif #endif
#endif #endif

96
host/windows/usb/api/SOURCES Executable file
View File

@@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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__

View File

@@ -1,47 +1,47 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/** \file /** \file
This file consists of implementation of class AdbApiInstance that is a main This file consists of implementation of class AdbApiInstance that is a main
API object representing a device interface that is in the interest of API object representing a device interface that is in the interest of
the API client. All device (interface) related operations go through this the API client. All device (interface) related operations go through this
class first. class first.
*/ */
#include "stdafx.h" #include "stdafx.h"
#include "adb_api_instance.h" #include "adb_api_instance.h"
#include "adb_helper_routines.h" #include "adb_helper_routines.h"
/// Map that holds all instances of this object /// Map that holds all instances of this object
AdbApiInstanceMap adb_app_instance_map; AdbApiInstanceMap adb_app_instance_map;
ULONG_PTR adb_app_instance_id = 0; ULONG_PTR adb_app_instance_id = 0;
CComAutoCriticalSection adb_app_instance_map_locker; CComAutoCriticalSection adb_app_instance_map_locker;
AdbApiInstance::AdbApiInstance() AdbApiInstance::AdbApiInstance()
: ref_count_(1) { : ref_count_(1) {
// Generate inteface handle // Generate inteface handle
adb_app_instance_map_locker.Lock(); adb_app_instance_map_locker.Lock();
adb_app_instance_id++; adb_app_instance_id++;
adb_app_instance_map_locker.Unlock(); adb_app_instance_map_locker.Unlock();
instance_handle_ = instance_handle_ =
reinterpret_cast<ADBAPIINSTANCEHANDLE>(adb_app_instance_id); reinterpret_cast<ADBAPIINSTANCEHANDLE>(adb_app_instance_id);
} }
AdbApiInstance::~AdbApiInstance() { AdbApiInstance::~AdbApiInstance() {
} }
void AdbApiInstance::LastReferenceReleased() { void AdbApiInstance::LastReferenceReleased() {
} }

View File

@@ -1,113 +1,113 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef ANDROID_USB_API_ADB_API_INSTANCE_H__ #ifndef ANDROID_USB_API_ADB_API_INSTANCE_H__
#define ANDROID_USB_API_ADB_API_INSTANCE_H__ #define ANDROID_USB_API_ADB_API_INSTANCE_H__
/** \file /** \file
This file consists of declaration of class AdbApiInstance that is a main This file consists of declaration of class AdbApiInstance that is a main
API object representing a device interface that is in the interest of API object representing a device interface that is in the interest of
the API client. All device (interface) related operations go through this the API client. All device (interface) related operations go through this
class first. class first.
*/ */
#include "adb_api.h" #include "adb_api.h"
#include "adb_api_private_defines.h" #include "adb_api_private_defines.h"
/** Class AdbApiInstance is the main API interbal object representing a device /** Class AdbApiInstance is the main API interbal object representing a device
interface that is in the interest of the API client. All device (interface) interface that is in the interest of the API client. All device (interface)
related operations go through this class first. So, before doing anything related operations go through this class first. So, before doing anything
meaningfull with the API a client must first create instance of the API meaningfull with the API a client must first create instance of the API
via CreateAdbApiInstance, select a device interface for that instance and via CreateAdbApiInstance, select a device interface for that instance and
then do everything else. then do everything else.
Objects of this class are globally stored in the map that matches Objects of this class are globally stored in the map that matches
ADBAPIINSTANCEHANDLE to the corresponded object. ADBAPIINSTANCEHANDLE to the corresponded object.
This class is self-referenced with the following reference model: 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 1. When object of this class is created and added to the map, its recount
is set to 1. is set to 1.
2. Every time the client makes an API call that uses ADBAPIINSTANCEHANDLE 2. Every time the client makes an API call that uses ADBAPIINSTANCEHANDLE
a corresponded AdbApiInstance object is looked up in the table and its a corresponded AdbApiInstance object is looked up in the table and its
refcount is incremented. Upon return from the API call that incremented refcount is incremented. Upon return from the API call that incremented
the refcount refcount gets decremented. the refcount refcount gets decremented.
3. When the client closes ADBAPIINSTANCEHANDLE via DeleteAdbApiInstance call 3. When the client closes ADBAPIINSTANCEHANDLE via DeleteAdbApiInstance call
corresponded object gets deleted from the map and its refcount is corresponded object gets deleted from the map and its refcount is
decremented. decremented.
So, at the end, this object destroys itself when refcount drops to zero. So, at the end, this object destroys itself when refcount drops to zero.
*/ */
class AdbApiInstance { class AdbApiInstance {
public: public:
/** \brief Constructs the object /** \brief Constructs the object
@param handle[in] Instance handle associated with this object @param handle[in] Instance handle associated with this object
*/ */
AdbApiInstance(); AdbApiInstance();
private: private:
/// Destructs the object /// Destructs the object
~AdbApiInstance(); ~AdbApiInstance();
/** \brief /** \brief
This method is called when last reference to this object has been released 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" In this method object is uninitialized and deleted (that is "delete this"
is called). is called).
*/ */
void LastReferenceReleased(); void LastReferenceReleased();
public: public:
/// Gets name of the USB interface (device name) for this instance /// Gets name of the USB interface (device name) for this instance
const std::wstring& interface_name() const { const std::wstring& interface_name() const {
return interface_name_; return interface_name_;
} }
/// References the object and returns number of references /// References the object and returns number of references
LONG AddRef() { LONG AddRef() {
return InterlockedIncrement(&ref_count_); return InterlockedIncrement(&ref_count_);
} }
/** \brief Dereferences the object and returns number of references /** \brief Dereferences the object and returns number of references
Object may be deleted in this method, so you cannot touch it after 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 this method returns, even if returned value is not zero, because object
can be deleted in another thread. can be deleted in another thread.
*/ */
LONG Release() { LONG Release() {
LONG ret = InterlockedDecrement(&ref_count_); LONG ret = InterlockedDecrement(&ref_count_);
if (0 == ret) if (0 == ret)
LastReferenceReleased(); LastReferenceReleased();
return ret; return ret;
} }
/// Checks if instance has been initialized /// Checks if instance has been initialized
bool IsInitialized() const { bool IsInitialized() const {
return !interface_name_.empty(); return !interface_name_.empty();
} }
private: private:
/// Name of the USB interface (device name) for this instance /// Name of the USB interface (device name) for this instance
std::wstring interface_name_; std::wstring interface_name_;
/// Instance handle for this object /// Instance handle for this object
ADBAPIINSTANCEHANDLE instance_handle_; ADBAPIINSTANCEHANDLE instance_handle_;
/// Reference counter for this instance /// Reference counter for this instance
LONG ref_count_; LONG ref_count_;
}; };
/// Defines map that matches ADBAPIINSTANCEHANDLE with AdbApiInstance object /// Defines map that matches ADBAPIINSTANCEHANDLE with AdbApiInstance object
typedef std::map< ADBAPIINSTANCEHANDLE, AdbApiInstance* > AdbApiInstanceMap; typedef std::map< ADBAPIINSTANCEHANDLE, AdbApiInstance* > AdbApiInstanceMap;
#endif // ANDROID_USB_API_ADB_API_INSTANCE_H__ #endif // ANDROID_USB_API_ADB_API_INSTANCE_H__

View File

@@ -1,115 +1,114 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__ #ifndef ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__
#define ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__ #define ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__
/** \file /** \file
This file consists of private definitions used inside the API This file consists of private definitions used inside the API
*/ */
#include "adb_api.h" #include "adb_api.h"
/** Class AdbInstanceEnumEntry encapsulates an entry in the array of /** \brief Encapsulates an entry in the array of enumerated interfaces.
enumerated interfaces. */
*/ class AdbInstanceEnumEntry {
class AdbInstanceEnumEntry { public:
public: /** \brief Constructs an empty object.
/** \brief Constructs an empty object. */
*/ AdbInstanceEnumEntry()
AdbInstanceEnumEntry() : flags_(0) {
: flags_(0) { ZeroMemory(&class_id_, sizeof(class_id_));
ZeroMemory(&class_id_, sizeof(class_id_)); }
}
/** \brief Copy constructor
/** \brief Copy constructor */
*/ AdbInstanceEnumEntry(const AdbInstanceEnumEntry& proto) {
AdbInstanceEnumEntry(const AdbInstanceEnumEntry& proto) { Set(proto.device_name().c_str(), proto.class_id(), proto.flags());
Set(proto.device_name().c_str(), proto.class_id(), proto.flags()); }
}
/** \brief Constructs the object with parameters.
/** \brief Constructs the object with parameters. */
*/ AdbInstanceEnumEntry(const wchar_t* dev_name, GUID cls_id, DWORD flgs) {
AdbInstanceEnumEntry(const wchar_t* dev_name, GUID cls_id, DWORD flgs) { Set(dev_name, cls_id, flgs);
Set(dev_name, cls_id, flgs); }
}
/** \brief Destructs the object.
/** \brief Destructs the object. */
*/ ~AdbInstanceEnumEntry() {
~AdbInstanceEnumEntry() { }
}
/// Operator =
/// Operator = AdbInstanceEnumEntry& operator=(const AdbInstanceEnumEntry& proto) {
AdbInstanceEnumEntry& operator=(const AdbInstanceEnumEntry& proto) { Set(proto.device_name().c_str(), proto.class_id(), proto.flags());
Set(proto.device_name().c_str(), proto.class_id(), proto.flags()); return *this;
return *this; }
}
/// Initializes instance with parameters
/// Initializes instance with parameters void Set(const wchar_t* dev_name, GUID cls_id, DWORD flgs) {
void Set(const wchar_t* dev_name, GUID cls_id, DWORD flgs) { device_name_ = dev_name;
device_name_ = dev_name; class_id_ = cls_id;
class_id_ = cls_id; flags_ = flgs;
flags_ = flgs; }
}
/// Calculates memory size needed to save this entry into AdbInterfaceInfo
/// Calculates memory size needed to save this entry into AdbInterfaceInfo /// structure
/// structure ULONG GetFlatSize() const {
ULONG GetFlatSize() const { return static_cast<ULONG>(FIELD_OFFSET(AdbInterfaceInfo, device_name) +
return static_cast<ULONG>(FIELD_OFFSET(AdbInterfaceInfo, device_name) + (device_name_.length() + 1) * sizeof(wchar_t));
(device_name_.length() + 1) * sizeof(wchar_t)); }
}
/** \brief Saves this entry into AdbInterfaceInfo structure.
/** \brief Saves this entry into AdbInterfaceInfo structure.
@param[in] info Buffer to save this entry to. Must be big enough to fit it.
@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.
Use GetFlatSize() method to get buffer size needed for that.
*/
*/ void Save(AdbInterfaceInfo* info) const {
void Save(AdbInterfaceInfo* info) const { info->class_id = class_id();
info->class_id = class_id(); info->flags = flags();
info->flags = flags(); wcscpy(info->device_name, device_name().c_str());
wcscpy(info->device_name, device_name().c_str()); }
}
/// Gets interface's device name
/// Gets interface's device name const std::wstring& device_name() const {
const std::wstring& device_name() const { return device_name_;
return device_name_; }
}
/// Gets inteface's class id
/// Gets inteface's class id GUID class_id() const {
GUID class_id() const { return class_id_;
return class_id_; }
}
/// Gets interface flags
/// Gets interface flags DWORD flags() const {
DWORD flags() const { return flags_;
return flags_; }
}
private:
private: /// Inteface's class id (see SP_DEVICE_INTERFACE_DATA)
/// Inteface's class id (see SP_DEVICE_INTERFACE_DATA) GUID class_id_;
GUID class_id_;
/// Interface's device name
/// Interface's device name std::wstring device_name_;
std::wstring device_name_;
/// Interface flags (see SP_DEVICE_INTERFACE_DATA)
/// Interface flags (see SP_DEVICE_INTERFACE_DATA) DWORD flags_;
DWORD flags_; };
};
/// Defines array of enumerated interface entries
/// Defines array of enumerated interface entries typedef std::vector< AdbInstanceEnumEntry > AdbEnumInterfaceArray;
typedef std::vector< AdbInstanceEnumEntry > AdbEnumInterfaceArray;
#endif // ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__
#endif // ANDROID_USB_ADB_API_PRIVATE_DEFINES_H__

View File

@@ -1,54 +1,221 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/** \file /** \file
This file consists of implementation of class AdbIOObject that This file consists of implementation of class AdbIOObject that
encapsulates an interface on our USB device. encapsulates an interface on our USB device.
*/ */
#include "stdafx.h" #include "stdafx.h"
#include "adb_endpoint_object.h" #include "adb_endpoint_object.h"
#include "adb_io_completion.h"
AdbEndpointObject::AdbEndpointObject(AdbInterfaceObject* parent_interf) #include "adb_helper_routines.h"
: AdbIOObject(parent_interf, AdbObjectTypeEndpoint) {
} AdbEndpointObject::AdbEndpointObject(AdbInterfaceObject* parent_interf,
UCHAR endpoint_id,
AdbEndpointObject::~AdbEndpointObject() { UCHAR endpoint_index)
} : AdbObjectHandle(AdbObjectTypeEndpoint),
parent_interface_(parent_interf),
bool AdbEndpointObject::IsObjectOfType(AdbObjectType obj_type) const { endpoint_id_(endpoint_id),
return ((obj_type == AdbObjectTypeEndpoint) || endpoint_index_(endpoint_index) {
(obj_type == AdbObjectTypeIo)); if (NULL != parent_interface_)
} parent_interface_->AddRef();
}
bool AdbEndpointObject::GetEndpointInformation(AdbEndpointInformation* info) {
if (!IsOpened() || !IsUsbOpened()) { AdbEndpointObject::~AdbEndpointObject() {
SetLastError(ERROR_INVALID_HANDLE); if (NULL != parent_interface_)
return false; parent_interface_->Release();
} }
// Send IOCTL bool AdbEndpointObject::GetEndpointInformation(AdbEndpointInformation* info) {
DWORD ret_bytes = 0; if (!IsOpened()) {
BOOL ret = DeviceIoControl(usb_handle(), SetLastError(ERROR_INVALID_HANDLE);
ADB_IOCTL_GET_ENDPOINT_INFORMATION, return false;
NULL, 0, }
info, sizeof(AdbEndpointInformation),
&ret_bytes, return parent_interface()->GetEndpointInformation(endpoint_index(), info);
NULL); }
ATLASSERT(!ret || (sizeof(AdbEndpointInformation) == ret_bytes));
ADBAPIHANDLE AdbEndpointObject::AsyncRead(void* buffer,
return ret ? true : false; 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<PUCHAR>(buffer),
bytes_to_transfer,
&transferred,
adb_io_completion->overlapped()) :
WinUsb_WritePipe(parent_interface()->winusb_handle(),
endpoint_id(),
reinterpret_cast<PUCHAR>(buffer),
bytes_to_transfer,
&transferred,
adb_io_completion->overlapped());
if (NULL != bytes_transferred)
*bytes_transferred = transferred;
ULONG error = GetLastError();
if (!res && (ERROR_IO_PENDING != error)) {
// I/O failed immediatelly. We need to close i/o completion object
// before we return NULL to the caller.
adb_io_completion->CloseHandle();
ret = NULL;
SetLastError(error);
}
}
// Offseting 'new'
adb_io_completion->Release();
return ret;
}
bool 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<PUCHAR>(buffer),
bytes_to_transfer,
&transferred,
&overlapped) :
WinUsb_WritePipe(parent_interface()->winusb_handle(),
endpoint_id(),
reinterpret_cast<PUCHAR>(buffer),
bytes_to_transfer,
&transferred,
&overlapped);
// Lets see the result
if (!ret && (ERROR_IO_PENDING != GetLastError())) {
// I/O failed.
if (NULL != overlapped.hEvent)
::CloseHandle(overlapped.hEvent);
return false;
}
// Lets wait till I/O completes
ret = WinUsb_GetOverlappedResult(parent_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;
}

View File

@@ -1,71 +1,233 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef ANDROID_USB_API_ADB_ENDPOINT_OBJECT_H__ #ifndef ANDROID_USB_API_ADB_ENDPOINT_OBJECT_H__
#define ANDROID_USB_API_ADB_ENDPOINT_OBJECT_H__ #define ANDROID_USB_API_ADB_ENDPOINT_OBJECT_H__
/** \file /** \file
This file consists of declaration of class AdbIOObject that encapsulates a This file consists of declaration of class AdbIOObject that encapsulates a
handle opened to an endpoint on our device. handle opened to an endpoint on our device.
*/ */
#include "adb_io_object.h" #include "adb_interface.h"
/** Class AdbEndpointObject encapsulates a handle opened to an endpoint on /** Class AdbEndpointObject encapsulates a handle opened to an endpoint on
our device. our device.
*/ */
class AdbEndpointObject : public AdbIOObject { class AdbEndpointObject : public AdbObjectHandle {
public: public:
/** \brief Constructs the object /** \brief Constructs the object
@param interface[in] Parent interface for this object. Interface will be @param[in] interface Parent interface for this object. Interface will be
referenced in this object's constructur and released in the referenced in this object's constructur and released in the
destructor. destructor.
@param obj_type[in] Object type from AdbObjectType enum @param[in] endpoint_id Endpoint ID (endpoint address) on the device.
*/ @param[in] endpoint_index Zero-based endpoint index in the interface's
AdbEndpointObject(AdbInterfaceObject* parent_interf); array of endpoints.
*/
protected: AdbEndpointObject(AdbInterfaceObject* parent_interf,
/** \brief Destructs the object. UCHAR endpoint_id,
UCHAR endpoint_index);
parent_interface_ will be dereferenced here.
We hide destructor in order to prevent ourseves from accidentaly allocating protected:
instances on the stack. If such attemp occur, compiler will error. /** \brief Destructs the object.
*/
virtual ~AdbEndpointObject(); We hide destructor in order to prevent ourseves from accidentaly allocating
instances on the stack. If such attemp occur, compiler will error.
public: */
/** \brief Gets information about this endpoint. virtual ~AdbEndpointObject();
@param info[out] Upon successful completion will have endpoint information. public:
@return 'true' on success, 'false' on failure. If 'false' is returned /** \brief Gets information about this endpoint.
GetLastError() provides extended error information.
*/ @param[out] info Upon successful completion will have endpoint information.
bool GetEndpointInformation(AdbEndpointInformation* info); @return true on success, false on failure. If false is returned
GetLastError() provides extended error information.
/** \brief Checks if this object is of the given type */
bool GetEndpointInformation(AdbEndpointInformation* info);
@param obj_type[in] One of the AdbObjectType types to check
@return 'true' is this object type matches obj_type and 'false' otherwise. /** \brief Reads from opened I/O object asynchronously
*/
virtual bool IsObjectOfType(AdbObjectType obj_type) const; @param[out] buffer Pointer to the buffer that receives the data.
@param[in] bytes_to_read Number of bytes to be read.
// This is a helper for extracting object from the AdbObjectHandleMap @param[out] bytes_read Number of bytes read. Can be NULL.
static AdbObjectType Type() { @param[in] event_handle Event handle that should be signaled when async I/O
return AdbObjectTypeEndpoint; 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
#endif // ANDROID_USB_API_ADB_ENDPOINT_OBJECT_H__ 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__

View File

@@ -1,248 +1,189 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/** \file /** \file
This file consists of implementation of helper routines used This file consists of implementation of helper routines used
in the API. in the API.
*/ */
#include "stdafx.h" #include "stdafx.h"
#include "adb_api.h" #include "adb_api.h"
#include "adb_helper_routines.h" #include "adb_helper_routines.h"
#include "adb_interface_enum.h" #include "adb_interface_enum.h"
bool GetSDKComplientParam(AdbOpenAccessType access_type, bool EnumerateDeviceInterfaces(HDEVINFO hardware_dev_info,
AdbOpenSharingMode sharing_mode, GUID class_id,
ULONG* desired_access, bool exclude_removed,
ULONG* desired_sharing) { bool active_only,
if (NULL != desired_access) { AdbEnumInterfaceArray* interfaces) {
switch (access_type) { AdbEnumInterfaceArray tmp;
case AdbOpenAccessTypeReadWrite: bool ret = false;
*desired_access = GENERIC_READ | GENERIC_WRITE;
break; // Enumerate interfaces on this device
for (ULONG index = 0; ; index++) {
case AdbOpenAccessTypeRead: SP_DEVICE_INTERFACE_DATA interface_data;
*desired_access = GENERIC_READ; interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
break;
// SetupDiEnumDeviceInterfaces() returns information about device
case AdbOpenAccessTypeWrite: // interfaces exposed by one or more devices defined by our interface
*desired_access = GENERIC_WRITE; // class. Each call returns information about one interface. The routine
break; // can be called repeatedly to get information about several interfaces
// exposed by one or more devices.
case AdbOpenAccessTypeQueryInfo: if (SetupDiEnumDeviceInterfaces(hardware_dev_info,
*desired_access = FILE_READ_ATTRIBUTES | FILE_READ_EA; 0,
break; &class_id,
index,
default: &interface_data)) {
AtlTrace("\n!!!!! ADB API -> GetSDKComplientParam %u is unknown access type", // Satisfy "exclude removed" and "active only" filters.
access_type); if ((!exclude_removed || (0 == (interface_data.Flags & SPINT_REMOVED))) &&
SetLastError(ERROR_INVALID_ACCESS); (!active_only || (interface_data.Flags & SPINT_ACTIVE))) {
return false; std::wstring dev_name;
}
} if (GetUsbDeviceName(hardware_dev_info, &interface_data, &dev_name)) {
try {
if (NULL != desired_sharing) { // Add new entry to the array
switch (sharing_mode) { tmp.push_back(AdbInstanceEnumEntry(dev_name.c_str(),
case AdbOpenSharingModeReadWrite: interface_data.InterfaceClassGuid,
*desired_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; interface_data.Flags));
break; } catch (... ) {
SetLastError(ERROR_OUTOFMEMORY);
case AdbOpenSharingModeRead: break;
*desired_sharing = FILE_SHARE_READ; }
break; } else {
// Something went wrong in getting device name
case AdbOpenSharingModeWrite: break;
*desired_sharing = FILE_SHARE_WRITE; }
break; }
} else {
case AdbOpenSharingModeExclusive: if (ERROR_NO_MORE_ITEMS == GetLastError()) {
*desired_sharing = 0; // There are no more items in the list. Enum is completed.
break; ret = true;
break;
default: } else {
AtlTrace("\n!!!!! ADB API -> GetSDKComplientParam %u is unknown share mode", // Something went wrong in SDK enum
sharing_mode); break;
SetLastError(ERROR_INVALID_PARAMETER); }
return false; }
} }
}
// On success, swap temp array with the returning one
return true; if (ret)
} interfaces->swap(tmp);
bool EnumerateDeviceInterfaces(HDEVINFO hardware_dev_info, return ret;
GUID class_id, }
bool exclude_removed,
bool active_only, bool EnumerateDeviceInterfaces(GUID class_id,
AdbEnumInterfaceArray* interfaces) { ULONG flags,
AdbEnumInterfaceArray tmp; bool exclude_removed,
bool ret = false; bool active_only,
AdbEnumInterfaceArray* interfaces) {
// Enumerate interfaces on this device // Open a handle to the plug and play dev node.
for (ULONG index = 0; ; index++) { // SetupDiGetClassDevs() returns a device information set that
SP_DEVICE_INTERFACE_DATA interface_data; // contains info on all installed devices of a specified class.
interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); HDEVINFO hardware_dev_info =
SetupDiGetClassDevs(&class_id, NULL, NULL, flags);
// SetupDiEnumDeviceInterfaces() returns information about device
// interfaces exposed by one or more devices defined by our interface bool ret = false;
// class. Each call returns information about one interface. The routine
// can be called repeatedly to get information about several interfaces if (INVALID_HANDLE_VALUE != hardware_dev_info) {
// exposed by one or more devices. // Do the enum
if (SetupDiEnumDeviceInterfaces(hardware_dev_info, ret = EnumerateDeviceInterfaces(hardware_dev_info,
0, class_id,
&class_id, exclude_removed,
index, active_only,
&interface_data)) { interfaces);
// Satisfy "exclude removed" and "active only" filters.
if ((!exclude_removed || (0 == (interface_data.Flags & SPINT_REMOVED))) && // Preserve last error accross hardware_dev_info destruction
(!active_only || (interface_data.Flags & SPINT_ACTIVE))) { ULONG error_to_report = ret ? NO_ERROR : GetLastError();
std::wstring dev_name;
SetupDiDestroyDeviceInfoList(hardware_dev_info);
if (GetUsbDeviceName(hardware_dev_info, &interface_data, &dev_name)) {
try { if (NO_ERROR != error_to_report)
// Add new entry to the array SetLastError(error_to_report);
tmp.push_back(AdbInstanceEnumEntry(dev_name.c_str(), }
interface_data.InterfaceClassGuid,
interface_data.Flags)); return ret;
} catch (... ) { }
SetLastError(ERROR_OUTOFMEMORY);
break; bool GetUsbDeviceDetails(
} HDEVINFO hardware_dev_info,
} else { PSP_DEVICE_INTERFACE_DATA dev_info_data,
// Something went wrong in getting device name PSP_DEVICE_INTERFACE_DETAIL_DATA* dev_info_detail_data) {
break; ULONG required_len = 0;
}
} // First query for the structure size. At this point we expect this call
} else { // to fail with ERROR_INSUFFICIENT_BUFFER error code.
if (ERROR_NO_MORE_ITEMS == GetLastError()) { if (SetupDiGetDeviceInterfaceDetail(hardware_dev_info,
// There are no more items in the list. Enum is completed. dev_info_data,
ret = true; NULL,
break; 0,
} else { &required_len,
// Something went wrong in SDK enum NULL)) {
break; return false;
} }
}
} if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
return false;
// On success, swap temp array with the returning one
if (ret) // Allocate buffer for the structure
interfaces->swap(tmp); PSP_DEVICE_INTERFACE_DETAIL_DATA buffer =
reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(malloc(required_len));
return ret;
} if (NULL == buffer) {
SetLastError(ERROR_OUTOFMEMORY);
bool EnumerateDeviceInterfaces(GUID class_id, return false;
ULONG flags, }
bool exclude_removed,
bool active_only, buffer->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
AdbEnumInterfaceArray* interfaces) {
// Open a handle to the plug and play dev node. // Retrieve the information from Plug and Play.
// SetupDiGetClassDevs() returns a device information set that if (SetupDiGetDeviceInterfaceDetail(hardware_dev_info,
// contains info on all installed devices of a specified class. dev_info_data,
HDEVINFO hardware_dev_info = buffer,
SetupDiGetClassDevs(&class_id, NULL, NULL, flags); required_len,
&required_len,
bool ret = false; NULL)) {
*dev_info_detail_data = buffer;
if (INVALID_HANDLE_VALUE != hardware_dev_info) { return true;
// Do the enum } else {
ret = EnumerateDeviceInterfaces(hardware_dev_info, // Free the buffer if this call failed
class_id, free(buffer);
exclude_removed,
active_only, return false;
interfaces); }
}
// Preserve last error accross hardware_dev_info destruction
ULONG error_to_report = ret ? NO_ERROR : GetLastError(); bool GetUsbDeviceName(HDEVINFO hardware_dev_info,
PSP_DEVICE_INTERFACE_DATA dev_info_data,
SetupDiDestroyDeviceInfoList(hardware_dev_info); std::wstring* name) {
PSP_DEVICE_INTERFACE_DETAIL_DATA func_class_dev_data = NULL;
if (NO_ERROR != error_to_report) if (!GetUsbDeviceDetails(hardware_dev_info,
SetLastError(error_to_report); dev_info_data,
} &func_class_dev_data)) {
return false;
return ret; }
}
try {
bool GetUsbDeviceDetails( *name = func_class_dev_data->DevicePath;
HDEVINFO hardware_dev_info, } catch (...) {
PSP_DEVICE_INTERFACE_DATA dev_info_data, SetLastError(ERROR_OUTOFMEMORY);
PSP_DEVICE_INTERFACE_DETAIL_DATA* dev_info_detail_data) { }
ULONG required_len = 0;
free(func_class_dev_data);
// First query for the structure size. At this point we expect this call
// to fail with ERROR_INSUFFICIENT_BUFFER error code. return !name->empty();
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<PSP_DEVICE_INTERFACE_DETAIL_DATA>(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();
}

View File

@@ -1,126 +1,109 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef ANDROID_USB_API_ADB_HELPER_ROUTINES_H__ #ifndef ANDROID_USB_API_ADB_HELPER_ROUTINES_H__
#define ANDROID_USB_API_ADB_HELPER_ROUTINES_H__ #define ANDROID_USB_API_ADB_HELPER_ROUTINES_H__
/** \file /** \file
This file consists of declarations of helper routines used This file consists of declarations of helper routines used
in the API. in the API.
*/ */
#include "adb_api_private_defines.h" #include "adb_api_private_defines.h"
/** \brief Converts access type and share mode from our enum into /** \brief Given the hardware device information enumerates interfaces for
SDK - complient values. this device.
@param access_type[in] Enumerated access type @param[in] hardware_dev_info A handle to hardware device information obtained
@param sharing_mode[in] Enumerated share mode from PnP manager via SetupDiGetClassDevs()
@param desired_access[out] Will receive SDK - complient desired access @param[in] class_id Device class ID how it is specified by our USB driver.
flags. This parameter can be NULL. @param[in] exclude_removed If true interfaces with SPINT_REMOVED flag set
@param desired_sharing[out] Will receive SDK - complient share mode. will be not included in the enumeration.
This parameter can be NULL. @param[in] active_only If true only active interfaces (with flag
@return True on success, false on failure, in which case GetLastError() SPINT_ACTIVE set) will be included in the enumeration.
provides extended information about the error that occurred. @param[out] interfaces Upon successfull completion will consist of array of
*/ all interfaces found for this device (matching all filters).
bool GetSDKComplientParam(AdbOpenAccessType access_type, @return True on success, false on failure, in which case GetLastError()
AdbOpenSharingMode sharing_mode, provides extended information about the error that occurred.
ULONG* desired_access, */
ULONG* desired_sharing); bool EnumerateDeviceInterfaces(HDEVINFO hardware_dev_info,
GUID class_id,
/** \brief bool exclude_removed,
Given the hardware device information enumerates interfaces for this device bool active_only,
AdbEnumInterfaceArray* interfaces);
@param hardware_dev_info[in] A handle to hardware device information obtained
from PnP manager via SetupDiGetClassDevs() /** \brief Enumerates all interfaces for our device class.
@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 This routine uses SetupDiGetClassDevs to get our device info and calls
will be not included in the enumeration. EnumerateDeviceInterfaces to perform the enumeration.
@param active_only[in] If 'true' only active interfaces (with flag @param[in] class_id Device class ID how it is specified by our USB driver
SPINT_ACTIVE set) will be included in the enumeration. @param[in] flags Flags to pass to SetupDiGetClassDevs to filter devices. See
@param interfaces[out] Upon successfull completion will consist of array of SetupDiGetClassDevs() in SDK for more info on these flags.
all interfaces found for this device (matching all filters). @param[in] exclude_removed If true interfaces with SPINT_REMOVED flag set
@return True on success, false on failure, in which case GetLastError() will be not included in the enumeration.
provides extended information about the error that occurred. @param[in] active_only If true only active interfaces (with flag
*/ SPINT_ACTIVE set) will be included in the enumeration.
bool EnumerateDeviceInterfaces(HDEVINFO hardware_dev_info, @param[out] interfaces Upon successfull completion will consist of array of
GUID class_id, all interfaces found for this device (matching all filters).
bool exclude_removed, @return True on success, false on failure, in which case GetLastError()
bool active_only, provides extended information about the error that occurred.
AdbEnumInterfaceArray* interfaces); */
bool EnumerateDeviceInterfaces(GUID class_id,
/** \brief Enumerates all interfaces for our device class ULONG flags,
bool exclude_removed,
This routine uses SetupDiGetClassDevs to get our device info and calls bool active_only,
EnumerateDeviceInterfaces to perform the enumeration. AdbEnumInterfaceArray* interfaces);
@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 /** \brief Given the hardware device information and data gets data details.
SetupDiGetClassDevs() in SDK for more info on these flags.
@param exclude_removed[in] If true interfaces with SPINT_REMOVED flag set Given the hardware_dev_info, representing a handle to the plug and
will be not included in the enumeration. play information, and dev_info_data, representing a specific usb device,
@param active_only[in] If 'true' only active interfaces (with flag gets detailed data about the device (interface).
SPINT_ACTIVE set) will be included in the enumeration. @param[in] hardware_dev_info A handle to hardware device information obtained
@param interfaces[out] Upon successfull completion will consist of array of from PnP manager via SetupDiGetClassDevs()
all interfaces found for this device (matching all filters). @param[in] dev_info_data Device information data obtained via call to
@return True on success, false on failure, in which case GetLastError() SetupDiEnumDeviceInterfaces()
provides extended information about the error that occurred. @param[out] dev_info_detail_data Upon successfull completion will consist of
*/ the detailed data about device interface. This routine always
bool EnumerateDeviceInterfaces(GUID class_id, allocates memory for the output structure so content of this pointer
ULONG flags, doesn't matter and will be overwritten by this routine. The caller
bool exclude_removed, of this method is responsible for freeing allocated data using free()
bool active_only, routine.
AdbEnumInterfaceArray* interfaces); @return True on success, false on failure, in which case GetLastError()
provides extended information about the error that occurred.
/** \brief Given the hardware device information and data gets data details */
bool GetUsbDeviceDetails(HDEVINFO hardware_dev_info,
Given the hardware_dev_info, representing a handle to the plug and PSP_DEVICE_INTERFACE_DATA dev_info_data,
play information, and dev_info_data, representing a specific usb device, PSP_DEVICE_INTERFACE_DETAIL_DATA* dev_info_detail_data);
gets detailed data about the device (interface).
@param hardware_dev_info[in] A handle to hardware device information obtained /** \brief Given the hardware device information and data gets device name.
from PnP manager via SetupDiGetClassDevs()
@param dev_info_data[in] Device information data obtained via call to Given the hardware_dev_info, representing a handle to the plug and
SetupDiEnumDeviceInterfaces() play information, and dev_info_data, representing a specific usb device,
@param dev_info_detail_data[out] Upon successfull completion will consist of gets device name. This routine uses GetUsbDeviceDetails to extract device
the detailed data about device interface. This routine always name.
allocates memory for the output structure so content of this pointer @param[in] hardware_dev_info A handle to hardware device information obtained
doesn't matter and will be overwritten by this routine. The caller from PnP manager via SetupDiGetClassDevs()
of this method is responsible for freeing allocated data using free() @param[in] dev_info_data Device information data obtained via call to
routine. SetupDiEnumDeviceInterfaces()
@return True on success, false on failure, in which case GetLastError() @param[out] name Upon successfull completion will have name for the device.
provides extended information about the error that occurred. @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, bool GetUsbDeviceName(HDEVINFO hardware_dev_info,
PSP_DEVICE_INTERFACE_DETAIL_DATA* dev_info_detail_data); PSP_DEVICE_INTERFACE_DATA dev_info_data,
std::wstring* name);
/** \brief Given the hardware device information and data gets device name.
#endif // ANDROID_USB_API_ADB_HELPER_ROUTINES_H__
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__

View File

@@ -1,344 +1,413 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/** \file /** \file
This file consists of implementation of class AdbInterfaceObject that This file consists of implementation of class AdbInterfaceObject that
encapsulates an interface on our USB device. encapsulates an interface on our USB device.
*/ */
#include "stdafx.h" #include "stdafx.h"
#include "adb_interface.h" #include "adb_interface.h"
#include "adb_endpoint_object.h" #include "adb_endpoint_object.h"
AdbInterfaceObject::AdbInterfaceObject(const wchar_t* interf_name) AdbInterfaceObject::AdbInterfaceObject(const wchar_t* interf_name)
: AdbObjectHandle(AdbObjectTypeInterface), : AdbObjectHandle(AdbObjectTypeInterface),
interface_name_(interf_name) { interface_name_(interf_name),
ATLASSERT(NULL != interf_name); usb_device_handle_(INVALID_HANDLE_VALUE),
} winusb_handle_(NULL),
interface_number_(0xFF),
AdbInterfaceObject::~AdbInterfaceObject() { def_read_endpoint_(0xFF),
} read_endpoint_id_(0xFF),
def_write_endpoint_(0xFF),
ADBAPIHANDLE AdbInterfaceObject::CreateHandle() { write_endpoint_id_(0xFF) {
// Open USB device for this intefface ATLASSERT(NULL != interf_name);
HANDLE usb_device_handle = CreateFile(interface_name().c_str(), }
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, AdbInterfaceObject::~AdbInterfaceObject() {
NULL, ATLASSERT(NULL == winusb_handle_);
OPEN_EXISTING, ATLASSERT(INVALID_HANDLE_VALUE == usb_device_handle_);
0, }
NULL);
if (INVALID_HANDLE_VALUE == usb_device_handle) ADBAPIHANDLE AdbInterfaceObject::CreateHandle() {
return NULL; // Open USB device for this inteface Note that WinUsb API
// requires the handle to be opened for overlapped I/O.
// Now, we ensured that our usb device / interface is up and running. usb_device_handle_ = CreateFile(interface_name().c_str(),
// Lets collect device, interface and pipe information GENERIC_READ | GENERIC_WRITE,
bool ok = true; FILE_SHARE_READ | FILE_SHARE_WRITE,
if (!CacheUsbDeviceDescriptor(usb_device_handle) || NULL, OPEN_EXISTING,
!CacheUsbConfigurationDescriptor(usb_device_handle) || FILE_FLAG_OVERLAPPED, NULL);
!CacheUsbInterfaceDescriptor(usb_device_handle)) { if (INVALID_HANDLE_VALUE == usb_device_handle_)
ok = false; return NULL;
}
// Initialize WinUSB API for this interface
// Preserve error accross handle close if (!WinUsb_Initialize(usb_device_handle_, &winusb_handle_))
ULONG error = ok ? NO_ERROR : GetLastError(); return NULL;
::CloseHandle(usb_device_handle); // Cache current interface number that will be used in
// WinUsb_Xxx calls performed on this interface.
if (NO_ERROR != error) if (!WinUsb_GetCurrentAlternateSetting(winusb_handle(), &interface_number_))
SetLastError(error); return false;
if (!ok) // Cache interface properties
return false; unsigned long bytes_written;
return AdbObjectHandle::CreateHandle(); // Cache USB device descriptor
} if (!WinUsb_GetDescriptor(winusb_handle(), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0,
reinterpret_cast<PUCHAR>(&usb_device_descriptor_),
bool AdbInterfaceObject::GetInterfaceName(void* buffer, sizeof(usb_device_descriptor_), &bytes_written)) {
unsigned long* buffer_char_size, return false;
bool ansi) { }
// Lets see if buffer is big enough
ULONG name_len = static_cast<ULONG>(interface_name_.length() + 1); // Cache USB configuration descriptor
if ((NULL == buffer) || (*buffer_char_size < name_len)) { if (!WinUsb_GetDescriptor(winusb_handle(), USB_CONFIGURATION_DESCRIPTOR_TYPE,
*buffer_char_size = name_len; 0, 0,
SetLastError(ERROR_INSUFFICIENT_BUFFER); reinterpret_cast<PUCHAR>(&usb_config_descriptor_),
return false; sizeof(usb_config_descriptor_), &bytes_written)) {
} return false;
}
if (!ansi) {
// If user asked for wide char name just return it // Cache USB interface descriptor
wcscpy(reinterpret_cast<wchar_t*>(buffer), interface_name().c_str()); if (!WinUsb_QueryInterfaceSettings(winusb_handle(), interface_number(),
return true; &usb_interface_descriptor_)) {
} return false;
}
// We need to convert name from wide char to ansi string
int res = WideCharToMultiByte(CP_ACP, // Save indexes and IDs for bulk read / write endpoints. We will use them to
0, // convert ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX and
interface_name().c_str(), // ADB_QUERY_BULK_READ_ENDPOINT_INDEX into actual endpoint indexes and IDs.
static_cast<int>(name_len), for (UCHAR endpoint = 0; endpoint < usb_interface_descriptor_.bNumEndpoints;
reinterpret_cast<PSTR>(buffer), endpoint++) {
static_cast<int>(*buffer_char_size), // Get endpoint information
NULL, WINUSB_PIPE_INFORMATION pipe_info;
NULL); if (!WinUsb_QueryPipe(winusb_handle(), interface_number(), endpoint,
return (res != 0); &pipe_info)) {
} return false;
}
bool AdbInterfaceObject::GetSerialNumber(void* buffer,
unsigned long* buffer_char_size, if (UsbdPipeTypeBulk == pipe_info.PipeType) {
bool ansi) { // This is a bulk endpoint. Cache its index and ID.
if (!IsOpened()) { if (0 != (pipe_info.PipeId & USB_ENDPOINT_DIRECTION_MASK)) {
SetLastError(ERROR_INVALID_HANDLE); // Use this endpoint as default bulk read endpoint
return false; ATLASSERT(0xFF == def_read_endpoint_);
} def_read_endpoint_ = endpoint;
read_endpoint_id_ = pipe_info.PipeId;
// Open USB device for this intefface } else {
HANDLE usb_device_handle = CreateFile(interface_name().c_str(), // Use this endpoint as default bulk write endpoint
GENERIC_READ, ATLASSERT(0xFF == def_write_endpoint_);
FILE_SHARE_READ | FILE_SHARE_WRITE, def_write_endpoint_ = endpoint;
NULL, write_endpoint_id_ = pipe_info.PipeId;
OPEN_EXISTING, }
0, }
NULL); }
if (INVALID_HANDLE_VALUE == usb_device_handle)
return NULL; return AdbObjectHandle::CreateHandle();
}
WCHAR serial_number[512];
bool AdbInterfaceObject::CloseHandle() {
// Send IOCTL if (NULL != winusb_handle_) {
DWORD ret_bytes = 0; WinUsb_Free(winusb_handle_);
BOOL ret = DeviceIoControl(usb_device_handle, winusb_handle_ = NULL;
ADB_IOCTL_GET_SERIAL_NUMBER, }
NULL, 0, if (INVALID_HANDLE_VALUE != usb_device_handle_) {
serial_number, sizeof(serial_number), ::CloseHandle(usb_device_handle_);
&ret_bytes, usb_device_handle_ = INVALID_HANDLE_VALUE;
NULL); }
// Preserve error accross CloseHandle return AdbObjectHandle::CloseHandle();
ULONG error = ret ? NO_ERROR : GetLastError(); }
::CloseHandle(usb_device_handle); bool AdbInterfaceObject::GetInterfaceName(void* buffer,
unsigned long* buffer_char_size,
if (NO_ERROR != error) { bool ansi) {
SetLastError(error); if (NULL == buffer_char_size) {
return false; SetLastError(ERROR_INVALID_PARAMETER);
} return false;
}
unsigned long str_len =
static_cast<unsigned long>(wcslen(serial_number) + 1); // Lets see if buffer is big enough
ULONG name_len = static_cast<ULONG>(interface_name_.length() + 1);
if ((NULL == buffer) || (*buffer_char_size < str_len)) { if ((NULL == buffer) || (*buffer_char_size < name_len)) {
*buffer_char_size = str_len; *buffer_char_size = name_len;
SetLastError(ERROR_INSUFFICIENT_BUFFER); SetLastError(ERROR_INSUFFICIENT_BUFFER);
return false; return false;
} }
if (!ansi) { if (!ansi) {
// If user asked for wide char name just return it // If user asked for wide char name just return it
wcscpy(reinterpret_cast<wchar_t*>(buffer), serial_number); wcscpy(reinterpret_cast<wchar_t*>(buffer), interface_name().c_str());
return true; return true;
} }
// We need to convert name from wide char to ansi string // We need to convert name from wide char to ansi string
int res = WideCharToMultiByte(CP_ACP, int res = WideCharToMultiByte(CP_ACP,
0, 0,
serial_number, interface_name().c_str(),
static_cast<int>(str_len), static_cast<int>(name_len),
reinterpret_cast<PSTR>(buffer), reinterpret_cast<PSTR>(buffer),
static_cast<int>(*buffer_char_size), static_cast<int>(*buffer_char_size),
NULL, NULL,
NULL); NULL);
return (res != 0); return (res != 0);
} }
bool AdbInterfaceObject::GetUsbDeviceDescriptor(USB_DEVICE_DESCRIPTOR* desc) { bool AdbInterfaceObject::GetSerialNumber(void* buffer,
if (!IsOpened()) { unsigned long* buffer_char_size,
SetLastError(ERROR_INVALID_HANDLE); bool ansi) {
return false; if (!IsOpened()) {
} SetLastError(ERROR_INVALID_HANDLE);
return false;
CopyMemory(desc, usb_device_descriptor(), sizeof(USB_DEVICE_DESCRIPTOR)); }
return true; if (NULL == buffer_char_size) {
} SetLastError(ERROR_INVALID_PARAMETER);
return false;
bool AdbInterfaceObject::GetUsbConfigurationDescriptor( }
USB_CONFIGURATION_DESCRIPTOR* desc) {
if (!IsOpened()) { // Calculate serial number string size. Note that WinUsb_GetDescriptor
SetLastError(ERROR_INVALID_HANDLE); // API will not return number of bytes needed to store serial number
return false; // 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.
CopyMemory(desc, usb_config_descriptor(), union {
sizeof(USB_CONFIGURATION_DESCRIPTOR)); // Preallocate reasonably sized buffer on the stack.
char small_buffer[64];
return true; USB_STRING_DESCRIPTOR initial_ser_num;
} };
USB_STRING_DESCRIPTOR* ser_num = &initial_ser_num;
bool AdbInterfaceObject::GetUsbInterfaceDescriptor( // Buffer byte size
USB_INTERFACE_DESCRIPTOR* desc) { unsigned long ser_num_size = sizeof(small_buffer);
if (!IsOpened()) { // After successful call to WinUsb_GetDescriptor will contain serial
SetLastError(ERROR_INVALID_HANDLE); // number descriptor size.
return false; unsigned long bytes_written;
} while (!WinUsb_GetDescriptor(winusb_handle(), USB_STRING_DESCRIPTOR_TYPE,
usb_device_descriptor_.iSerialNumber,
CopyMemory(desc, usb_interface_descriptor(), sizeof(USB_INTERFACE_DESCRIPTOR)); 0x0409, // English (US)
reinterpret_cast<PUCHAR>(ser_num),
return true; ser_num_size, &bytes_written)) {
} // Any error other than ERROR_INSUFFICIENT_BUFFER is terminal here.
if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) {
bool AdbInterfaceObject::GetEndpointInformation(UCHAR endpoint_index, if (ser_num != &initial_ser_num)
AdbEndpointInformation* info) { delete[] reinterpret_cast<char*>(ser_num);
if (!IsOpened()) { return false;
SetLastError(ERROR_INVALID_HANDLE); }
return false;
} // Double up buffer size and reallocate string buffer
ser_num_size *= 2;
// Open USB device for this intefface if (ser_num != &initial_ser_num)
HANDLE usb_device_handle = CreateFile(interface_name().c_str(), delete[] reinterpret_cast<char*>(ser_num);
GENERIC_READ, try {
FILE_SHARE_READ | FILE_SHARE_WRITE, ser_num =
NULL, reinterpret_cast<USB_STRING_DESCRIPTOR*>(new char[ser_num_size]);
OPEN_EXISTING, } catch (...) {
0, SetLastError(ERROR_OUTOFMEMORY);
NULL); return false;
if (INVALID_HANDLE_VALUE == usb_device_handle) }
return NULL; }
// Init ICTL param // Serial number string length
AdbQueryEndpointInformation param; unsigned long str_len = (ser_num->bLength -
param.endpoint_index = endpoint_index; FIELD_OFFSET(USB_STRING_DESCRIPTOR, bString)) /
sizeof(wchar_t);
// Send IOCTL
DWORD ret_bytes = 0; // Lets see if requested buffer is big enough to fit the string
BOOL ret = DeviceIoControl(usb_device_handle, if ((NULL == buffer) || (*buffer_char_size < (str_len + 1))) {
ADB_IOCTL_GET_ENDPOINT_INFORMATION, // Requested buffer is too small.
&param, sizeof(param), if (ser_num != &initial_ser_num)
info, sizeof(AdbEndpointInformation), delete[] reinterpret_cast<char*>(ser_num);
&ret_bytes, *buffer_char_size = str_len + 1;
NULL); SetLastError(ERROR_INSUFFICIENT_BUFFER);
ATLASSERT(!ret || (sizeof(AdbEndpointInformation) == ret_bytes)); return false;
}
// Preserve error accross CloseHandle
ULONG error = ret ? NO_ERROR : GetLastError(); bool ret = true;
if (ansi) {
::CloseHandle(usb_device_handle); // We need to convert name from wide char to ansi string
if (0 != WideCharToMultiByte(CP_ACP, 0, ser_num->bString,
if (NO_ERROR != error) static_cast<int>(str_len),
SetLastError(error); reinterpret_cast<PSTR>(buffer),
static_cast<int>(*buffer_char_size),
return ret ? true : false; NULL, NULL)) {
} // Zero-terminate output string.
reinterpret_cast<char*>(buffer)[str_len] = '\0';
ADBAPIHANDLE AdbInterfaceObject::OpenEndpoint( } else {
UCHAR endpoint_index, ret = false;
AdbOpenAccessType access_type, }
AdbOpenSharingMode sharing_mode) { } else {
// Convert index into name // For wide char output just copy string buffer,
std::wstring endpoint_name; // and zero-terminate output string.
CopyMemory(buffer, ser_num->bString, bytes_written);
try { reinterpret_cast<wchar_t*>(buffer)[str_len] = L'\0';
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) { if (ser_num != &initial_ser_num)
endpoint_name = DEVICE_BULK_WRITE_PIPE_NAME; delete[] reinterpret_cast<char*>(ser_num);
} else {
wchar_t fmt[265]; return ret;
swprintf(fmt, L"%ws%u", DEVICE_PIPE_NAME_PREFIX, endpoint_index); }
endpoint_name = fmt;
} bool AdbInterfaceObject::GetUsbDeviceDescriptor(USB_DEVICE_DESCRIPTOR* desc) {
} catch (...) { if (!IsOpened()) {
SetLastError(ERROR_OUTOFMEMORY); SetLastError(ERROR_INVALID_HANDLE);
return NULL; return false;
} }
return OpenEndpoint(endpoint_name.c_str(), access_type, sharing_mode); if (NULL == desc) {
} SetLastError(ERROR_INVALID_PARAMETER);
return false;
ADBAPIHANDLE AdbInterfaceObject::OpenEndpoint( }
const wchar_t* endpoint_name,
AdbOpenAccessType access_type, CopyMemory(desc, usb_device_descriptor(), sizeof(USB_DEVICE_DESCRIPTOR));
AdbOpenSharingMode sharing_mode) {
if (!IsOpened()) { return true;
SetLastError(ERROR_INVALID_HANDLE); }
return false;
} bool AdbInterfaceObject::GetUsbConfigurationDescriptor(
USB_CONFIGURATION_DESCRIPTOR* desc) {
AdbEndpointObject* adb_endpoint = NULL; if (!IsOpened()) {
SetLastError(ERROR_INVALID_HANDLE);
try { return false;
adb_endpoint = new AdbEndpointObject(this); }
} catch (...) {
SetLastError(ERROR_OUTOFMEMORY); if (NULL == desc) {
return NULL; SetLastError(ERROR_INVALID_PARAMETER);
} return false;
}
// Build full path to the object
std::wstring endpoint_path = interface_name(); CopyMemory(desc, usb_config_descriptor(),
endpoint_path += L"\\"; sizeof(USB_CONFIGURATION_DESCRIPTOR));
endpoint_path += endpoint_name;
return true;
ADBAPIHANDLE ret = adb_endpoint->CreateHandle(endpoint_path.c_str(), }
access_type,
sharing_mode); bool AdbInterfaceObject::GetUsbInterfaceDescriptor(
USB_INTERFACE_DESCRIPTOR* desc) {
adb_endpoint->Release(); if (!IsOpened()) {
SetLastError(ERROR_INVALID_HANDLE);
return ret; return false;
} }
bool AdbInterfaceObject::CacheUsbDeviceDescriptor(HANDLE usb_device_handle) { if (NULL == desc) {
DWORD ret_bytes = 0; SetLastError(ERROR_INVALID_PARAMETER);
BOOL ret = DeviceIoControl(usb_device_handle, return false;
ADB_IOCTL_GET_USB_DEVICE_DESCRIPTOR, }
NULL, 0,
&usb_device_descriptor_, CopyMemory(desc, usb_interface_descriptor(), sizeof(USB_INTERFACE_DESCRIPTOR));
sizeof(usb_device_descriptor_),
&ret_bytes, return true;
NULL); }
ATLASSERT(!ret || (sizeof(USB_DEVICE_DESCRIPTOR) == ret_bytes));
bool AdbInterfaceObject::GetEndpointInformation(UCHAR endpoint_index,
return ret ? true : false; AdbEndpointInformation* info) {
} if (!IsOpened()) {
SetLastError(ERROR_INVALID_HANDLE);
bool AdbInterfaceObject::CacheUsbConfigurationDescriptor( return false;
HANDLE usb_device_handle) { }
DWORD ret_bytes = 0;
BOOL ret = DeviceIoControl(usb_device_handle, if (NULL == info) {
ADB_IOCTL_GET_USB_CONFIGURATION_DESCRIPTOR, SetLastError(ERROR_INVALID_PARAMETER);
NULL, 0, return false;
&usb_config_descriptor_, }
sizeof(usb_config_descriptor_),
&ret_bytes, // Get actual endpoint index for predefined read / write endpoints.
NULL); if (ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index) {
ATLASSERT(!ret || (sizeof(USB_CONFIGURATION_DESCRIPTOR) == ret_bytes)); endpoint_index = def_read_endpoint_;
} else if (ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX == endpoint_index) {
return ret ? true : false; endpoint_index = def_write_endpoint_;
} }
bool AdbInterfaceObject::CacheUsbInterfaceDescriptor( // Query endpoint information
HANDLE usb_device_handle) { WINUSB_PIPE_INFORMATION pipe_info;
DWORD ret_bytes = 0; if (!WinUsb_QueryPipe(winusb_handle(), interface_number(), endpoint_index,
BOOL ret = DeviceIoControl(usb_device_handle, &pipe_info)) {
ADB_IOCTL_GET_USB_INTERFACE_DESCRIPTOR, return false;
NULL, 0, }
&usb_interface_descriptor_,
sizeof(usb_interface_descriptor_), // Save endpoint information into output.
&ret_bytes, info->max_packet_size = pipe_info.MaximumPacketSize;
NULL); info->max_transfer_size = 0xFFFFFFFF;
ATLASSERT(!ret || (sizeof(USB_INTERFACE_DESCRIPTOR) == ret_bytes)); info->endpoint_address = pipe_info.PipeId;
info->polling_interval = pipe_info.Interval;
return ret ? true : false; 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;
}

View File

@@ -1,244 +1,258 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef ANDROID_USB_API_ADB_INTERFACE_H__ #ifndef ANDROID_USB_API_ADB_INTERFACE_H__
#define ANDROID_USB_API_ADB_INTERFACE_H__ #define ANDROID_USB_API_ADB_INTERFACE_H__
/** \file /** \file
This file consists of declaration of class AdbInterfaceObject that This file consists of declaration of class AdbInterfaceObject that
encapsulates an interface on our USB device. encapsulates an interface on our USB device.
*/ */
#include "adb_object_handle.h" #include "adb_object_handle.h"
/** Class AdbInterfaceObject encapsulates an interface on our USB device. /** \brief Encapsulates an interface on our USB device.
*/ */
class AdbInterfaceObject : public AdbObjectHandle { class AdbInterfaceObject : public AdbObjectHandle {
public: public:
/** \brief Constructs the object /** \brief Constructs the object.
@param interf_name[in] Name of the interface @param[in] interf_name Name of the interface
*/ */
explicit AdbInterfaceObject(const wchar_t* interf_name); explicit AdbInterfaceObject(const wchar_t* interf_name);
protected: protected:
/** \brief Destructs the object. /** \brief Destructs the object.
We hide destructor in order to prevent ourseves from accidentaly allocating We hide destructor in order to prevent ourseves from accidentaly allocating
instances on the stack. If such attemp occur, compiler will error. instances on the stack. If such attemp occur, compiler will error.
*/ */
virtual ~AdbInterfaceObject(); virtual ~AdbInterfaceObject();
public: public:
/** \brief Creates handle to this object /** \brief Creates handle to this object.
In this call a handle for this object is generated and object is added 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 to the AdbObjectHandleMap. We override this method in order to verify that
interface indeed exists and gather device, interface and pipe properties. interface indeed exists and gather device, interface and pipe properties.
If this step succeeds then and only then AdbObjectHandle::CreateHandle If this step succeeds then and only then AdbObjectHandle::CreateHandle
will be called. will be called. Note that in this method we will open a handle to the
@return A handle to this object on success or NULL on an error. USB device (saved in usb_device_handle_). The handle will be opened for
If NULL is returned GetLastError() provides extended error read and write access, and for read and write sharing mode. The handle
information. ERROR_GEN_FAILURE is set if an attempt was will be closed in CloseHandle method of this class.
made to create already opened object. @return A handle to this object on success or NULL on an error.
*/ If NULL is returned GetLastError() provides extended error
virtual ADBAPIHANDLE CreateHandle(); information. ERROR_GEN_FAILURE is set if an attempt was
made to create already opened object.
/** \brief Gets interface device name. */
virtual ADBAPIHANDLE CreateHandle();
@param buffer[out] Buffer for the name. Can be NULL in which case
buffer_char_size will contain number of characters required to fit /** \brief This method is called when handle to this object gets closed.
the name.
@param buffer_char_size[in/out] On the way in supplies size (in characters) In this call object is deleted from the AdbObjectHandleMap. We override
of the buffer. On the way out if method failed and GetLastError this method in order close device and WinUsb handles created in
reports ERROR_INSUFFICIENT_BUFFER will contain number of characters CreateHandle method of this class.
required to fit the name. @return true on success or false if object is already closed. If
@param ansi[in] If true the name will be returned as single character false is returned GetLastError() provides extended error
string. Otherwise name will be returned as wide character string. information.
@return 'true' on success, 'false' on failure. If 'false' is returned */
GetLastError() provides extended error information. virtual bool CloseHandle();
*/
bool GetInterfaceName(void* buffer, /** \brief Gets interface device name.
unsigned long* buffer_char_size,
bool ansi); @param[out] buffer Buffer for the name. Can be NULL in which case
buffer_char_size will contain number of characters required to fit
/** \brief Gets serial number for interface's device. the name.
@param[in,out] buffer_char_size On the way in supplies size (in characters)
@param buffer[out] Buffer for the serail number string. Can be NULL in of the buffer. On the way out if method failed and GetLastError
which case buffer_char_size will contain number of characters reports ERROR_INSUFFICIENT_BUFFER will contain number of characters
required for the string. required to fit the name.
@param buffer_char_size[in/out] On the way in supplies size (in characters) @param[in] ansi If true the name will be returned as single character
of the buffer. On the way out, if method failed and GetLastError string. Otherwise name will be returned as wide character string.
reports ERROR_INSUFFICIENT_BUFFER, will contain number of characters @return true on success, false on failure. If false is returned
required for the name. GetLastError() provides extended error information.
@param ansi[in] If 'true' the name will be returned as single character */
string. Otherwise name will be returned as wide character string. bool GetInterfaceName(void* buffer,
@return 'true' on success, 'false' on failure. If 'false' is returned unsigned long* buffer_char_size,
GetLastError() provides extended error information. bool ansi);
*/
bool GetSerialNumber(void* buffer, /** \brief Gets serial number for interface's device.
unsigned long* buffer_char_size,
bool ansi); @param[out] buffer Buffer for the serail number string. Can be NULL in
which case buffer_char_size will contain number of characters
/** \brief Gets device descriptor for the USB device associated with required for the string.
this interface. @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
@param desc[out] Upon successful completion will have usb device reports ERROR_INSUFFICIENT_BUFFER, will contain number of characters
descriptor. required for the name.
@return 'true' on success, 'false' on failure. If 'false' is returned @param[in] ansi If true the name will be returned as single character
GetLastError() provides extended error information. string. Otherwise name will be returned as wide character string.
*/ @return true on success, false on failure. If false is returned
bool GetUsbDeviceDescriptor(USB_DEVICE_DESCRIPTOR* desc); GetLastError() provides extended error information.
*/
/** \brief Gets descriptor for the selected USB device configuration. bool GetSerialNumber(void* buffer,
unsigned long* buffer_char_size,
@param desc[out] Upon successful completion will have usb device bool ansi);
configuration descriptor.
@return 'true' on success, 'false' on failure. If 'false' is returned /** \brief Gets device descriptor for the USB device associated with
GetLastError() provides extended error information. this interface.
*/
bool GetUsbConfigurationDescriptor(USB_CONFIGURATION_DESCRIPTOR* desc); @param[out] desc Upon successful completion will have usb device
descriptor.
/** \brief Gets descriptor for this interface. @return true on success, false on failure. If false is returned
GetLastError() provides extended error information.
@param desc[out] Upon successful completion will have interface */
descriptor. bool GetUsbDeviceDescriptor(USB_DEVICE_DESCRIPTOR* desc);
@return 'true' on success, 'false' on failure. If 'false' is returned
GetLastError() provides extended error information. /** \brief Gets descriptor for the selected USB device configuration.
*/
bool GetUsbInterfaceDescriptor(USB_INTERFACE_DESCRIPTOR* desc); @param[out] desc Upon successful completion will have usb device
configuration descriptor.
/** \brief Gets information about an endpoint on this interface. @return true on success, false on failure. If false is returned
GetLastError() provides extended error information.
@param endpoint_index[in] Zero-based endpoint index. There are two */
shortcuts for this parameter: ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX bool GetUsbConfigurationDescriptor(USB_CONFIGURATION_DESCRIPTOR* desc);
and ADB_QUERY_BULK_READ_ENDPOINT_INDEX that provide infor about
(default?) bulk write and read endpoints respectively. /** \brief Gets descriptor for this interface.
@param info[out] Upon successful completion will have endpoint information.
@return 'true' on success, 'false' on failure. If 'false' is returned @param[out] desc Upon successful completion will have interface
GetLastError() provides extended error information. descriptor.
*/ @return true on success, false on failure. If false is returned
bool GetEndpointInformation(UCHAR endpoint_index, AdbEndpointInformation* info); GetLastError() provides extended error information.
*/
/** \brief Opens an endpoint on this interface. bool GetUsbInterfaceDescriptor(USB_INTERFACE_DESCRIPTOR* desc);
@param endpoint_index[in] Zero-based endpoint index. There are two /** \brief Gets information about an endpoint on this interface.
shortcuts for this parameter: ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX
and ADB_QUERY_BULK_READ_ENDPOINT_INDEX that provide infor about @param[in] endpoint_index Zero-based endpoint index. There are two
(default?) bulk write and read endpoints respectively. shortcuts for this parameter: ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX
@param access_type[in] Desired access type. In the current implementation and ADB_QUERY_BULK_READ_ENDPOINT_INDEX that provide infor about
this parameter has no effect on the way endpoint is opened. It's (default?) bulk write and read endpoints respectively.
always read / write access. @param[out] info Upon successful completion will have endpoint information.
@param sharing_mode[in] Desired share mode. In the current implementation @return true on success, false on failure. If false is returned
this parameter has no effect on the way endpoint is opened. It's GetLastError() provides extended error information.
always shared for read / write. */
@return Handle to the opened endpoint object or NULL on failure. bool GetEndpointInformation(UCHAR endpoint_index,
If NULL is returned GetLastError() provides extended information AdbEndpointInformation* info);
about the error that occurred.
*/ /** \brief Opens an endpoint on this interface.
ADBAPIHANDLE OpenEndpoint(UCHAR endpoint_index,
AdbOpenAccessType access_type, @param[in] endpoint_index Zero-based endpoint index. There are two
AdbOpenSharingMode sharing_mode); shortcuts for this parameter: ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX
and ADB_QUERY_BULK_READ_ENDPOINT_INDEX that provide infor about
/** \brief Opens an endpoint on this interface. (default?) bulk write and read endpoints respectively.
@param[in] access_type Desired access type. In the current implementation
@param endpoint_name[in] Endpoint file name. this parameter has no effect on the way endpoint is opened. It's
@param access_type[in] Desired access type. In the current implementation always read / write access.
this parameter has no effect on the way endpoint is opened. It's @param[in] sharing_mode Desired share mode. In the current implementation
always read / write access. this parameter has no effect on the way endpoint is opened. It's
@param sharing_mode[in] Desired share mode. In the current implementation always shared for read / write.
this parameter has no effect on the way endpoint is opened. It's @return Handle to the opened endpoint object or NULL on failure.
always shared for read / write. If NULL is returned GetLastError() provides extended information
@return Handle to the opened endpoint object or NULL on failure. about the error that occurred.
If NULL is returned GetLastError() provides extended information */
about the error that occurred. ADBAPIHANDLE OpenEndpoint(UCHAR endpoint_index,
*/ AdbOpenAccessType access_type,
ADBAPIHANDLE OpenEndpoint(const wchar_t* endpoint_name, AdbOpenSharingMode sharing_mode);
AdbOpenAccessType access_type,
AdbOpenSharingMode sharing_mode); /** \brief Opens an endpoint on this interface.
private: @param[in] endpoint_id Endpoint (pipe) address on the device.
/** \brief Caches device descriptor for the USB device associated with @param[in] endpoint_index Zero-based endpoint index.
this interface. @return Handle to the opened endpoint object or NULL on failure.
If NULL is returned GetLastError() provides extended information
This method is called from CreateHandle method to cache some interface about the error that occurred.
information. */
@param usb_device_handle[in] Handle to USB device. ADBAPIHANDLE OpenEndpoint(UCHAR endpoint_id, UCHAR endpoint_index);
@return 'true' on success, 'false' on failure. If 'false' is returned
GetLastError() provides extended error information. public:
*/ /// Gets name of the USB interface (device name) for this object
bool CacheUsbDeviceDescriptor(HANDLE usb_device_handle); const std::wstring& interface_name() const {
return interface_name_;
/** \brief Caches descriptor for the selected USB device configuration. }
This method is called from CreateHandle method to cache some interface /// This is a helper for extracting object from the AdbObjectHandleMap
information. static AdbObjectType Type() {
@param usb_device_handle[in] Handle to USB device. return AdbObjectTypeInterface;
@return 'true' on success, 'false' on failure. If 'false' is returned }
GetLastError() provides extended error information.
*/ /// Gets cached usb device descriptor
bool CacheUsbConfigurationDescriptor(HANDLE usb_device_handle); const USB_DEVICE_DESCRIPTOR* usb_device_descriptor() const {
return &usb_device_descriptor_;
/** \brief Caches descriptor for this interface. }
This method is called from CreateHandle method to cache some interface /// Gets cached usb configuration descriptor
information. const USB_CONFIGURATION_DESCRIPTOR* usb_config_descriptor() const {
@param usb_device_handle[in] Handle to USB device. return &usb_config_descriptor_;
@return 'true' on success, 'false' on failure. If 'false' is returned }
GetLastError() provides extended error information.
*/ /// Gets cached usb interface descriptor
bool CacheUsbInterfaceDescriptor(HANDLE usb_device_handle); const USB_INTERFACE_DESCRIPTOR* usb_interface_descriptor() const {
return &usb_interface_descriptor_;
public: }
/// Gets name of the USB interface (device name) for this object
const std::wstring& interface_name() const { /// Gets handle to the USB device
return interface_name_; HANDLE usb_device_handle() const {
} return usb_device_handle_;
}
// This is a helper for extracting object from the AdbObjectHandleMap
static AdbObjectType Type() { /// Gets interface handle used by WinUSB API
return AdbObjectTypeInterface; WINUSB_INTERFACE_HANDLE winusb_handle() const {
} return winusb_handle_;
}
/// Gets cached usb device descriptor
const USB_DEVICE_DESCRIPTOR* usb_device_descriptor() const { /// Gets current interface number.
return &usb_device_descriptor_; UCHAR interface_number() const {
} return interface_number_;
}
/// Gets cached usb configuration descriptor
const USB_CONFIGURATION_DESCRIPTOR* usb_config_descriptor() const { private:
return &usb_config_descriptor_; /// Name of the USB interface (device name) for this object
} std::wstring interface_name_;
/// Gets cached usb interface descriptor /// Cached usb device descriptor
const USB_INTERFACE_DESCRIPTOR* usb_interface_descriptor() const { USB_DEVICE_DESCRIPTOR usb_device_descriptor_;
return &usb_interface_descriptor_;
} /// Cached usb configuration descriptor
USB_CONFIGURATION_DESCRIPTOR usb_config_descriptor_;
private:
/// Name of the USB interface (device name) for this object /// Cached usb interface descriptor
std::wstring interface_name_; USB_INTERFACE_DESCRIPTOR usb_interface_descriptor_;
/// Cached usb device descriptor /// Handle to the USB device
USB_DEVICE_DESCRIPTOR usb_device_descriptor_; HANDLE usb_device_handle_;
/// Cached usb configuration descriptor /// Interface handle used by WinUSB API
USB_CONFIGURATION_DESCRIPTOR usb_config_descriptor_; WINUSB_INTERFACE_HANDLE winusb_handle_;
/// Cached usb interface descriptor /// Current interface number. This value is obtained via call to
USB_INTERFACE_DESCRIPTOR usb_interface_descriptor_; /// WinUsb_GetCurrentAlternateSetting and is used in WinUsb_Xxx
}; /// calls that require interface number.
UCHAR interface_number_;
#endif // ANDROID_USB_API_ADB_INTERFACE_H__
/// 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__

View File

@@ -1,103 +1,103 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/** \file /** \file
This file consists of implementation of AdbInterfaceEnumObject class that This file consists of implementation of AdbInterfaceEnumObject class that
encapsulates enumerator of USB interfaces available through this API. encapsulates enumerator of USB interfaces available through this API.
*/ */
#include "stdafx.h" #include "stdafx.h"
#include "adb_api.h" #include "adb_api.h"
#include "adb_interface_enum.h" #include "adb_interface_enum.h"
#include "adb_helper_routines.h" #include "adb_helper_routines.h"
AdbInterfaceEnumObject::AdbInterfaceEnumObject() AdbInterfaceEnumObject::AdbInterfaceEnumObject()
: AdbObjectHandle(AdbObjectTypeInterfaceEnumerator) { : AdbObjectHandle(AdbObjectTypeInterfaceEnumerator) {
current_interface_ = interfaces_.begin(); current_interface_ = interfaces_.begin();
} }
AdbInterfaceEnumObject::~AdbInterfaceEnumObject() { AdbInterfaceEnumObject::~AdbInterfaceEnumObject() {
} }
bool AdbInterfaceEnumObject::InitializeEnum(GUID class_id, bool AdbInterfaceEnumObject::InitializeEnum(GUID class_id,
bool exclude_not_present, bool exclude_not_present,
bool exclude_removed, bool exclude_removed,
bool active_only) { bool active_only) {
// Calc flags for SetupDiGetClassDevs // Calc flags for SetupDiGetClassDevs
DWORD flags = DIGCF_DEVICEINTERFACE; DWORD flags = DIGCF_DEVICEINTERFACE;
if (exclude_not_present) if (exclude_not_present)
flags |= DIGCF_PRESENT; flags |= DIGCF_PRESENT;
// Do the enum // Do the enum
bool ret = EnumerateDeviceInterfaces(class_id, bool ret = EnumerateDeviceInterfaces(class_id,
flags, flags,
exclude_removed, exclude_removed,
active_only, active_only,
&interfaces_); &interfaces_);
// If enum was successfull set current enum pointer // If enum was successfull set current enum pointer
// to the beginning of the array // to the beginning of the array
if (ret) if (ret)
current_interface_ = interfaces_.begin(); current_interface_ = interfaces_.begin();
return ret; return ret;
} }
bool AdbInterfaceEnumObject::Next(AdbInterfaceInfo* info, ULONG* size) { bool AdbInterfaceEnumObject::Next(AdbInterfaceInfo* info, ULONG* size) {
// Make sure that it's opened // Make sure that it's opened
if (!IsOpened()) { if (!IsOpened()) {
SetLastError(ERROR_INVALID_HANDLE); SetLastError(ERROR_INVALID_HANDLE);
return false; return false;
} }
ATLASSERT(NULL != size); ATLASSERT(NULL != size);
if (NULL == size) { if (NULL == size) {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return false; return false;
} }
// Lets see if enum is over // Lets see if enum is over
if (interfaces_.end() == current_interface_) { if (interfaces_.end() == current_interface_) {
SetLastError(ERROR_NO_MORE_ITEMS); SetLastError(ERROR_NO_MORE_ITEMS);
return false; return false;
} }
AdbInstanceEnumEntry& entry = *current_interface_; AdbInstanceEnumEntry& entry = *current_interface_;
// Big enough? // Big enough?
if ((NULL == info) || (*size < entry.GetFlatSize())) { if ((NULL == info) || (*size < entry.GetFlatSize())) {
*size = entry.GetFlatSize(); *size = entry.GetFlatSize();
SetLastError(ERROR_INSUFFICIENT_BUFFER); SetLastError(ERROR_INSUFFICIENT_BUFFER);
return false; return false;
} }
// All checks passed // All checks passed
entry.Save(info); entry.Save(info);
current_interface_++; current_interface_++;
return true; return true;
} }
bool AdbInterfaceEnumObject::Reset() { bool AdbInterfaceEnumObject::Reset() {
// Make sure that it's opened // Make sure that it's opened
if (!IsOpened()) { if (!IsOpened()) {
SetLastError(ERROR_INVALID_HANDLE); SetLastError(ERROR_INVALID_HANDLE);
return false; return false;
} }
current_interface_ = interfaces_.begin(); current_interface_ = interfaces_.begin();
return true; return true;
} }

View File

@@ -1,101 +1,98 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef ANDROID_USB_API_ADB_INTERFACE_ENUM_H__ #ifndef ANDROID_USB_API_ADB_INTERFACE_ENUM_H__
#define ANDROID_USB_API_ADB_INTERFACE_ENUM_H__ #define ANDROID_USB_API_ADB_INTERFACE_ENUM_H__
/** \file /** \file
This file consists of declaration of AdbInterfaceEnumObject class that This file consists of declaration of AdbInterfaceEnumObject class that
encapsulates enumerator of USB interfaces available through this API. encapsulates enumerator of USB interfaces available through this API.
*/ */
#include "adb_object_handle.h" #include "adb_object_handle.h"
/** Class AdbInterfaceEnumObject encapsulates enumerator of USB /** \brief Enumerator of USB interfaces available through this API.
interfaces available through this API. */
*/ class AdbInterfaceEnumObject : public AdbObjectHandle {
class AdbInterfaceEnumObject : public AdbObjectHandle { public:
public: /** \brief Constructs the object.
/** \brief Constructs the object. */
*/ AdbInterfaceEnumObject();
AdbInterfaceEnumObject();
protected:
protected: /** \brief Destructs the object.
/** \brief Destructs the object.
We hide destructor in order to prevent ourseves from accidentaly allocating
We hide destructor in order to prevent ourseves from accidentaly allocating instances on the stack. If such attemp occur, compiler will error.
instances on the stack. If such attemp occur, compiler will error. */
*/ virtual ~AdbInterfaceEnumObject();
virtual ~AdbInterfaceEnumObject();
public:
public: /** \brief Enumerates all interfaces for the given device class.
/** \brief Enumerates all interfaces for our device class
This routine uses SetupDiGetClassDevs to get our device info and calls
This routine uses SetupDiGetClassDevs to get our device info and calls EnumerateDeviceInterfaces to perform the enumeration.
EnumerateDeviceInterfaces to perform the enumeration. @param[in] class_id Device class ID that is specified by our USB driver
@param class_id[in] Device class ID that is specified by our USB driver @param[in] exclude_not_present If set include only those devices that are
@param exclude_not_present[in] If set include only those devices that are currently present.
currently present. @param[in] exclude_removed If true interfaces with SPINT_REMOVED flag set
@param exclude_removed[in] If true interfaces with SPINT_REMOVED flag set will be not included in the enumeration.
will be not included in the enumeration. @param[in] active_only If true only active interfaces (with flag
@param active_only[in] If 'true' only active interfaces (with flag SPINT_ACTIVE set) will be included in the enumeration.
SPINT_ACTIVE set) will be included in the enumeration. @return True on success, false on failure, in which case GetLastError()
@return True on success, false on failure, in which case GetLastError() provides extended information about the error that occurred.
provides extended information about the error that occurred. */
*/ bool InitializeEnum(GUID class_id,
bool InitializeEnum(GUID class_id, bool exclude_not_present,
bool exclude_not_present, bool exclude_removed,
bool exclude_removed, bool active_only);
bool active_only);
/** \brief Gets next enumerated interface information
/** \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
@param info[out] Upon successful completion will receive interface method *size will have memory size required to fit this entry.
information. Can be NULL. If it is NULL, upon return from this @param[in,out] size On the way in provides size of the memory buffer
method *size will have memory size required to fit this entry. addressed by info param. On the way out (only if buffer is not
@param size[in,out]. On the way in provides size of the memory buffer big enough) will provide memory size required to fit this entry.
addressed by info param. On the way out (only if buffer is not @return true on success, false on error. If false is returned
big enough) will provide memory size required to fit this entry. GetLastError() provides extended information about the error that
@return true on success, false on error. If false is returned occurred. ERROR_INSUFFICIENT_BUFFER indicates that buffer provided
GetLastError() provides extended information about the error that in info param was not big enough and *size specifies memory size
occurred. ERROR_INSUFFICIENT_BUFFER indicates that buffer provided required to fit this entry. ERROR_NO_MORE_ITEMS indicates that
in info param was not big enough and *size specifies memory size enumeration is over and there are no more entries to return.
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);
*/
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
/** \brief Makes enumerator to start from the beginning. GetLastError() provides extended information about the error that
occurred.
@return true on success, false on error. If false is returned */
GetLastError() provides extended information about the error that bool Reset();
occurred.
*/ // This is a helper for extracting object from the AdbObjectHandleMap
bool Reset(); static AdbObjectType Type() {
return AdbObjectTypeInterfaceEnumerator;
// 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_;
protected:
/// Array of interfaces enumerated with this object /// Current enumerator
AdbEnumInterfaceArray interfaces_; AdbEnumInterfaceArray::iterator current_interface_;
};
/// Current enumerator
AdbEnumInterfaceArray::iterator current_interface_; #endif // ANDROID_USB_API_ADB_INTERFACE_ENUM_H__
};
#endif // ANDROID_USB_API_ADB_INTERFACE_ENUM_H__

View File

@@ -1,103 +1,98 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/** \file /** \file
This file consists of implementation of class AdbIOCompletion that This file consists of implementation of class AdbIOCompletion that
encapsulates a wrapper around OVERLAPPED Win32 structure returned encapsulates a wrapper around OVERLAPPED Win32 structure returned
from asynchronous I/O requests. from asynchronous I/O requests.
*/ */
#include "stdafx.h" #include "stdafx.h"
#include "adb_io_completion.h" #include "adb_io_completion.h"
AdbIOCompletion::AdbIOCompletion(AdbIOObject* parent_io_obj, AdbIOCompletion::AdbIOCompletion(AdbEndpointObject* parent_io_obj,
bool is_write_ctl, ULONG expected_trans_size,
ULONG expected_trans_size, HANDLE event_hndl)
HANDLE event_hndl) : AdbObjectHandle(AdbObjectTypeIoCompletion),
: AdbObjectHandle(AdbObjectTypeIoCompletion), expected_transfer_size_(expected_trans_size),
transferred_bytes_(0), parent_io_object_(parent_io_obj) {
expected_transfer_size_(expected_trans_size), ATLASSERT(NULL != parent_io_obj);
is_write_ioctl_(is_write_ctl), parent_io_obj->AddRef();
parent_io_object_(parent_io_obj) { ZeroMemory(&overlapped_, sizeof(overlapped_));
ATLASSERT(NULL != parent_io_obj); overlapped_.hEvent = event_hndl;
parent_io_obj->AddRef(); }
ZeroMemory(&overlapped_, sizeof(overlapped_));
overlapped_.hEvent = event_hndl; AdbIOCompletion::~AdbIOCompletion() {
} parent_io_object_->Release();
}
AdbIOCompletion::~AdbIOCompletion() {
parent_io_object_->Release(); bool AdbIOCompletion::GetOvelappedIoResult(LPOVERLAPPED ovl_data,
} ULONG* bytes_transferred,
bool wait) {
bool AdbIOCompletion::GetOvelappedIoResult(LPOVERLAPPED ovl_data, if (NULL != bytes_transferred)
ULONG* bytes_transferred, *bytes_transferred = 0;
bool wait) {
if (NULL != bytes_transferred) if (!IsOpened()) {
*bytes_transferred = 0; SetLastError(ERROR_INVALID_HANDLE);
return false;
if (!IsOpened()) { }
SetLastError(ERROR_INVALID_HANDLE);
return false; ULONG transfer;
} bool ret = WinUsb_GetOverlappedResult(parent_io_object()->winusb_handle(),
overlapped(),
ULONG transfer; &transfer,
bool ret = GetOverlappedResult(parent_io_object()->usb_handle(), wait ? TRUE : FALSE) ? true : false;
overlapped(),
&transfer, // TODO: This is bizzare but I've seen it happening
wait) ? true : // that GetOverlappedResult with wait set to true returns "prematurely",
false; // with wrong transferred bytes value and GetLastError reporting
// ERROR_IO_PENDING. So, lets give it an up to a 20 ms loop!
// TODO: This is bizzare but I've seen it happening ULONG error = GetLastError();
// that GetOverlappedResult with wait set to true returns "prematurely",
// with wrong transferred bytes value and GetLastError reporting if (wait && ret && (0 == transfer) && (0 != expected_transfer_size_) &&
// ERROR_IO_PENDING. So, lets give it an up to a 20 ms loop! ((ERROR_IO_INCOMPLETE == error) || (ERROR_IO_PENDING == error))) {
ULONG error = GetLastError(); for (int trying = 0; trying < 10; trying++) {
Sleep(2);
if (wait && ret && (0 == transfer) && (0 != expected_transfer_size_) && ret = WinUsb_GetOverlappedResult(parent_io_object()->winusb_handle(),
((ERROR_IO_INCOMPLETE == error) || (ERROR_IO_PENDING == error))) { overlapped(),
for (int trying = 0; trying < 10; trying++) { &transfer,
Sleep(2); wait ? TRUE : FALSE) ? true : false;
ret = GetOverlappedResult(parent_io_object()->usb_handle(), error = GetLastError();
overlapped(), if (!ret || (0 != transfer) ||
&transfer, ((ERROR_IO_INCOMPLETE != error) && (ERROR_IO_PENDING != error))) {
wait) ? true : break;
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;
if (NULL != ovl_data)
CopyMemory(ovl_data, overlapped(), sizeof(OVERLAPPED)); return ret;
}
if (NULL != bytes_transferred)
*bytes_transferred = is_write_ioctl() ? transferred_bytes_ : transfer; bool AdbIOCompletion::IsCompleted() {
SetLastError(NO_ERROR);
return ret; if (!IsOpened()) {
} SetLastError(ERROR_INVALID_HANDLE);
return true;
bool AdbIOCompletion::IsCompleted() { }
SetLastError(NO_ERROR);
if (!IsOpened()) { return HasOverlappedIoCompleted(overlapped()) ? true : false;
SetLastError(ERROR_INVALID_HANDLE); }
return true;
}
return HasOverlappedIoCompleted(overlapped()) ? true : false;
}

View File

@@ -1,140 +1,122 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef ANDROID_USB_API_ADB_IO_COMPLETION_H__ #ifndef ANDROID_USB_API_ADB_IO_COMPLETION_H__
#define ANDROID_USB_API_ADB_IO_COMPLETION_H__ #define ANDROID_USB_API_ADB_IO_COMPLETION_H__
/** \file /** \file
This file consists of declaration of class AdbIOCompletion that encapsulates This file consists of declaration of class AdbIOCompletion that encapsulates
a wrapper around OVERLAPPED Win32 structure returned from asynchronous I/O a wrapper around OVERLAPPED Win32 structure returned from asynchronous I/O
requests. requests.
*/ */
#include "adb_io_object.h" #include "adb_endpoint_object.h"
/** Class AdbIOCompletion encapsulates encapsulates a wrapper around /** \brief Encapsulates encapsulates a wrapper around OVERLAPPED Win32
OVERLAPPED Win32 structure returned from asynchronous I/O requests. 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 A handle to this object is returned to the caller of each successful
must be closed after it's no longer needed. 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: class AdbIOCompletion : public AdbObjectHandle {
/** \brief Constructs the object 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 @param[in] parent_io_obj Parent I/O object that created this instance.
released in the destructor. Parent object will be referenced in this object's constructor and
@param is_write_ctl[in] Flag indicating whether or not this completion released in the destructor.
object is created for ADB_IOCTL_BULK_WRITE I/O. @param[in] expected_trans_size Number of bytes expected to be transferred
@param event_hndl[in] Event handle that should be signaled when I/O with the I/O.
completes. Can be NULL. If it's not NULL this handle will be @param[in] event_hndl Event handle that should be signaled when I/O
used to initialize OVERLAPPED structure for this object. 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, AdbIOCompletion(AdbEndpointObject* parent_io_obj,
ULONG expected_trans_size, ULONG expected_trans_size,
HANDLE event_hndl); HANDLE event_hndl);
protected: protected:
/** \brief Destructs the object. /** \brief Destructs the object.
parent_io_object_ will be dereferenced here. We hide destructor in order to prevent ourseves from accidentaly allocating
We hide destructor in order to prevent ourseves from accidentaly allocating instances on the stack. If such attemp occur, compiler will error.
instances on the stack. If such attemp occur, compiler will error. */
*/ virtual ~AdbIOCompletion();
virtual ~AdbIOCompletion();
public:
public: /** \brief Gets overlapped I/O result
/** \brief Gets overlapped I/O result
@param[out] ovl_data Buffer for the copy of this object's OVERLAPPED
@param ovl_data[out] Buffer for the copy of this object's OVERLAPPED structure. Can be NULL.
structure. Can be NULL. @param[out] bytes_transferred Pointer to a variable that receives the
@param bytes_transferred[out] Pointer to a variable that receives the number of bytes that were actually transferred by a read or write
number of bytes that were actually transferred by a read or write operation. See SDK doc on GetOvelappedResult for more information.
operation. See SDK doc on GetOvelappedResult for more information. Unlike regular GetOvelappedResult call this parameter can be NULL.
Unlike regular GetOvelappedResult call this parameter can be NULL. @param[in] wait If this parameter is true, the method does not return
@param wait[in] If this parameter is 'true', the method does not return until the operation has been completed. If this parameter is false
until the operation has been completed. If this parameter is 'false' and the operation is still pending, the method returns false and
and the operation is still pending, the method returns 'false' and the GetLastError function returns ERROR_IO_INCOMPLETE.
the GetLastError function returns ERROR_IO_INCOMPLETE. @return true if I/O has been completed or false on failure or if request
@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
is not yet completed. If 'false' is returned GetLastError() provides extended error information. If GetLastError returns
extended error information. If GetLastError returns ERROR_IO_INCOMPLETE it means that I/O is not yet completed.
ERROR_IO_INCOMPLETE it means that I/O is not yet completed. */
*/ virtual bool GetOvelappedIoResult(LPOVERLAPPED ovl_data,
virtual bool GetOvelappedIoResult(LPOVERLAPPED ovl_data, ULONG* bytes_transferred,
ULONG* bytes_transferred, bool wait);
bool wait);
/** \brief Checks if I/O that this object represents has completed.
/** \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
@return 'true' if I/O has been completed or 'false' if it's still incomplete. Regardless of the returned value, caller should
incomplete. Regardless of the returned value, caller should check GetLastError to validate that handle was OK.
check GetLastError to validate that handle was OK. */
*/ virtual bool IsCompleted();
virtual bool IsCompleted();
public:
public: /// Gets overlapped structure for this I/O
/// Gets overlapped structure for this I/O LPOVERLAPPED overlapped() {
LPOVERLAPPED overlapped() { return &overlapped_;
return &overlapped_; }
}
/// Gets parent object
/// Gets parent object AdbEndpointObject* parent_io_object() const {
AdbIOObject* parent_io_object() const { return parent_io_object_;
return parent_io_object_; }
}
/// Gets parent object handle
/// Gets parent object handle ADBAPIHANDLE GetParentObjectHandle() const {
ADBAPIHANDLE GetParentObjectHandle() const { return (NULL != parent_io_object()) ? parent_io_object()->adb_handle() :
return (NULL != parent_io_object()) ? parent_io_object()->adb_handle() : NULL;
NULL; }
}
// This is a helper for extracting object from the AdbObjectHandleMap
/// Gets address for ADB_IOCTL_BULK_WRITE output buffer static AdbObjectType Type() {
ULONG* transferred_bytes_ptr() { return AdbObjectTypeIoCompletion;
ATLASSERT(is_write_ioctl()); }
return &transferred_bytes_;
} protected:
/// Overlapped structure for this I/O
/// Gets write IOCTL flag OVERLAPPED overlapped_;
bool is_write_ioctl() const {
return is_write_ioctl_; /// Parent I/O object
} AdbEndpointObject* parent_io_object_;
// This is a helper for extracting object from the AdbObjectHandleMap /// Expected number of bytes transferred in thi I/O
static AdbObjectType Type() { ULONG expected_transfer_size_;
return AdbObjectTypeIoCompletion; };
}
#endif // ANDROID_USB_API_ADB_IO_COMPLETION_H__
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__

View File

@@ -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;
}

View File

@@ -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__

View File

@@ -1,167 +1,167 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/** \file /** \file
This file consists of implementation of a class AdbObjectHandle that This file consists of implementation of a class AdbObjectHandle that
encapsulates an internal API object that is visible to the outside encapsulates an internal API object that is visible to the outside
of the API through a handle. of the API through a handle.
*/ */
#include "stdafx.h" #include "stdafx.h"
#include "adb_api.h" #include "adb_api.h"
#include "adb_object_handle.h" #include "adb_object_handle.h"
/// Global ADBAPIHANDLE -> AdbObjectHandle* map /// Global ADBAPIHANDLE -> AdbObjectHandle* map
AdbObjectHandleMap the_map; AdbObjectHandleMap the_map;
/// Locker for the AdbObjectHandleMap instance /// Locker for the AdbObjectHandleMap instance
CComAutoCriticalSection the_map_locker; CComAutoCriticalSection the_map_locker;
/// Next adb handle value generator /// Next adb handle value generator
ULONG_PTR next_adb_handle_value = 0; ULONG_PTR next_adb_handle_value = 0;
AdbObjectHandle::AdbObjectHandle(AdbObjectType obj_type) AdbObjectHandle::AdbObjectHandle(AdbObjectType obj_type)
: adb_handle_(NULL), : adb_handle_(NULL),
object_type_(obj_type), object_type_(obj_type),
ref_count_(1) { ref_count_(1) {
ATLASSERT(obj_type < AdbObjectTypeMax); ATLASSERT(obj_type < AdbObjectTypeMax);
} }
AdbObjectHandle::~AdbObjectHandle() { AdbObjectHandle::~AdbObjectHandle() {
ATLASSERT(0 == ref_count_); ATLASSERT(0 == ref_count_);
ATLASSERT(NULL == adb_handle_); ATLASSERT(NULL == adb_handle_);
} }
LONG AdbObjectHandle::AddRef() { LONG AdbObjectHandle::AddRef() {
ATLASSERT(ref_count_ > 0); ATLASSERT(ref_count_ > 0);
return InterlockedIncrement(&ref_count_); return InterlockedIncrement(&ref_count_);
} }
LONG AdbObjectHandle::Release() { LONG AdbObjectHandle::Release() {
ATLASSERT(ref_count_ > 0); ATLASSERT(ref_count_ > 0);
LONG ret = InterlockedDecrement(&ref_count_); LONG ret = InterlockedDecrement(&ref_count_);
ATLASSERT(ret >= 0); ATLASSERT(ret >= 0);
if (0 == ret) { if (0 == ret) {
LastReferenceReleased(); LastReferenceReleased();
delete this; delete this;
} }
return ret; return ret;
} }
ADBAPIHANDLE AdbObjectHandle::CreateHandle() { ADBAPIHANDLE AdbObjectHandle::CreateHandle() {
ADBAPIHANDLE ret = NULL; ADBAPIHANDLE ret = NULL;
// We have to hold this lock while we're dealing with the handle // We have to hold this lock while we're dealing with the handle
// and the table // and the table
the_map_locker.Lock(); the_map_locker.Lock();
ATLASSERT(!IsOpened()); ATLASSERT(!IsOpened());
if (!IsOpened()) { if (!IsOpened()) {
try { try {
// Generate next handle value // Generate next handle value
next_adb_handle_value++; next_adb_handle_value++;
ret = reinterpret_cast<ADBAPIHANDLE>(next_adb_handle_value); ret = reinterpret_cast<ADBAPIHANDLE>(next_adb_handle_value);
// Add ourselves to the map // Add ourselves to the map
the_map[ret] = this; the_map[ret] = this;
// Save handle, addref and return // Save handle, addref and return
adb_handle_ = ret; adb_handle_ = ret;
AddRef(); AddRef();
} catch (...) { } catch (...) {
ret = NULL; ret = NULL;
SetLastError(ERROR_OUTOFMEMORY); SetLastError(ERROR_OUTOFMEMORY);
} }
} else { } else {
// Signaling that this object is already opened // Signaling that this object is already opened
SetLastError(ERROR_GEN_FAILURE); SetLastError(ERROR_GEN_FAILURE);
} }
the_map_locker.Unlock(); the_map_locker.Unlock();
return ret; return ret;
} }
bool AdbObjectHandle::CloseHandle() { bool AdbObjectHandle::CloseHandle() {
bool ret = false; bool ret = false;
// Addref just in case that last reference to this object is being // Addref just in case that last reference to this object is being
// held in the map // held in the map
AddRef(); AddRef();
the_map_locker.Lock(); the_map_locker.Lock();
ATLASSERT(IsOpened()); ATLASSERT(IsOpened());
if (IsOpened()) { if (IsOpened()) {
try { try {
// Look us up in the map. // Look us up in the map.
AdbObjectHandleMap::iterator found = the_map.find(adb_handle()); AdbObjectHandleMap::iterator found = the_map.find(adb_handle());
ATLASSERT((found != the_map.end()) && (this == found->second)); ATLASSERT((found != the_map.end()) && (this == found->second));
if ((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 // Remove ourselves from the map, close and release the object
the_map.erase(found); the_map.erase(found);
adb_handle_ = NULL; adb_handle_ = NULL;
Release(); Release();
ret = true; ret = true;
} else { } else {
SetLastError(ERROR_INVALID_HANDLE); SetLastError(ERROR_INVALID_HANDLE);
} }
} catch (...) { } catch (...) {
ret = false; ret = false;
SetLastError(ERROR_OUTOFMEMORY); SetLastError(ERROR_OUTOFMEMORY);
} }
} else { } else {
SetLastError(ERROR_INVALID_HANDLE); SetLastError(ERROR_INVALID_HANDLE);
} }
the_map_locker.Unlock(); the_map_locker.Unlock();
Release(); Release();
return ret; return ret;
} }
bool AdbObjectHandle::IsObjectOfType(AdbObjectType obj_type) const { bool AdbObjectHandle::IsObjectOfType(AdbObjectType obj_type) const {
return (obj_type == object_type()); return (obj_type == object_type());
} }
void AdbObjectHandle::LastReferenceReleased() { void AdbObjectHandle::LastReferenceReleased() {
ATLASSERT(!IsOpened()); ATLASSERT(!IsOpened());
} }
AdbObjectHandle* AdbObjectHandle::Lookup(ADBAPIHANDLE adb_hndl) { AdbObjectHandle* AdbObjectHandle::Lookup(ADBAPIHANDLE adb_hndl) {
AdbObjectHandle* ret = NULL; AdbObjectHandle* ret = NULL;
the_map_locker.Lock(); the_map_locker.Lock();
try { try {
// Look us up in the map. // Look us up in the map.
AdbObjectHandleMap::iterator found = the_map.find(adb_hndl); AdbObjectHandleMap::iterator found = the_map.find(adb_hndl);
if (found != the_map.end()) { if (found != the_map.end()) {
ret = found->second; ret = found->second;
ret->AddRef(); ret->AddRef();
} }
} catch (...) { } catch (...) {
SetLastError(ERROR_OUTOFMEMORY); SetLastError(ERROR_OUTOFMEMORY);
} }
the_map_locker.Unlock(); the_map_locker.Unlock();
return ret; return ret;
} }

View File

@@ -1,213 +1,211 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef ANDROID_USB_API_ADB_OBJECT_HANDLE_H__ #ifndef ANDROID_USB_API_ADB_OBJECT_HANDLE_H__
#define ANDROID_USB_API_ADB_OBJECT_HANDLE_H__ #define ANDROID_USB_API_ADB_OBJECT_HANDLE_H__
/** \file /** \file
This file consists of declaration of a class AdbObjectHandle that This file consists of declaration of a class AdbObjectHandle that
encapsulates an internal API object that is visible to the outside encapsulates an internal API object that is visible to the outside
of the API through a handle. of the API through a handle.
*/ */
#include "adb_api_private_defines.h" #include "adb_api_private_defines.h"
/** AdbObjectType enum defines types of internal API objects /** \brief Defines types of internal API objects
*/ */
enum AdbObjectType { enum AdbObjectType {
/// Object is AdbInterfaceEnumObject /// Object is AdbInterfaceEnumObject.
AdbObjectTypeInterfaceEnumerator, AdbObjectTypeInterfaceEnumerator,
/// Object is AdbInterfaceObject /// Object is AdbInterfaceObject.
AdbObjectTypeInterface, AdbObjectTypeInterface,
/// Object is derived from AdbIOObject /// Object is AdbEndpointObject.
AdbObjectTypeIo, AdbObjectTypeEndpoint,
/// Object is AdbEndpointObject /// Object is AdbIOCompletion.
AdbObjectTypeEndpoint, AdbObjectTypeIoCompletion,
/// Object is AdbIOCompletion AdbObjectTypeMax
AdbObjectTypeIoCompletion, };
AdbObjectTypeMax /** \brief Encapsulates an internal API basic object that is visible to the
}; outside of the API through a handle.
/** Class AdbObjectHandle encapsulates an internal API basic object that is In order to prevent crashes when API client tries to access an object through
visible to the outside of the API through a handle. In order to prevent an invalid or already closed handle, we keep track of all opened handles in
crashes when API client tries to access an object through an invalid or AdbObjectHandleMap that maps association between valid ADBAPIHANDLE and
already closed handle, we keep track of all opened handles in an object that this handle represents. All objects that are exposed to the
AdbObjectHandleMap that maps association between valid ADBAPIHANDLE and outside of API via ADBAPIHANDLE are self-destructing referenced objects.
an object that this handle represents. All objects that are exposed to the The reference model for these objects is as such:
outside of API via ADBAPIHANDLE are self-destructing referenced objects. 1. When CreateHandle() method is called on an object, a handle (ADBAPIHANDLE
The reference model for these objects is as such: that is) is assigned to it, a pair <handle, object> is added to the global
1. When CreateHandle() method is called on an object, a handle (ADBAPIHANDLE AdbObjectHandleMap instance, object is referenced and then handle is
that is) is assigned to it, a pair <handle, object> is added to the global returned to the API client.
AdbObjectHandleMap instance, object is referenced and then handle is 2. Every time API is called with a handle, a lookup is performed in
returned to the API client. AdbObjectHandleMap to find an object that is associated with the handle.
2. Every time API is called with a handle, a lookup is performed in If object is not found then ERROR_INVALID_HANDLE is immediatelly returned
AdbObjectHandleMap to find an object that is associated with the handle. (via SetLastError() call). If object is found then it is referenced and
If object is not found then ERROR_INVALID_HANDLE is immediatelly returned API call is dispatched to appropriate method of the found object. Upon
(via SetLastError() call). If object is found then it is referenced and return from this method, just before returning from the API call, object
API call is dispatched to appropriate method of the found object. Upon is dereferenced back to match lookup reference.
return from this method, just before returning from the API call, object 3. When object handle gets closed, assuming object is found in the map, that
is dereferenced back to match lookup reference. <handle, object> pair is deleted from the map and object's refcount is
3. When object handle gets closed, assuming object is found in the map, that decremented to match refcount increment performed when object has been
<handle, object> pair is deleted from the map and object's refcount is added to the map.
decremented to match refcount increment performed when object has been 4. When object's refcount drops to zero, the object commits suicide by
added to the map. calling "delete this".
4. When object's refcount drops to zero, the object commits suicide by All API objects that have handles that are sent back to API client must be
calling "delete this". derived from this class.
All API objects that have handles that are sent back to API client must be */
derived from this class. class AdbObjectHandle {
*/ public:
class AdbObjectHandle { /** \brief Constructs the object
public:
/** \brief Constructs the object Refernce counter is set to 1 in the constructor.
@param[in] obj_type Object type from AdbObjectType enum
Refernce counter is set to 1 in the constructor. */
@param obj_type[in] Object type from AdbObjectType enum explicit AdbObjectHandle(AdbObjectType obj_type);
*/
explicit AdbObjectHandle(AdbObjectType obj_type); protected:
/** \brief Destructs the object.
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.
We hide destructor in order to prevent ourseves from accidentaly allocating */
instances on the stack. If such attempt occurs, compiler will error. virtual ~AdbObjectHandle();
*/
virtual ~AdbObjectHandle(); public:
/** \brief References the object.
public:
/** \brief References the object @return Value of the reference counter after object is referenced in this
method.
@return Value of the reference counter after object is referenced in this */
method. virtual LONG AddRef();
*/
virtual LONG AddRef(); /** \brief Releases the object.
/** \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
If refcount drops to zero as the result of this release, the object is after this method returns even if returned value is not zero.
destroyed in this method. As a general rule, objects must not be touched @return Value of the reference counter after object is released in this
after this method returns even if returned value is not zero. method.
@return Value of the reference counter after object is released in this */
method. virtual LONG Release();
*/
virtual LONG Release(); /** \brief Creates handle to this object.
/** \brief Creates handle to this object In this call a handle for this object is generated and object is added
to the AdbObjectHandleMap.
In this call a handle for this object is generated and object is added @return A handle to this object on success or NULL on an error.
to the AdbObjectHandleMap. If NULL is returned GetLastError() provides extended error
@return A handle to this object on success or NULL on an error. information. ERROR_GEN_FAILURE is set if an attempt was
If NULL is returned GetLastError() provides extended error made to create already opened object.
information. ERROR_GEN_FAILURE is set if an attempt was */
made to create already opened object. virtual ADBAPIHANDLE CreateHandle();
*/
virtual ADBAPIHANDLE CreateHandle(); /** \brief This method is called when handle to this object gets closed.
/** \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
In this call object is deleted from the AdbObjectHandleMap. false is returned GetLastError() provides extended error
@return 'true' on success or 'false' if object is already closed. If information.
'false' is returned GetLastError() provides extended error */
information. virtual bool CloseHandle();
*/
virtual bool CloseHandle(); /** \brief Checks if this object is of the given type.
/** \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.
@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;
*/
virtual bool IsObjectOfType(AdbObjectType obj_type) const; /** \brief Looks up AdbObjectHandle instance associated with the given handle
in the AdbObjectHandleMap.
/** \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
This method increments reference counter for the returned found object. @return API object associated with the handle or NULL if object is not
@param adb_handle[in] ADB handle to the object found. If NULL is returned GetLastError() provides extended error
@return API object associated with the handle or NULL if object is not information.
found. If NULL is returned GetLastError() provides extended error */
information. static AdbObjectHandle* Lookup(ADBAPIHANDLE adb_handle);
*/
static AdbObjectHandle* Lookup(ADBAPIHANDLE adb_handle); protected:
/** \brief Called when last reference to this object is released.
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.
Derived object should override this method to perform cleanup that is not */
suitable for destructors. virtual void LastReferenceReleased();
*/
virtual void LastReferenceReleased(); public:
/// Gets ADB handle associated with this object
public: ADBAPIHANDLE adb_handle() const {
/// Gets ADB handle associated with this object return adb_handle_;
ADBAPIHANDLE adb_handle() const { }
return adb_handle_;
} /// Gets type of this object
AdbObjectType object_type() const {
/// Gets type of this object return object_type_;
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.
/// Checks if object is still opened. Note that it is not guaranteed that bool IsOpened() const {
/// object remains opened when this method returns. return (NULL != adb_handle());
bool IsOpened() const { }
return (NULL != adb_handle());
} protected:
/// API handle associated with this object
protected: ADBAPIHANDLE adb_handle_;
/// API handle associated with this object
ADBAPIHANDLE adb_handle_; /// Type of this object
AdbObjectType object_type_;
/// Type of this object
AdbObjectType object_type_; /// This object's reference counter
LONG ref_count_;
/// This object's reference counter };
LONG ref_count_;
}; /// Maps ADBAPIHANDLE to associated AdbObjectHandle object
typedef std::map< ADBAPIHANDLE, AdbObjectHandle* > AdbObjectHandleMap;
/// 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
/** \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
@param adb_handle[in] API handle for the object returned GetLastError() provides extended error information.
@return Object associated with the handle or NULL on error. If NULL is */
returned GetLastError() provides extended error information. template<class obj_class>
*/ obj_class* LookupObject(ADBAPIHANDLE adb_handle) {
template<class obj_class> // Lookup object for the handle in the map
obj_class* LookupObject(ADBAPIHANDLE adb_handle) { AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle);
// Lookup object for the handle in the map if (NULL != adb_object) {
AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle); // Make sure it's of the correct type
if (NULL != adb_object) { if (!adb_object->IsObjectOfType(obj_class::Type())) {
// Make sure it's of the correct type adb_object->Release();
if (!adb_object->IsObjectOfType(obj_class::Type())) { adb_object = NULL;
adb_object->Release(); SetLastError(ERROR_INVALID_HANDLE);
adb_object = NULL; }
SetLastError(ERROR_INVALID_HANDLE); } else {
} SetLastError(ERROR_INVALID_HANDLE);
} else { }
SetLastError(ERROR_INVALID_HANDLE); return (adb_object != NULL) ? reinterpret_cast<obj_class*>(adb_object) :
} NULL;
return (adb_object != NULL) ? reinterpret_cast<obj_class*>(adb_object) : }
NULL;
} #endif // ANDROID_USB_API_ADB_OBJECT_HANDLE_H__
#endif // ANDROID_USB_API_ADB_OBJECT_HANDLE_H__

View File

@@ -1,21 +1,21 @@
/* /*
* Copyright (C) 2008 The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
// stdafx.cpp : source file that includes just the standard includes // stdafx.cpp : source file that includes just the standard includes
// AdbWinApi.pch will be the pre-compiled header // AdbWinApi.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information // stdafx.obj will contain the pre-compiled type information
#include "stdafx.h" #include "stdafx.h"

View File

@@ -1,71 +1,82 @@
/* /*
* Copyright (C) 2006 The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/** \file /** \file
Visual Studio generated include file for standard system include files, or Visual Studio generated include file for standard system include files, or
project specific include files that are used frequently, but are changed project specific include files that are used frequently, but are changed
infrequently. infrequently.
*/ */
#pragma once #pragma once
#ifndef STRICT #ifndef STRICT
#define STRICT #define STRICT
#endif #endif
// Modify the following defines if you have to target a platform prior to the ones specified below. // 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. // 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. #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. #define WINVER 0x0500 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif #endif
#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. #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. #define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target Windows 2000 or later.
#endif #endif
#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. #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. #define _WIN32_WINDOWS 0x0500 // Change this to the appropriate value to target Windows Me or later.
#endif #endif
#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. #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. #define _WIN32_IE 0x0501 // Change this to the appropriate value to target IE 5.0 or later.
#endif #endif
#define _ATL_APARTMENT_THREADED // These defines prevent the MS header files from ejecting #pragma comment
#define _ATL_NO_AUTOMATIC_NAMESPACE // statements with the manifest information of the used ATL, STL, and CRT
#define _ATL_NOFORCE_MANIFEST
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit #define _STL_NOFORCE_MANIFEST
#define _CRT_NOFORCE_MANIFEST
// turns off ATL's hiding of some common and often safely ignored warning messages
#define _ATL_ALL_WARNINGS #define _ATL_APARTMENT_THREADED
#define _ATL_NO_AUTOMATIC_NAMESPACE
#pragma warning(disable: 4702)
#include "resource.h" #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
#include <atlbase.h>
#include <atlcom.h> // turns off ATL's hiding of some common and often safely ignored warning messages
#include <winioctl.h> #define _ATL_ALL_WARNINGS
#include <setupapi.h>
#include <vector> // #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <map>
#include <string> #include <windows.h>
#pragma warning(disable: 4200) #pragma warning(disable: 4702)
extern "C" { #pragma warning(disable: 4201)
#include <usbdi.h> #include <atlbase.h>
} #include <winioctl.h>
#include <setupapi.h>
#include "android_usb_common_defines.h" #include <vector>
#include <map>
using namespace ATL; #include <string>
#pragma warning(default: 4201)
#pragma warning(disable: 4200)
extern "C" {
#include <usbdi.h>
#include <winusb.h>
#include <usb100.h>
}
#include "resource.h"
using namespace ATL;