adb_helper_routines.cpp revision 5c11852110eeb03dc5a69111354b383f98d15336
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/** \file 18 This file consists of implementation of helper routines used 19 in the API. 20*/ 21 22#include "stdafx.h" 23#include "adb_api.h" 24#include "adb_helper_routines.h" 25#include "adb_interface_enum.h" 26 27bool GetSDKComplientParam(AdbOpenAccessType access_type, 28 AdbOpenSharingMode sharing_mode, 29 ULONG* desired_access, 30 ULONG* desired_sharing) { 31 if (NULL != desired_access) { 32 switch (access_type) { 33 case AdbOpenAccessTypeReadWrite: 34 *desired_access = GENERIC_READ | GENERIC_WRITE; 35 break; 36 37 case AdbOpenAccessTypeRead: 38 *desired_access = GENERIC_READ; 39 break; 40 41 case AdbOpenAccessTypeWrite: 42 *desired_access = GENERIC_WRITE; 43 break; 44 45 case AdbOpenAccessTypeQueryInfo: 46 *desired_access = FILE_READ_ATTRIBUTES | FILE_READ_EA; 47 break; 48 49 default: 50 AtlTrace("\n!!!!! ADB API -> GetSDKComplientParam %u is unknown access type", 51 access_type); 52 SetLastError(ERROR_INVALID_ACCESS); 53 return false; 54 } 55 } 56 57 if (NULL != desired_sharing) { 58 switch (sharing_mode) { 59 case AdbOpenSharingModeReadWrite: 60 *desired_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; 61 break; 62 63 case AdbOpenSharingModeRead: 64 *desired_sharing = FILE_SHARE_READ; 65 break; 66 67 case AdbOpenSharingModeWrite: 68 *desired_sharing = FILE_SHARE_WRITE; 69 break; 70 71 case AdbOpenSharingModeExclusive: 72 *desired_sharing = 0; 73 break; 74 75 default: 76 AtlTrace("\n!!!!! ADB API -> GetSDKComplientParam %u is unknown share mode", 77 sharing_mode); 78 SetLastError(ERROR_INVALID_PARAMETER); 79 return false; 80 } 81 } 82 83 return true; 84} 85 86bool EnumerateDeviceInterfaces(HDEVINFO hardware_dev_info, 87 GUID class_id, 88 bool exclude_removed, 89 bool active_only, 90 AdbEnumInterfaceArray* interfaces) { 91 AdbEnumInterfaceArray tmp; 92 bool ret = false; 93 94 // Enumerate interfaces on this device 95 for (ULONG index = 0; ; index++) { 96 SP_DEVICE_INTERFACE_DATA interface_data; 97 interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); 98 99 // SetupDiEnumDeviceInterfaces() returns information about device 100 // interfaces exposed by one or more devices defined by our interface 101 // class. Each call returns information about one interface. The routine 102 // can be called repeatedly to get information about several interfaces 103 // exposed by one or more devices. 104 if (SetupDiEnumDeviceInterfaces(hardware_dev_info, 105 0, 106 &class_id, 107 index, 108 &interface_data)) { 109 // Satisfy "exclude removed" and "active only" filters. 110 if ((!exclude_removed || (0 == (interface_data.Flags & SPINT_REMOVED))) && 111 (!active_only || (interface_data.Flags & SPINT_ACTIVE))) { 112 std::wstring dev_name; 113 114 if (GetUsbDeviceName(hardware_dev_info, &interface_data, &dev_name)) { 115 try { 116 // Add new entry to the array 117 tmp.push_back(AdbInstanceEnumEntry(dev_name.c_str(), 118 interface_data.InterfaceClassGuid, 119 interface_data.Flags)); 120 } catch (... ) { 121 SetLastError(ERROR_OUTOFMEMORY); 122 break; 123 } 124 } else { 125 // Something went wrong in getting device name 126 break; 127 } 128 } 129 } else { 130 if (ERROR_NO_MORE_ITEMS == GetLastError()) { 131 // There are no more items in the list. Enum is completed. 132 ret = true; 133 break; 134 } else { 135 // Something went wrong in SDK enum 136 break; 137 } 138 } 139 } 140 141 // On success, swap temp array with the returning one 142 if (ret) 143 interfaces->swap(tmp); 144 145 return ret; 146} 147 148bool EnumerateDeviceInterfaces(GUID class_id, 149 ULONG flags, 150 bool exclude_removed, 151 bool active_only, 152 AdbEnumInterfaceArray* interfaces) { 153 // Open a handle to the plug and play dev node. 154 // SetupDiGetClassDevs() returns a device information set that 155 // contains info on all installed devices of a specified class. 156 HDEVINFO hardware_dev_info = 157 SetupDiGetClassDevs(&class_id, NULL, NULL, flags); 158 159 bool ret = false; 160 161 if (INVALID_HANDLE_VALUE != hardware_dev_info) { 162 // Do the enum 163 ret = EnumerateDeviceInterfaces(hardware_dev_info, 164 class_id, 165 exclude_removed, 166 active_only, 167 interfaces); 168 169 // Preserve last error accross hardware_dev_info destruction 170 ULONG error_to_report = ret ? NO_ERROR : GetLastError(); 171 172 SetupDiDestroyDeviceInfoList(hardware_dev_info); 173 174 if (NO_ERROR != error_to_report) 175 SetLastError(error_to_report); 176 } 177 178 return ret; 179} 180 181bool GetUsbDeviceDetails( 182 HDEVINFO hardware_dev_info, 183 PSP_DEVICE_INTERFACE_DATA dev_info_data, 184 PSP_DEVICE_INTERFACE_DETAIL_DATA* dev_info_detail_data) { 185 ULONG required_len = 0; 186 187 // First query for the structure size. At this point we expect this call 188 // to fail with ERROR_INSUFFICIENT_BUFFER error code. 189 if (SetupDiGetDeviceInterfaceDetail(hardware_dev_info, 190 dev_info_data, 191 NULL, 192 0, 193 &required_len, 194 NULL)) { 195 return false; 196 } 197 198 if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) 199 return false; 200 201 // Allocate buffer for the structure 202 PSP_DEVICE_INTERFACE_DETAIL_DATA buffer = 203 reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(malloc(required_len)); 204 205 if (NULL == buffer) { 206 SetLastError(ERROR_OUTOFMEMORY); 207 return false; 208 } 209 210 buffer->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); 211 212 // Retrieve the information from Plug and Play. 213 if (SetupDiGetDeviceInterfaceDetail(hardware_dev_info, 214 dev_info_data, 215 buffer, 216 required_len, 217 &required_len, 218 NULL)) { 219 *dev_info_detail_data = buffer; 220 return true; 221 } else { 222 // Free the buffer if this call failed 223 free(buffer); 224 225 return false; 226 } 227} 228 229bool GetUsbDeviceName(HDEVINFO hardware_dev_info, 230 PSP_DEVICE_INTERFACE_DATA dev_info_data, 231 std::wstring* name) { 232 PSP_DEVICE_INTERFACE_DETAIL_DATA func_class_dev_data = NULL; 233 if (!GetUsbDeviceDetails(hardware_dev_info, 234 dev_info_data, 235 &func_class_dev_data)) { 236 return false; 237 } 238 239 try { 240 *name = func_class_dev_data->DevicePath; 241 } catch (...) { 242 SetLastError(ERROR_OUTOFMEMORY); 243 } 244 245 free(func_class_dev_data); 246 247 return !name->empty(); 248} 249