1 /* 2 * Copyright (C) 2009 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 class AdbLegacyInterfaceObject 19 that encapsulates an interface on our USB device that is accessible 20 */ 21 22 #include "stdafx.h" 23 #include "adb_api_legacy.h" 24 #include "adb_legacy_interface.h" 25 #include "adb_legacy_endpoint_object.h" 26 27 AdbLegacyInterfaceObject::AdbLegacyInterfaceObject(const wchar_t* interf_name) 28 : AdbInterfaceObject(interf_name), 29 def_read_endpoint_(0xFF), 30 read_endpoint_id_(0xFF), 31 def_write_endpoint_(0xFF), 32 write_endpoint_id_(0xFF) { 33 } 34 35 AdbLegacyInterfaceObject::~AdbLegacyInterfaceObject() { 36 } 37 38 ADBAPIHANDLE AdbLegacyInterfaceObject::CreateHandle() { 39 // Open USB device for this intefface 40 HANDLE usb_device_handle = CreateFile(interface_name().c_str(), 41 GENERIC_READ | GENERIC_WRITE, 42 FILE_SHARE_READ | FILE_SHARE_WRITE, 43 NULL, 44 OPEN_EXISTING, 45 0, 46 NULL); 47 if (INVALID_HANDLE_VALUE == usb_device_handle) { 48 return NULL; 49 } 50 51 // Now, we ensured that our usb device / interface is up and running. 52 // Lets collect device, interface and pipe information 53 bool ok = true; 54 if (!CacheUsbDeviceDescriptor(usb_device_handle) || 55 !CacheUsbConfigurationDescriptor(usb_device_handle) || 56 !CacheUsbInterfaceDescriptor(usb_device_handle)) { 57 ok = false; 58 } 59 60 // Preserve error accross handle close 61 ULONG error = ok ? NO_ERROR : GetLastError(); 62 63 ::CloseHandle(usb_device_handle); 64 65 if (NO_ERROR != error) { 66 SetLastError(error); 67 } 68 69 if (!ok) { 70 return false; 71 } 72 73 // Save indexes and IDs for bulk read / write endpoints. We will use them to 74 // convert ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX and 75 // ADB_QUERY_BULK_READ_ENDPOINT_INDEX into actual endpoint indexes and IDs. 76 for (UCHAR endpoint = 0; endpoint < usb_interface_descriptor_.bNumEndpoints; 77 endpoint++) { 78 // Get endpoint information 79 AdbEndpointInformation pipe_info; 80 if (!GetEndpointInformation(endpoint, &pipe_info)) { 81 return false; 82 } 83 84 if (AdbEndpointTypeBulk == pipe_info.endpoint_type) { 85 // This is a bulk endpoint. Cache its index and ID. 86 if (0 != (pipe_info.endpoint_address & USB_ENDPOINT_DIRECTION_MASK)) { 87 // Use this endpoint as default bulk read endpoint 88 ATLASSERT(0xFF == def_read_endpoint_); 89 def_read_endpoint_ = endpoint; 90 read_endpoint_id_ = pipe_info.endpoint_address; 91 } else { 92 // Use this endpoint as default bulk write endpoint 93 ATLASSERT(0xFF == def_write_endpoint_); 94 def_write_endpoint_ = endpoint; 95 write_endpoint_id_ = pipe_info.endpoint_address; 96 } 97 } 98 } 99 100 return AdbObjectHandle::CreateHandle(); 101 } 102 103 bool AdbLegacyInterfaceObject::GetSerialNumber(void* buffer, 104 unsigned long* buffer_char_size, 105 bool ansi) { 106 if (!IsOpened()) { 107 SetLastError(ERROR_INVALID_HANDLE); 108 return false; 109 } 110 111 // Open USB device for this intefface 112 HANDLE usb_device_handle = CreateFile(interface_name().c_str(), 113 GENERIC_READ, 114 FILE_SHARE_READ | FILE_SHARE_WRITE, 115 NULL, 116 OPEN_EXISTING, 117 0, 118 NULL); 119 if (INVALID_HANDLE_VALUE == usb_device_handle) { 120 return NULL; 121 } 122 123 WCHAR serial_number[512]; 124 125 // Send IOCTL 126 DWORD ret_bytes = 0; 127 BOOL ret = DeviceIoControl(usb_device_handle, 128 ADB_IOCTL_GET_SERIAL_NUMBER, 129 NULL, 0, 130 serial_number, sizeof(serial_number), 131 &ret_bytes, 132 NULL); 133 134 // Preserve error accross CloseHandle 135 ULONG error = ret ? NO_ERROR : GetLastError(); 136 137 ::CloseHandle(usb_device_handle); 138 139 if (NO_ERROR != error) { 140 SetLastError(error); 141 return false; 142 } 143 144 unsigned long str_len = 145 static_cast<unsigned long>(wcslen(serial_number) + 1); 146 147 if ((NULL == buffer) || (*buffer_char_size < str_len)) { 148 *buffer_char_size = str_len; 149 SetLastError(ERROR_INSUFFICIENT_BUFFER); 150 return false; 151 } 152 153 if (!ansi) { 154 // If user asked for wide char name just return it 155 wcscpy(reinterpret_cast<wchar_t*>(buffer), serial_number); 156 return true; 157 } 158 159 // We need to convert name from wide char to ansi string 160 int res = WideCharToMultiByte(CP_ACP, 161 0, 162 serial_number, 163 static_cast<int>(str_len), 164 reinterpret_cast<PSTR>(buffer), 165 static_cast<int>(*buffer_char_size), 166 NULL, 167 NULL); 168 return (res != 0); 169 } 170 171 bool AdbLegacyInterfaceObject::GetEndpointInformation( 172 UCHAR endpoint_index, 173 AdbEndpointInformation* info) { 174 // Open USB device for this intefface 175 HANDLE usb_device_handle = CreateFile(interface_name().c_str(), 176 GENERIC_READ, 177 FILE_SHARE_READ | FILE_SHARE_WRITE, 178 NULL, 179 OPEN_EXISTING, 180 0, 181 NULL); 182 if (INVALID_HANDLE_VALUE == usb_device_handle) { 183 return NULL; 184 } 185 186 // Init ICTL param 187 AdbQueryEndpointInformation param; 188 param.endpoint_index = endpoint_index; 189 190 // Send IOCTL 191 DWORD ret_bytes = 0; 192 BOOL ret = DeviceIoControl(usb_device_handle, 193 ADB_IOCTL_GET_ENDPOINT_INFORMATION, 194 ¶m, sizeof(param), 195 info, sizeof(AdbEndpointInformation), 196 &ret_bytes, 197 NULL); 198 ATLASSERT(!ret || (sizeof(AdbEndpointInformation) == ret_bytes)); 199 200 // Preserve error accross CloseHandle 201 ULONG error = ret ? NO_ERROR : GetLastError(); 202 203 ::CloseHandle(usb_device_handle); 204 205 if (NO_ERROR != error) { 206 SetLastError(error); 207 } 208 209 return ret ? true : false; 210 } 211 212 ADBAPIHANDLE AdbLegacyInterfaceObject::OpenEndpoint( 213 UCHAR endpoint_index, 214 AdbOpenAccessType access_type, 215 AdbOpenSharingMode sharing_mode) { 216 // Convert index into name and ID. 217 std::wstring endpoint_name; 218 UCHAR endpoint_id; 219 220 try { 221 if ((ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index) || 222 (def_read_endpoint_ == endpoint_index)) { 223 endpoint_name = DEVICE_BULK_READ_PIPE_NAME; 224 endpoint_id = read_endpoint_id_; 225 endpoint_index = def_read_endpoint_; 226 } else if ((ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX == endpoint_index) || 227 (def_write_endpoint_ == endpoint_index)) { 228 endpoint_name = DEVICE_BULK_WRITE_PIPE_NAME; 229 endpoint_id = write_endpoint_id_; 230 endpoint_index = def_write_endpoint_; 231 } else { 232 SetLastError(ERROR_INVALID_PARAMETER); 233 return false; 234 } 235 } catch (...) { 236 // We don't expect exceptions other than OOM thrown here. 237 SetLastError(ERROR_OUTOFMEMORY); 238 return NULL; 239 } 240 241 return OpenEndpoint(endpoint_name.c_str(), endpoint_id, endpoint_index, 242 access_type, sharing_mode); 243 } 244 245 ADBAPIHANDLE AdbLegacyInterfaceObject::OpenEndpoint( 246 const wchar_t* endpoint_name, 247 UCHAR endpoint_id, 248 UCHAR endpoint_index, 249 AdbOpenAccessType access_type, 250 AdbOpenSharingMode sharing_mode) { 251 if (!IsOpened()) { 252 SetLastError(ERROR_INVALID_HANDLE); 253 return false; 254 } 255 256 AdbLegacyEndpointObject* adb_endpoint = NULL; 257 258 try { 259 adb_endpoint = 260 new AdbLegacyEndpointObject(this, endpoint_id, endpoint_index); 261 } catch (...) { 262 // We don't expect exceptions other than OOM thrown here. 263 SetLastError(ERROR_OUTOFMEMORY); 264 return NULL; 265 } 266 267 // Build full path to the object 268 std::wstring endpoint_path = interface_name(); 269 endpoint_path += L"\\"; 270 endpoint_path += endpoint_name; 271 272 ADBAPIHANDLE ret = adb_endpoint->CreateHandle(endpoint_path.c_str(), 273 access_type, 274 sharing_mode); 275 276 adb_endpoint->Release(); 277 278 return ret; 279 } 280 281 bool AdbLegacyInterfaceObject::CacheUsbDeviceDescriptor( 282 HANDLE usb_device_handle) { 283 DWORD ret_bytes = 0; 284 BOOL ret = DeviceIoControl(usb_device_handle, 285 ADB_IOCTL_GET_USB_DEVICE_DESCRIPTOR, 286 NULL, 0, 287 &usb_device_descriptor_, 288 sizeof(usb_device_descriptor_), 289 &ret_bytes, 290 NULL); 291 ATLASSERT(!ret || (sizeof(USB_DEVICE_DESCRIPTOR) == ret_bytes)); 292 293 return ret ? true : false; 294 } 295 296 bool AdbLegacyInterfaceObject::CacheUsbConfigurationDescriptor( 297 HANDLE usb_device_handle) { 298 DWORD ret_bytes = 0; 299 BOOL ret = DeviceIoControl(usb_device_handle, 300 ADB_IOCTL_GET_USB_CONFIGURATION_DESCRIPTOR, 301 NULL, 0, 302 &usb_config_descriptor_, 303 sizeof(usb_config_descriptor_), 304 &ret_bytes, 305 NULL); 306 ATLASSERT(!ret || (sizeof(USB_CONFIGURATION_DESCRIPTOR) == ret_bytes)); 307 308 return ret ? true : false; 309 } 310 311 bool AdbLegacyInterfaceObject::CacheUsbInterfaceDescriptor( 312 HANDLE usb_device_handle) { 313 DWORD ret_bytes = 0; 314 BOOL ret = DeviceIoControl(usb_device_handle, 315 ADB_IOCTL_GET_USB_INTERFACE_DESCRIPTOR, 316 NULL, 0, 317 &usb_interface_descriptor_, 318 sizeof(usb_interface_descriptor_), 319 &ret_bytes, 320 NULL); 321 ATLASSERT(!ret || (sizeof(USB_INTERFACE_DESCRIPTOR) == ret_bytes)); 322 323 return ret ? true : false; 324 } 325