/*
* 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"
#include "adb_winusb_api.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;
}
}