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