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 rotines that are exported 19 from this DLL. 20 */ 21 22 #include "stdafx.h" 23 #include "adb_api.h" 24 #include "adb_object_handle.h" 25 #include "adb_interface_enum.h" 26 #include "adb_interface.h" 27 #include "adb_legacy_interface.h" 28 #include "adb_endpoint_object.h" 29 #include "adb_io_completion.h" 30 #include "adb_helper_routines.h" 31 #include "adb_winusb_api.h" 32 33 /** \brief Points to InstantiateWinUsbInterface exported from AdbWinUsbApi.dll. 34 35 This variable is initialized with the actual address in DllMain routine for 36 this DLL on DLL_PROCESS_ATTACH event. 37 @see PFN_INSTWINUSBINTERFACE for more information. 38 */ 39 PFN_INSTWINUSBINTERFACE InstantiateWinUsbInterface = NULL; 40 41 ADBAPIHANDLE __cdecl AdbEnumInterfaces(GUID class_id, 42 bool exclude_not_present, 43 bool exclude_removed, 44 bool active_only) { 45 AdbInterfaceEnumObject* enum_obj = NULL; 46 ADBAPIHANDLE ret = NULL; 47 48 try { 49 // Instantiate and initialize enum object 50 enum_obj = new AdbInterfaceEnumObject(); 51 52 if (enum_obj->InitializeEnum(class_id, 53 exclude_not_present, 54 exclude_removed, 55 active_only)) { 56 // After successful initialization we can create handle. 57 ret = enum_obj->CreateHandle(); 58 } 59 } catch (...) { 60 SetLastError(ERROR_OUTOFMEMORY); 61 } 62 63 if (NULL != enum_obj) 64 enum_obj->Release(); 65 66 return ret; 67 } 68 69 bool __cdecl AdbNextInterface(ADBAPIHANDLE adb_handle, 70 AdbInterfaceInfo* info, 71 unsigned long* size) { 72 if (NULL == size) { 73 SetLastError(ERROR_INVALID_PARAMETER); 74 return false; 75 } 76 77 // Lookup AdbInterfaceEnumObject object for the handle 78 AdbInterfaceEnumObject* adb_ienum_object = 79 LookupObject<AdbInterfaceEnumObject>(adb_handle); 80 if (NULL == adb_ienum_object) 81 return false; 82 83 // Everything is verified. Pass it down to the object 84 bool ret = adb_ienum_object->Next(info, size); 85 86 adb_ienum_object->Release(); 87 88 return ret; 89 } 90 91 bool __cdecl AdbResetInterfaceEnum(ADBAPIHANDLE adb_handle) { 92 // Lookup AdbInterfaceEnumObject object for the handle 93 AdbInterfaceEnumObject* adb_ienum_object = 94 LookupObject<AdbInterfaceEnumObject>(adb_handle); 95 if (NULL == adb_ienum_object) 96 return false; 97 98 // Everything is verified. Pass it down to the object 99 bool ret = adb_ienum_object->Reset(); 100 101 adb_ienum_object->Release(); 102 103 return ret; 104 } 105 106 ADBAPIHANDLE __cdecl AdbCreateInterfaceByName( 107 const wchar_t* interface_name) { 108 AdbInterfaceObject* obj = NULL; 109 ADBAPIHANDLE ret = NULL; 110 111 try { 112 // Instantiate interface object, depending on the USB driver type. 113 if (IsLegacyInterface(interface_name)) { 114 // We have legacy USB driver underneath us. 115 obj = new AdbLegacyInterfaceObject(interface_name); 116 } else { 117 // We have WinUsb driver underneath us. Make sure that AdbWinUsbApi.dll 118 // is loaded and its InstantiateWinUsbInterface routine address has 119 // been cached. 120 if (NULL != InstantiateWinUsbInterface) { 121 obj = InstantiateWinUsbInterface(interface_name); 122 if (NULL == obj) { 123 return NULL; 124 } 125 } else { 126 return NULL; 127 } 128 } 129 130 // Create handle for it 131 ret = obj->CreateHandle(); 132 } catch (...) { 133 SetLastError(ERROR_OUTOFMEMORY); 134 } 135 136 if (NULL != obj) 137 obj->Release(); 138 139 return ret; 140 } 141 142 ADBAPIHANDLE __cdecl AdbCreateInterface(GUID class_id, 143 unsigned short vendor_id, 144 unsigned short product_id, 145 unsigned char interface_id) { 146 // Enumerate all active interfaces for the given class 147 AdbEnumInterfaceArray interfaces; 148 149 if (!EnumerateDeviceInterfaces(class_id, 150 DIGCF_DEVICEINTERFACE | DIGCF_PRESENT, 151 true, 152 true, 153 &interfaces)) { 154 return NULL; 155 } 156 157 if (interfaces.empty()) { 158 SetLastError(ERROR_DEVICE_NOT_AVAILABLE); 159 return NULL; 160 } 161 162 // Now iterate over active interfaces looking for the name match. 163 // The name is formatted as such: 164 // "\\\\?\\usb#vid_xxxx&pid_xxxx&mi_xx#123456789abcdef#{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 165 // where 166 // vid_xxxx is for the vendor id (xxxx are hex for the given vendor id), 167 // pid_xxxx is for the product id (xxxx are hex for the given product id) 168 // mi_xx is for the interface id (xx are hex for the given interface id) 169 // EnumerateDeviceInterfaces will guarantee that returned interface names 170 // will have our class id at the end of the name (those last XXXes in the 171 // format). So, we only need to match the beginning of the name 172 wchar_t match_name[64]; 173 if (0xFF == interface_id) { 174 // No interface id for the name. 175 swprintf(match_name, L"\\\\?\\usb#vid_%04x&pid_%04x#", 176 vendor_id, product_id); 177 } else { 178 // With interface id for the name. 179 swprintf(match_name, L"\\\\?\\usb#vid_%04x&pid_%04x&mi_%02x#", 180 vendor_id, product_id, interface_id); 181 } 182 size_t match_len = wcslen(match_name); 183 184 for (AdbEnumInterfaceArray::iterator it = interfaces.begin(); 185 it != interfaces.end(); it++) { 186 const AdbInstanceEnumEntry& next_interface = *it; 187 if (0 == _wcsnicmp(match_name, 188 next_interface.device_name().c_str(), 189 match_len)) { 190 // Found requested interface among active interfaces. 191 return AdbCreateInterfaceByName(next_interface.device_name().c_str()); 192 } 193 } 194 195 SetLastError(ERROR_DEVICE_NOT_AVAILABLE); 196 return NULL; 197 } 198 199 bool __cdecl AdbGetInterfaceName(ADBAPIHANDLE adb_interface, 200 void* buffer, 201 unsigned long* buffer_char_size, 202 bool ansi) { 203 // Lookup interface object for the handle 204 AdbInterfaceObject* adb_object = 205 LookupObject<AdbInterfaceObject>(adb_interface); 206 207 if (NULL != adb_object) { 208 // Dispatch call to the found object 209 bool ret = adb_object->GetInterfaceName(buffer, buffer_char_size, ansi); 210 adb_object->Release(); 211 return ret; 212 } else { 213 SetLastError(ERROR_INVALID_HANDLE); 214 return false; 215 } 216 } 217 218 bool __cdecl AdbGetSerialNumber(ADBAPIHANDLE adb_interface, 219 void* buffer, 220 unsigned long* buffer_char_size, 221 bool ansi) { 222 // Lookup interface object for the handle 223 AdbInterfaceObject* adb_object = 224 LookupObject<AdbInterfaceObject>(adb_interface); 225 226 if (NULL != adb_object) { 227 // Dispatch call to the found object 228 bool ret = adb_object->GetSerialNumber(buffer, buffer_char_size, ansi); 229 adb_object->Release(); 230 return ret; 231 } else { 232 SetLastError(ERROR_INVALID_HANDLE); 233 return false; 234 } 235 } 236 237 bool __cdecl AdbGetUsbDeviceDescriptor(ADBAPIHANDLE adb_interface, 238 USB_DEVICE_DESCRIPTOR* desc) { 239 // Lookup interface object for the handle 240 AdbInterfaceObject* adb_object = 241 LookupObject<AdbInterfaceObject>(adb_interface); 242 243 if (NULL != adb_object) { 244 // Dispatch close to the found object 245 bool ret = adb_object->GetUsbDeviceDescriptor(desc); 246 adb_object->Release(); 247 return ret; 248 } else { 249 SetLastError(ERROR_INVALID_HANDLE); 250 return false; 251 } 252 } 253 254 bool __cdecl AdbGetUsbConfigurationDescriptor(ADBAPIHANDLE adb_interface, 255 USB_CONFIGURATION_DESCRIPTOR* desc) { 256 // Lookup interface object for the handle 257 AdbInterfaceObject* adb_object = 258 LookupObject<AdbInterfaceObject>(adb_interface); 259 260 if (NULL != adb_object) { 261 // Dispatch close to the found object 262 bool ret = adb_object->GetUsbConfigurationDescriptor(desc); 263 adb_object->Release(); 264 return ret; 265 } else { 266 SetLastError(ERROR_INVALID_HANDLE); 267 return false; 268 } 269 } 270 271 bool __cdecl AdbGetUsbInterfaceDescriptor(ADBAPIHANDLE adb_interface, 272 USB_INTERFACE_DESCRIPTOR* desc) { 273 // Lookup interface object for the handle 274 AdbInterfaceObject* adb_object = 275 LookupObject<AdbInterfaceObject>(adb_interface); 276 277 if (NULL != adb_object) { 278 // Dispatch close to the found object 279 bool ret = adb_object->GetUsbInterfaceDescriptor(desc); 280 adb_object->Release(); 281 return ret; 282 } else { 283 SetLastError(ERROR_INVALID_HANDLE); 284 return false; 285 } 286 } 287 288 bool __cdecl AdbGetEndpointInformation(ADBAPIHANDLE adb_interface, 289 UCHAR endpoint_index, 290 AdbEndpointInformation* info) { 291 // Lookup interface object for the handle 292 AdbInterfaceObject* adb_object = 293 LookupObject<AdbInterfaceObject>(adb_interface); 294 295 if (NULL != adb_object) { 296 // Dispatch close to the found object 297 bool ret = adb_object->GetEndpointInformation(endpoint_index, info); 298 adb_object->Release(); 299 return ret; 300 } else { 301 SetLastError(ERROR_INVALID_HANDLE); 302 return false; 303 } 304 } 305 306 bool __cdecl AdbGetDefaultBulkReadEndpointInformation(ADBAPIHANDLE adb_interface, 307 AdbEndpointInformation* info) { 308 return AdbGetEndpointInformation(adb_interface, 309 ADB_QUERY_BULK_READ_ENDPOINT_INDEX, 310 info); 311 } 312 313 bool __cdecl AdbGetDefaultBulkWriteEndpointInformation(ADBAPIHANDLE adb_interface, 314 AdbEndpointInformation* info) { 315 return AdbGetEndpointInformation(adb_interface, 316 ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX, 317 info); 318 } 319 320 ADBAPIHANDLE __cdecl AdbOpenEndpoint(ADBAPIHANDLE adb_interface, 321 unsigned char endpoint_index, 322 AdbOpenAccessType access_type, 323 AdbOpenSharingMode sharing_mode) { 324 // Lookup interface object for the handle 325 AdbInterfaceObject* adb_object = 326 LookupObject<AdbInterfaceObject>(adb_interface); 327 328 if (NULL != adb_object) { 329 // Dispatch close to the found object 330 ADBAPIHANDLE ret = 331 adb_object->OpenEndpoint(endpoint_index, access_type, sharing_mode); 332 adb_object->Release(); 333 return ret; 334 } else { 335 SetLastError(ERROR_INVALID_HANDLE); 336 return NULL; 337 } 338 } 339 340 ADBAPIHANDLE __cdecl AdbOpenDefaultBulkReadEndpoint(ADBAPIHANDLE adb_interface, 341 AdbOpenAccessType access_type, 342 AdbOpenSharingMode sharing_mode) { 343 return AdbOpenEndpoint(adb_interface, 344 ADB_QUERY_BULK_READ_ENDPOINT_INDEX, 345 access_type, 346 sharing_mode); 347 } 348 349 ADBAPIHANDLE __cdecl AdbOpenDefaultBulkWriteEndpoint(ADBAPIHANDLE adb_interface, 350 AdbOpenAccessType access_type, 351 AdbOpenSharingMode sharing_mode) { 352 return AdbOpenEndpoint(adb_interface, 353 ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX, 354 access_type, 355 sharing_mode); 356 } 357 358 ADBAPIHANDLE __cdecl AdbGetEndpointInterface(ADBAPIHANDLE adb_endpoint) { 359 // Lookup endpoint object for the handle 360 AdbEndpointObject* adb_object = 361 LookupObject<AdbEndpointObject>(adb_endpoint); 362 363 if (NULL != adb_object) { 364 // Dispatch the call to the found object 365 ADBAPIHANDLE ret = adb_object->GetParentInterfaceHandle(); 366 adb_object->Release(); 367 return ret; 368 } else { 369 SetLastError(ERROR_INVALID_HANDLE); 370 return NULL; 371 } 372 } 373 374 bool __cdecl AdbQueryInformationEndpoint(ADBAPIHANDLE adb_endpoint, 375 AdbEndpointInformation* info) { 376 // Lookup endpoint object for the handle 377 AdbEndpointObject* adb_object = 378 LookupObject<AdbEndpointObject>(adb_endpoint); 379 380 if (NULL != adb_object) { 381 // Dispatch the call to the found object 382 bool ret = adb_object->GetEndpointInformation(info); 383 adb_object->Release(); 384 return ret; 385 } else { 386 SetLastError(ERROR_INVALID_HANDLE); 387 return false; 388 } 389 } 390 391 ADBAPIHANDLE __cdecl AdbReadEndpointAsync(ADBAPIHANDLE adb_endpoint, 392 void* buffer, 393 unsigned long bytes_to_read, 394 unsigned long* bytes_read, 395 unsigned long time_out, 396 HANDLE event_handle) { 397 // Lookup endpoint object for the handle 398 AdbEndpointObject* adb_object = 399 LookupObject<AdbEndpointObject>(adb_endpoint); 400 401 if (NULL != adb_object) { 402 // Dispatch the call to the found object 403 ADBAPIHANDLE ret = adb_object->AsyncRead(buffer, 404 bytes_to_read, 405 bytes_read, 406 event_handle, 407 time_out); 408 adb_object->Release(); 409 return ret; 410 } else { 411 SetLastError(ERROR_INVALID_HANDLE); 412 return NULL; 413 } 414 } 415 416 ADBAPIHANDLE __cdecl AdbWriteEndpointAsync(ADBAPIHANDLE adb_endpoint, 417 void* buffer, 418 unsigned long bytes_to_write, 419 unsigned long* bytes_written, 420 unsigned long time_out, 421 HANDLE event_handle) { 422 // Lookup endpoint object for the handle 423 AdbEndpointObject* adb_object = 424 LookupObject<AdbEndpointObject>(adb_endpoint); 425 426 if (NULL != adb_object) { 427 // Dispatch the call to the found object 428 ADBAPIHANDLE ret = adb_object->AsyncWrite(buffer, 429 bytes_to_write, 430 bytes_written, 431 event_handle, 432 time_out); 433 adb_object->Release(); 434 return ret; 435 } else { 436 SetLastError(ERROR_INVALID_HANDLE); 437 return false; 438 } 439 } 440 441 bool __cdecl AdbReadEndpointSync(ADBAPIHANDLE adb_endpoint, 442 void* buffer, 443 unsigned long bytes_to_read, 444 unsigned long* bytes_read, 445 unsigned long time_out) { 446 // Lookup endpoint object for the handle 447 AdbEndpointObject* adb_object = 448 LookupObject<AdbEndpointObject>(adb_endpoint); 449 450 if (NULL != adb_object) { 451 // Dispatch the call to the found object 452 bool ret = 453 adb_object->SyncRead(buffer, bytes_to_read, bytes_read, time_out); 454 adb_object->Release(); 455 return ret; 456 } else { 457 SetLastError(ERROR_INVALID_HANDLE); 458 return NULL; 459 } 460 } 461 462 bool __cdecl AdbWriteEndpointSync(ADBAPIHANDLE adb_endpoint, 463 void* buffer, 464 unsigned long bytes_to_write, 465 unsigned long* bytes_written, 466 unsigned long time_out) { 467 // Lookup endpoint object for the handle 468 AdbEndpointObject* adb_object = 469 LookupObject<AdbEndpointObject>(adb_endpoint); 470 471 if (NULL != adb_object) { 472 // Dispatch the call to the found object 473 bool ret = 474 adb_object->SyncWrite(buffer, bytes_to_write, bytes_written, time_out); 475 adb_object->Release(); 476 return ret; 477 } else { 478 SetLastError(ERROR_INVALID_HANDLE); 479 return false; 480 } 481 } 482 483 bool __cdecl AdbGetOvelappedIoResult(ADBAPIHANDLE adb_io_completion, 484 LPOVERLAPPED overlapped, 485 unsigned long* bytes_transferred, 486 bool wait) { 487 // Lookup endpoint object for the handle 488 AdbIOCompletion* adb_object = 489 LookupObject<AdbIOCompletion>(adb_io_completion); 490 491 if (NULL != adb_object) { 492 // Dispatch the call to the found object 493 bool ret = 494 adb_object->GetOvelappedIoResult(overlapped, bytes_transferred, wait); 495 adb_object->Release(); 496 return ret; 497 } else { 498 SetLastError(ERROR_INVALID_HANDLE); 499 return false; 500 } 501 } 502 503 bool __cdecl AdbHasOvelappedIoComplated(ADBAPIHANDLE adb_io_completion) { 504 // Lookup endpoint object for the handle 505 AdbIOCompletion* adb_object = 506 LookupObject<AdbIOCompletion>(adb_io_completion); 507 508 if (NULL != adb_object) { 509 // Dispatch the call to the found object 510 bool ret = 511 adb_object->IsCompleted(); 512 adb_object->Release(); 513 return ret; 514 } else { 515 SetLastError(ERROR_INVALID_HANDLE); 516 return true; 517 } 518 } 519 520 bool __cdecl AdbCloseHandle(ADBAPIHANDLE adb_handle) { 521 // Lookup object for the handle 522 AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle); 523 524 if (NULL != adb_object) { 525 // Dispatch close to the found object 526 bool ret = adb_object->CloseHandle(); 527 adb_object->Release(); 528 return ret; 529 } else { 530 SetLastError(ERROR_INVALID_HANDLE); 531 return false; 532 } 533 } 534