/* * 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(adb_handle); if (NULL == adb_ienum_object) return false; // Everything is verified. Pass it down to the object bool ret = adb_ienum_object->Next(info, size); adb_ienum_object->Release(); return ret; } bool __cdecl AdbResetInterfaceEnum(ADBAPIHANDLE adb_handle) { // Lookup AdbInterfaceEnumObject object for the handle AdbInterfaceEnumObject* adb_ienum_object = LookupObject(adb_handle); if (NULL == adb_ienum_object) return false; // Everything is verified. Pass it down to the object bool ret = adb_ienum_object->Reset(); adb_ienum_object->Release(); return ret; } ADBAPIHANDLE __cdecl AdbCreateInterfaceByName( const wchar_t* interface_name) { AdbInterfaceObject* obj = NULL; ADBAPIHANDLE ret = NULL; try { // Instantiate 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(adb_interface); if (NULL != adb_object) { // Dispatch call to the found object bool ret = adb_object->GetInterfaceName(buffer, buffer_char_size, ansi); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return false; } } bool __cdecl AdbGetSerialNumber(ADBAPIHANDLE adb_interface, void* buffer, unsigned long* buffer_char_size, bool ansi) { // Lookup interface object for the handle AdbInterfaceObject* adb_object = LookupObject(adb_interface); if (NULL != adb_object) { // Dispatch call to the found object bool ret = adb_object->GetSerialNumber(buffer, buffer_char_size, ansi); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return false; } } bool __cdecl AdbGetUsbDeviceDescriptor(ADBAPIHANDLE adb_interface, USB_DEVICE_DESCRIPTOR* desc) { // Lookup interface object for the handle AdbInterfaceObject* adb_object = LookupObject(adb_interface); if (NULL != adb_object) { // Dispatch close to the found object bool ret = adb_object->GetUsbDeviceDescriptor(desc); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return false; } } bool __cdecl AdbGetUsbConfigurationDescriptor(ADBAPIHANDLE adb_interface, USB_CONFIGURATION_DESCRIPTOR* desc) { // Lookup interface object for the handle AdbInterfaceObject* adb_object = LookupObject(adb_interface); if (NULL != adb_object) { // Dispatch close to the found object bool ret = adb_object->GetUsbConfigurationDescriptor(desc); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return false; } } bool __cdecl AdbGetUsbInterfaceDescriptor(ADBAPIHANDLE adb_interface, USB_INTERFACE_DESCRIPTOR* desc) { // Lookup interface object for the handle AdbInterfaceObject* adb_object = LookupObject(adb_interface); if (NULL != adb_object) { // Dispatch close to the found object bool ret = adb_object->GetUsbInterfaceDescriptor(desc); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return false; } } bool __cdecl AdbGetEndpointInformation(ADBAPIHANDLE adb_interface, UCHAR endpoint_index, AdbEndpointInformation* info) { // Lookup interface object for the handle AdbInterfaceObject* adb_object = LookupObject(adb_interface); if (NULL != adb_object) { // Dispatch close to the found object bool ret = adb_object->GetEndpointInformation(endpoint_index, info); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return false; } } bool __cdecl AdbGetDefaultBulkReadEndpointInformation(ADBAPIHANDLE adb_interface, AdbEndpointInformation* info) { return AdbGetEndpointInformation(adb_interface, ADB_QUERY_BULK_READ_ENDPOINT_INDEX, info); } bool __cdecl AdbGetDefaultBulkWriteEndpointInformation(ADBAPIHANDLE adb_interface, AdbEndpointInformation* info) { return AdbGetEndpointInformation(adb_interface, ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX, info); } ADBAPIHANDLE __cdecl AdbOpenEndpoint(ADBAPIHANDLE adb_interface, unsigned char endpoint_index, AdbOpenAccessType access_type, AdbOpenSharingMode sharing_mode) { // Lookup interface object for the handle AdbInterfaceObject* adb_object = LookupObject(adb_interface); if (NULL != adb_object) { // Dispatch close to the found object ADBAPIHANDLE ret = adb_object->OpenEndpoint(endpoint_index, access_type, sharing_mode); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return NULL; } } ADBAPIHANDLE __cdecl AdbOpenDefaultBulkReadEndpoint(ADBAPIHANDLE adb_interface, AdbOpenAccessType access_type, AdbOpenSharingMode sharing_mode) { return AdbOpenEndpoint(adb_interface, ADB_QUERY_BULK_READ_ENDPOINT_INDEX, access_type, sharing_mode); } ADBAPIHANDLE __cdecl AdbOpenDefaultBulkWriteEndpoint(ADBAPIHANDLE adb_interface, AdbOpenAccessType access_type, AdbOpenSharingMode sharing_mode) { return AdbOpenEndpoint(adb_interface, ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX, access_type, sharing_mode); } ADBAPIHANDLE __cdecl AdbGetEndpointInterface(ADBAPIHANDLE adb_endpoint) { // Lookup endpoint object for the handle AdbEndpointObject* adb_object = LookupObject(adb_endpoint); if (NULL != adb_object) { // Dispatch the call to the found object ADBAPIHANDLE ret = adb_object->GetParentInterfaceHandle(); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return NULL; } } bool __cdecl AdbQueryInformationEndpoint(ADBAPIHANDLE adb_endpoint, AdbEndpointInformation* info) { // Lookup endpoint object for the handle AdbEndpointObject* adb_object = LookupObject(adb_endpoint); if (NULL != adb_object) { // Dispatch the call to the found object bool ret = adb_object->GetEndpointInformation(info); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return false; } } ADBAPIHANDLE __cdecl AdbReadEndpointAsync(ADBAPIHANDLE adb_endpoint, void* buffer, unsigned long bytes_to_read, unsigned long* bytes_read, unsigned long time_out, HANDLE event_handle) { // Lookup endpoint object for the handle AdbEndpointObject* adb_object = LookupObject(adb_endpoint); if (NULL != adb_object) { // Dispatch the call to the found object ADBAPIHANDLE ret = adb_object->AsyncRead(buffer, bytes_to_read, bytes_read, event_handle, time_out); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return NULL; } } ADBAPIHANDLE __cdecl AdbWriteEndpointAsync(ADBAPIHANDLE adb_endpoint, void* buffer, unsigned long bytes_to_write, unsigned long* bytes_written, unsigned long time_out, HANDLE event_handle) { // Lookup endpoint object for the handle AdbEndpointObject* adb_object = LookupObject(adb_endpoint); if (NULL != adb_object) { // Dispatch the call to the found object ADBAPIHANDLE ret = adb_object->AsyncWrite(buffer, bytes_to_write, bytes_written, event_handle, time_out); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return false; } } bool __cdecl AdbReadEndpointSync(ADBAPIHANDLE adb_endpoint, void* buffer, unsigned long bytes_to_read, unsigned long* bytes_read, unsigned long time_out) { // Lookup endpoint object for the handle AdbEndpointObject* adb_object = LookupObject(adb_endpoint); if (NULL != adb_object) { // Dispatch the call to the found object bool ret = adb_object->SyncRead(buffer, bytes_to_read, bytes_read, time_out); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return NULL; } } bool __cdecl AdbWriteEndpointSync(ADBAPIHANDLE adb_endpoint, void* buffer, unsigned long bytes_to_write, unsigned long* bytes_written, unsigned long time_out) { // Lookup endpoint object for the handle AdbEndpointObject* adb_object = LookupObject(adb_endpoint); if (NULL != adb_object) { // Dispatch the call to the found object bool ret = adb_object->SyncWrite(buffer, bytes_to_write, bytes_written, time_out); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return false; } } bool __cdecl AdbGetOvelappedIoResult(ADBAPIHANDLE adb_io_completion, LPOVERLAPPED overlapped, unsigned long* bytes_transferred, bool wait) { // Lookup endpoint object for the handle AdbIOCompletion* adb_object = LookupObject(adb_io_completion); if (NULL != adb_object) { // Dispatch the call to the found object bool ret = adb_object->GetOvelappedIoResult(overlapped, bytes_transferred, wait); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return false; } } bool __cdecl AdbHasOvelappedIoComplated(ADBAPIHANDLE adb_io_completion) { // Lookup endpoint object for the handle AdbIOCompletion* adb_object = LookupObject(adb_io_completion); if (NULL != adb_object) { // Dispatch the call to the found object bool ret = adb_object->IsCompleted(); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return true; } } bool __cdecl AdbCloseHandle(ADBAPIHANDLE adb_handle) { // Lookup object for the handle AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle); if (NULL != adb_object) { // Dispatch close to the found object bool ret = adb_object->CloseHandle(); adb_object->Release(); return ret; } else { SetLastError(ERROR_INVALID_HANDLE); return false; } }