/* | |
* Copyright (C) 2006 The Android Open Source Project | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
/** \file | |
This file consists of implementation of rotines that are exported | |
from this DLL. | |
*/ | |
#include "stdafx.h" | |
#include "adb_api.h" | |
#include "adb_object_handle.h" | |
#include "adb_interface_enum.h" | |
#include "adb_interface.h" | |
#include "adb_legacy_interface.h" | |
#include "adb_endpoint_object.h" | |
#include "adb_io_completion.h" | |
#include "adb_helper_routines.h" | |
/** \brief Points to InstantiateWinUsbInterface exported from AdbWinUsbApi.dll. | |
This variable is initialized with the actual address in DllMain routine for | |
this DLL on DLL_PROCESS_ATTACH event. | |
@see PFN_INSTWINUSBINTERFACE for more information. | |
*/ | |
PFN_INSTWINUSBINTERFACE InstantiateWinUsbInterface = NULL; | |
ADBAPIHANDLE __cdecl AdbEnumInterfaces(GUID class_id, | |
bool exclude_not_present, | |
bool exclude_removed, | |
bool active_only) { | |
AdbInterfaceEnumObject* enum_obj = NULL; | |
ADBAPIHANDLE ret = NULL; | |
try { | |
// Instantiate and initialize enum object | |
enum_obj = new AdbInterfaceEnumObject(); | |
if (enum_obj->InitializeEnum(class_id, | |
exclude_not_present, | |
exclude_removed, | |
active_only)) { | |
// After successful initialization we can create handle. | |
ret = enum_obj->CreateHandle(); | |
} | |
} catch (...) { | |
SetLastError(ERROR_OUTOFMEMORY); | |
} | |
if (NULL != enum_obj) | |
enum_obj->Release(); | |
return ret; | |
} | |
bool __cdecl AdbNextInterface(ADBAPIHANDLE adb_handle, | |
AdbInterfaceInfo* info, | |
unsigned long* size) { | |
if (NULL == size) { | |
SetLastError(ERROR_INVALID_PARAMETER); | |
return false; | |
} | |
// Lookup AdbInterfaceEnumObject object for the handle | |
AdbInterfaceEnumObject* adb_ienum_object = | |
LookupObject<AdbInterfaceEnumObject>(adb_handle); | |
if (NULL == adb_ienum_object) | |
return false; | |
// Everything is verified. Pass it down to the object | |
bool ret = adb_ienum_object->Next(info, size); | |
adb_ienum_object->Release(); | |
return ret; | |
} | |
bool __cdecl AdbResetInterfaceEnum(ADBAPIHANDLE adb_handle) { | |
// Lookup AdbInterfaceEnumObject object for the handle | |
AdbInterfaceEnumObject* adb_ienum_object = | |
LookupObject<AdbInterfaceEnumObject>(adb_handle); | |
if (NULL == adb_ienum_object) | |
return false; | |
// Everything is verified. Pass it down to the object | |
bool ret = adb_ienum_object->Reset(); | |
adb_ienum_object->Release(); | |
return ret; | |
} | |
ADBAPIHANDLE __cdecl AdbCreateInterfaceByName( | |
const wchar_t* interface_name) { | |
AdbInterfaceObject* obj = NULL; | |
ADBAPIHANDLE ret = NULL; | |
try { | |
// Instantiate interface object, depending on the USB driver type. | |
if (IsLegacyInterface(interface_name)) { | |
// We have legacy USB driver underneath us. | |
obj = new AdbLegacyInterfaceObject(interface_name); | |
} else { | |
// We have WinUsb driver underneath us. Make sure that AdbWinUsbApi.dll | |
// is loaded and its InstantiateWinUsbInterface routine address has | |
// been cached. | |
if (NULL != InstantiateWinUsbInterface) { | |
obj = InstantiateWinUsbInterface(interface_name); | |
if (NULL == obj) { | |
return NULL; | |
} | |
} else { | |
return NULL; | |
} | |
} | |
// Create handle for it | |
ret = obj->CreateHandle(); | |
} catch (...) { | |
SetLastError(ERROR_OUTOFMEMORY); | |
} | |
if (NULL != obj) | |
obj->Release(); | |
return ret; | |
} | |
ADBAPIHANDLE __cdecl AdbCreateInterface(GUID class_id, | |
unsigned short vendor_id, | |
unsigned short product_id, | |
unsigned char interface_id) { | |
// Enumerate all active interfaces for the given class | |
AdbEnumInterfaceArray interfaces; | |
if (!EnumerateDeviceInterfaces(class_id, | |
DIGCF_DEVICEINTERFACE | DIGCF_PRESENT, | |
true, | |
true, | |
&interfaces)) { | |
return NULL; | |
} | |
if (interfaces.empty()) { | |
SetLastError(ERROR_DEVICE_NOT_AVAILABLE); | |
return NULL; | |
} | |
// Now iterate over active interfaces looking for the name match. | |
// The name is formatted as such: | |
// "\\\\?\\usb#vid_xxxx&pid_xxxx&mi_xx#123456789abcdef#{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" | |
// where | |
// vid_xxxx is for the vendor id (xxxx are hex for the given vendor id), | |
// pid_xxxx is for the product id (xxxx are hex for the given product id) | |
// mi_xx is for the interface id (xx are hex for the given interface id) | |
// EnumerateDeviceInterfaces will guarantee that returned interface names | |
// will have our class id at the end of the name (those last XXXes in the | |
// format). So, we only need to match the beginning of the name | |
wchar_t match_name[64]; | |
if (0xFF == interface_id) { | |
// No interface id for the name. | |
swprintf(match_name, L"\\\\?\\usb#vid_%04x&pid_%04x#", | |
vendor_id, product_id); | |
} else { | |
// With interface id for the name. | |
swprintf(match_name, L"\\\\?\\usb#vid_%04x&pid_%04x&mi_%02x#", | |
vendor_id, product_id, interface_id); | |
} | |
size_t match_len = wcslen(match_name); | |
for (AdbEnumInterfaceArray::iterator it = interfaces.begin(); | |
it != interfaces.end(); it++) { | |
const AdbInstanceEnumEntry& next_interface = *it; | |
if (0 == _wcsnicmp(match_name, | |
next_interface.device_name().c_str(), | |
match_len)) { | |
// Found requested interface among active interfaces. | |
return AdbCreateInterfaceByName(next_interface.device_name().c_str()); | |
} | |
} | |
SetLastError(ERROR_DEVICE_NOT_AVAILABLE); | |
return NULL; | |
} | |
bool __cdecl AdbGetInterfaceName(ADBAPIHANDLE adb_interface, | |
void* buffer, | |
unsigned long* buffer_char_size, | |
bool ansi) { | |
// Lookup interface object for the handle | |
AdbInterfaceObject* adb_object = | |
LookupObject<AdbInterfaceObject>(adb_interface); | |
if (NULL != adb_object) { | |
// Dispatch call to the found object | |
bool ret = adb_object->GetInterfaceName(buffer, buffer_char_size, ansi); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return false; | |
} | |
} | |
bool __cdecl AdbGetSerialNumber(ADBAPIHANDLE adb_interface, | |
void* buffer, | |
unsigned long* buffer_char_size, | |
bool ansi) { | |
// Lookup interface object for the handle | |
AdbInterfaceObject* adb_object = | |
LookupObject<AdbInterfaceObject>(adb_interface); | |
if (NULL != adb_object) { | |
// Dispatch call to the found object | |
bool ret = adb_object->GetSerialNumber(buffer, buffer_char_size, ansi); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return false; | |
} | |
} | |
bool __cdecl AdbGetUsbDeviceDescriptor(ADBAPIHANDLE adb_interface, | |
USB_DEVICE_DESCRIPTOR* desc) { | |
// Lookup interface object for the handle | |
AdbInterfaceObject* adb_object = | |
LookupObject<AdbInterfaceObject>(adb_interface); | |
if (NULL != adb_object) { | |
// Dispatch close to the found object | |
bool ret = adb_object->GetUsbDeviceDescriptor(desc); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return false; | |
} | |
} | |
bool __cdecl AdbGetUsbConfigurationDescriptor(ADBAPIHANDLE adb_interface, | |
USB_CONFIGURATION_DESCRIPTOR* desc) { | |
// Lookup interface object for the handle | |
AdbInterfaceObject* adb_object = | |
LookupObject<AdbInterfaceObject>(adb_interface); | |
if (NULL != adb_object) { | |
// Dispatch close to the found object | |
bool ret = adb_object->GetUsbConfigurationDescriptor(desc); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return false; | |
} | |
} | |
bool __cdecl AdbGetUsbInterfaceDescriptor(ADBAPIHANDLE adb_interface, | |
USB_INTERFACE_DESCRIPTOR* desc) { | |
// Lookup interface object for the handle | |
AdbInterfaceObject* adb_object = | |
LookupObject<AdbInterfaceObject>(adb_interface); | |
if (NULL != adb_object) { | |
// Dispatch close to the found object | |
bool ret = adb_object->GetUsbInterfaceDescriptor(desc); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return false; | |
} | |
} | |
bool __cdecl AdbGetEndpointInformation(ADBAPIHANDLE adb_interface, | |
UCHAR endpoint_index, | |
AdbEndpointInformation* info) { | |
// Lookup interface object for the handle | |
AdbInterfaceObject* adb_object = | |
LookupObject<AdbInterfaceObject>(adb_interface); | |
if (NULL != adb_object) { | |
// Dispatch close to the found object | |
bool ret = adb_object->GetEndpointInformation(endpoint_index, info); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return false; | |
} | |
} | |
bool __cdecl AdbGetDefaultBulkReadEndpointInformation(ADBAPIHANDLE adb_interface, | |
AdbEndpointInformation* info) { | |
return AdbGetEndpointInformation(adb_interface, | |
ADB_QUERY_BULK_READ_ENDPOINT_INDEX, | |
info); | |
} | |
bool __cdecl AdbGetDefaultBulkWriteEndpointInformation(ADBAPIHANDLE adb_interface, | |
AdbEndpointInformation* info) { | |
return AdbGetEndpointInformation(adb_interface, | |
ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX, | |
info); | |
} | |
ADBAPIHANDLE __cdecl AdbOpenEndpoint(ADBAPIHANDLE adb_interface, | |
unsigned char endpoint_index, | |
AdbOpenAccessType access_type, | |
AdbOpenSharingMode sharing_mode) { | |
// Lookup interface object for the handle | |
AdbInterfaceObject* adb_object = | |
LookupObject<AdbInterfaceObject>(adb_interface); | |
if (NULL != adb_object) { | |
// Dispatch close to the found object | |
ADBAPIHANDLE ret = | |
adb_object->OpenEndpoint(endpoint_index, access_type, sharing_mode); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return NULL; | |
} | |
} | |
ADBAPIHANDLE __cdecl AdbOpenDefaultBulkReadEndpoint(ADBAPIHANDLE adb_interface, | |
AdbOpenAccessType access_type, | |
AdbOpenSharingMode sharing_mode) { | |
return AdbOpenEndpoint(adb_interface, | |
ADB_QUERY_BULK_READ_ENDPOINT_INDEX, | |
access_type, | |
sharing_mode); | |
} | |
ADBAPIHANDLE __cdecl AdbOpenDefaultBulkWriteEndpoint(ADBAPIHANDLE adb_interface, | |
AdbOpenAccessType access_type, | |
AdbOpenSharingMode sharing_mode) { | |
return AdbOpenEndpoint(adb_interface, | |
ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX, | |
access_type, | |
sharing_mode); | |
} | |
ADBAPIHANDLE __cdecl AdbGetEndpointInterface(ADBAPIHANDLE adb_endpoint) { | |
// Lookup endpoint object for the handle | |
AdbEndpointObject* adb_object = | |
LookupObject<AdbEndpointObject>(adb_endpoint); | |
if (NULL != adb_object) { | |
// Dispatch the call to the found object | |
ADBAPIHANDLE ret = adb_object->GetParentInterfaceHandle(); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return NULL; | |
} | |
} | |
bool __cdecl AdbQueryInformationEndpoint(ADBAPIHANDLE adb_endpoint, | |
AdbEndpointInformation* info) { | |
// Lookup endpoint object for the handle | |
AdbEndpointObject* adb_object = | |
LookupObject<AdbEndpointObject>(adb_endpoint); | |
if (NULL != adb_object) { | |
// Dispatch the call to the found object | |
bool ret = adb_object->GetEndpointInformation(info); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return false; | |
} | |
} | |
ADBAPIHANDLE __cdecl AdbReadEndpointAsync(ADBAPIHANDLE adb_endpoint, | |
void* buffer, | |
unsigned long bytes_to_read, | |
unsigned long* bytes_read, | |
unsigned long time_out, | |
HANDLE event_handle) { | |
// Lookup endpoint object for the handle | |
AdbEndpointObject* adb_object = | |
LookupObject<AdbEndpointObject>(adb_endpoint); | |
if (NULL != adb_object) { | |
// Dispatch the call to the found object | |
ADBAPIHANDLE ret = adb_object->AsyncRead(buffer, | |
bytes_to_read, | |
bytes_read, | |
event_handle, | |
time_out); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return NULL; | |
} | |
} | |
ADBAPIHANDLE __cdecl AdbWriteEndpointAsync(ADBAPIHANDLE adb_endpoint, | |
void* buffer, | |
unsigned long bytes_to_write, | |
unsigned long* bytes_written, | |
unsigned long time_out, | |
HANDLE event_handle) { | |
// Lookup endpoint object for the handle | |
AdbEndpointObject* adb_object = | |
LookupObject<AdbEndpointObject>(adb_endpoint); | |
if (NULL != adb_object) { | |
// Dispatch the call to the found object | |
ADBAPIHANDLE ret = adb_object->AsyncWrite(buffer, | |
bytes_to_write, | |
bytes_written, | |
event_handle, | |
time_out); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return false; | |
} | |
} | |
bool __cdecl AdbReadEndpointSync(ADBAPIHANDLE adb_endpoint, | |
void* buffer, | |
unsigned long bytes_to_read, | |
unsigned long* bytes_read, | |
unsigned long time_out) { | |
// Lookup endpoint object for the handle | |
AdbEndpointObject* adb_object = | |
LookupObject<AdbEndpointObject>(adb_endpoint); | |
if (NULL != adb_object) { | |
// Dispatch the call to the found object | |
bool ret = | |
adb_object->SyncRead(buffer, bytes_to_read, bytes_read, time_out); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return NULL; | |
} | |
} | |
bool __cdecl AdbWriteEndpointSync(ADBAPIHANDLE adb_endpoint, | |
void* buffer, | |
unsigned long bytes_to_write, | |
unsigned long* bytes_written, | |
unsigned long time_out) { | |
// Lookup endpoint object for the handle | |
AdbEndpointObject* adb_object = | |
LookupObject<AdbEndpointObject>(adb_endpoint); | |
if (NULL != adb_object) { | |
// Dispatch the call to the found object | |
bool ret = | |
adb_object->SyncWrite(buffer, bytes_to_write, bytes_written, time_out); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return false; | |
} | |
} | |
bool __cdecl AdbGetOvelappedIoResult(ADBAPIHANDLE adb_io_completion, | |
LPOVERLAPPED overlapped, | |
unsigned long* bytes_transferred, | |
bool wait) { | |
// Lookup endpoint object for the handle | |
AdbIOCompletion* adb_object = | |
LookupObject<AdbIOCompletion>(adb_io_completion); | |
if (NULL != adb_object) { | |
// Dispatch the call to the found object | |
bool ret = | |
adb_object->GetOvelappedIoResult(overlapped, bytes_transferred, wait); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return false; | |
} | |
} | |
bool __cdecl AdbHasOvelappedIoComplated(ADBAPIHANDLE adb_io_completion) { | |
// Lookup endpoint object for the handle | |
AdbIOCompletion* adb_object = | |
LookupObject<AdbIOCompletion>(adb_io_completion); | |
if (NULL != adb_object) { | |
// Dispatch the call to the found object | |
bool ret = | |
adb_object->IsCompleted(); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return true; | |
} | |
} | |
bool __cdecl AdbCloseHandle(ADBAPIHANDLE adb_handle) { | |
// Lookup object for the handle | |
AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle); | |
if (NULL != adb_object) { | |
// Dispatch close to the found object | |
bool ret = adb_object->CloseHandle(); | |
adb_object->Release(); | |
return ret; | |
} else { | |
SetLastError(ERROR_INVALID_HANDLE); | |
return false; | |
} | |
} |