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 // This file contains implementation of a test application that tests 18 // functionality of AdbWinApi interface. In this test we will use AdbWinApi 19 // interface in order to enumerate USB interfaces for Android ADB class, and 20 // for each interface found we will test USB I/O on that interface by sending 21 // a simple "hand shake" message to the device connected via this interface. 22 23 #include "stdafx.h" 24 25 #ifdef _DEBUG 26 #define new DEBUG_NEW 27 #endif 28 29 // Android ADB interface identifier 30 const GUID kAdbInterfaceId = ANDROID_USB_CLASS_ID; 31 32 // Number of interfaces detected in TestEnumInterfaces. 33 int interface_count = 0; 34 35 // Constants used to initialize a "handshake" message 36 #define MAX_PAYLOAD 4096 37 #define A_SYNC 0x434e5953 38 #define A_CNXN 0x4e584e43 39 #define A_OPEN 0x4e45504f 40 #define A_OKAY 0x59414b4f 41 #define A_CLSE 0x45534c43 42 #define A_WRTE 0x45545257 43 #define A_AUTH 0x48545541 44 #define A_VERSION 0x01000000 45 46 // AUTH packets first argument 47 #define ADB_AUTH_TOKEN 1 48 #define ADB_AUTH_SIGNATURE 2 49 #define ADB_AUTH_RSAPUBLICKEY 3 50 51 // Interface descriptor constants for ADB interface 52 #define ADB_CLASS 0xff 53 #define ADB_SUBCLASS 0x42 54 #define ADB_PROTOCOL 0x1 55 56 // Formats message sent to USB device 57 struct message { 58 unsigned int command; /* command identifier constant */ 59 unsigned int arg0; /* first argument */ 60 unsigned int arg1; /* second argument */ 61 unsigned int data_length; /* length of payload (0 is allowed) */ 62 unsigned int data_crc32; /* crc32 of data payload */ 63 unsigned int magic; /* command ^ 0xffffffff */ 64 }; 65 66 // 67 // Test routines declarations. 68 // 69 70 // Tests interface enumeration. 71 bool TestEnumInterfaces(); 72 73 // Tests all interfaces detected for our device class. 74 bool TestInterfaces(); 75 76 // Tests interface addressed by the given device name. 77 bool TestInterface(const wchar_t* device_name); 78 79 // Tests interface opened with ADB API. 80 bool TestInterfaceHandle(ADBAPIHANDLE interface_handle); 81 82 // Sends a "handshake" message to the given interface. 83 bool DeviceHandShake(ADBAPIHANDLE adb_interface); 84 85 // Test AdbCloseHandle race condition. 86 bool TestCloseRaceCondition(); 87 88 int __cdecl _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { 89 // Test enum interfaces. 90 if (!TestEnumInterfaces()) 91 return -1; 92 93 if (0 == interface_count) { 94 printf("\nNo ADB interfaces found. Make sure that device is " 95 "connected to USB port and is powered on."); 96 return 1; 97 } 98 99 // Test each interface found in the system 100 if (!TestInterfaces()) 101 return -2; 102 103 // Test for AdbCloseHandle race condition 104 if (!TestCloseRaceCondition()) 105 return -3; 106 107 return 0; 108 } 109 110 bool TestEnumInterfaces() { 111 // Enumerate interfaces 112 ADBAPIHANDLE enum_handle = 113 AdbEnumInterfaces(kAdbInterfaceId, true, true, true); 114 if (NULL == enum_handle) { 115 printf("\nEnum interfaces failure:"); 116 printf("\nUnable to enumerate ADB interfaces: %u", GetLastError()); 117 return false; 118 } 119 120 // Unite interface info structure and buffer big enough to contain the 121 // largest structure. 122 union { 123 AdbInterfaceInfo interface_info; 124 char buf[4096]; 125 }; 126 unsigned long buf_size = sizeof(buf); 127 128 // Enumerate (and count) interfaces, printing information for each found 129 // interface. 130 interface_count = 0; 131 while (AdbNextInterface(enum_handle, &interface_info, &buf_size)) { 132 interface_count++; 133 printf("\nFound interface %ws:", interface_info.device_name); 134 if (interface_info.flags & SPINT_ACTIVE) 135 printf(" ACTIVE"); 136 if (interface_info.flags & SPINT_DEFAULT) 137 printf(" DEFAULT"); 138 if (interface_info.flags & SPINT_REMOVED) 139 printf(" REMOVED"); 140 141 buf_size = sizeof(buf); 142 } 143 144 bool ret = true; 145 if (GetLastError() != ERROR_NO_MORE_ITEMS) { 146 printf("\n--- AdbNextInterface failure %u", GetLastError()); 147 ret = false; 148 } 149 150 if (!AdbCloseHandle(enum_handle)) { 151 printf("\n--- AdbCloseHandle failure %u", GetLastError()); 152 ret = false; 153 } 154 155 return ret; 156 } 157 158 bool TestInterfaces() { 159 bool ret = true; 160 161 // Enumerate interfaces 162 ADBAPIHANDLE enum_handle = 163 AdbEnumInterfaces(kAdbInterfaceId, true, true, true); 164 if (NULL == enum_handle) { 165 printf("\nTest interfaces failure:"); 166 printf("\nUnable to enumerate ADB interfaces: %u", GetLastError()); 167 ret = false; 168 } else { 169 // Unite interface info structure and buffer big enough to contain the 170 // largest structure. 171 union { 172 AdbInterfaceInfo interface_info; 173 char buf[4096]; 174 }; 175 unsigned long buf_size = sizeof(buf); 176 177 // Test each found interface 178 while (AdbNextInterface(enum_handle, &interface_info, &buf_size)) { 179 TestInterface(interface_info.device_name); 180 buf_size = sizeof(buf); 181 } 182 183 if (GetLastError() != ERROR_NO_MORE_ITEMS) { 184 printf("\n--- AdbNextInterface failure %u", GetLastError()); 185 ret = false; 186 } 187 188 if (!AdbCloseHandle(enum_handle)) { 189 printf("\n--- AdbCloseHandle failure %u", GetLastError()); 190 ret = false; 191 } 192 } 193 194 return ret; 195 } 196 197 bool TestInterface(const wchar_t* device_name) { 198 printf("\n*** Test interface( %ws )", device_name); 199 200 // Get ADB handle to the interface by its name 201 ADBAPIHANDLE interface_handle = AdbCreateInterfaceByName(device_name); 202 if (NULL == interface_handle) { 203 printf(" FAILED:\nUnable to create interface by name: %u", GetLastError()); 204 return false; 205 } 206 207 // Test it 208 TestInterfaceHandle(interface_handle); 209 if (!AdbCloseHandle(interface_handle)) { 210 printf("\n--- AdbCloseHandle failure %u", GetLastError()); 211 return false; 212 } 213 214 return true; 215 } 216 217 bool TestInterfaceName(ADBAPIHANDLE interface_handle) { 218 bool ret = true; 219 unsigned long intr_name_size = 0; 220 char* buf = NULL; 221 222 if (AdbGetInterfaceName(interface_handle, NULL, &intr_name_size, true)) { 223 printf("\n--- AdbGetInterfaceName unexpectedly succeeded %u", 224 GetLastError()); 225 ret = false; 226 goto exit; 227 } 228 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { 229 printf("\n--- AdbGetInterfaceName failure %u", GetLastError()); 230 ret = false; 231 goto exit; 232 } 233 if (intr_name_size == 0) { 234 printf("\n--- AdbGetInterfaceName returned name size of zero"); 235 ret = false; 236 goto exit; 237 } 238 239 const size_t buf_size = intr_name_size + 16; // extra in case of overwrite 240 buf = reinterpret_cast<char*>(malloc(buf_size)); 241 if (buf == NULL) { 242 printf("\n--- could not malloc %d bytes, errno %u", buf_size, errno); 243 ret = false; 244 goto exit; 245 } 246 const char buf_fill = (unsigned char)0xFF; 247 memset(buf, buf_fill, buf_size); 248 249 if (!AdbGetInterfaceName(interface_handle, buf, &intr_name_size, true)) { 250 printf("\n--- AdbGetInterfaceName failure %u", GetLastError()); 251 ret = false; 252 goto exit; 253 } 254 if (buf[intr_name_size - 1] != '\0') { 255 printf("\n--- AdbGetInterfaceName returned non-NULL terminated string"); 256 ret = false; 257 goto exit; 258 } 259 for (size_t i = intr_name_size; i < buf_size; ++i) { 260 if (buf[i] != buf_fill) { 261 printf("\n--- AdbGetInterfaceName overwrote past the end of the buffer at" 262 " index %u with 0x%02X", i, (unsigned char)buf[i]); 263 ret = false; 264 goto exit; 265 } 266 } 267 268 printf("\n+++ Interface name %s", buf); 269 270 exit: 271 free(buf); 272 273 return ret; 274 } 275 276 void DumpEndpointInformation(const AdbEndpointInformation* pipe_info) { 277 printf("\n max_packet_size = %u", pipe_info->max_packet_size); 278 printf("\n max_transfer_size = %u", pipe_info->max_transfer_size); 279 printf("\n endpoint_type = %u", pipe_info->endpoint_type); 280 const char* endpoint_type_desc = NULL; 281 switch (pipe_info->endpoint_type) { 282 #define CASE_TYPE(type) case type: endpoint_type_desc = #type; break 283 CASE_TYPE(AdbEndpointTypeInvalid); 284 CASE_TYPE(AdbEndpointTypeControl); 285 CASE_TYPE(AdbEndpointTypeIsochronous); 286 CASE_TYPE(AdbEndpointTypeBulk); 287 CASE_TYPE(AdbEndpointTypeInterrupt); 288 #undef CASE_TYPE 289 } 290 if (endpoint_type_desc != NULL) { 291 printf(" (%s)", endpoint_type_desc); 292 } 293 printf("\n endpoint_address = %02X", pipe_info->endpoint_address); 294 printf("\n polling_interval = %u", pipe_info->polling_interval); 295 printf("\n setting_index = %u", pipe_info->setting_index); 296 } 297 298 bool TestInterfaceHandle(ADBAPIHANDLE interface_handle) { 299 // Get interface name. 300 if (!TestInterfaceName(interface_handle)) { 301 return false; 302 } 303 304 // Get device descriptor for the interface 305 USB_DEVICE_DESCRIPTOR dev_desc; 306 if (AdbGetUsbDeviceDescriptor(interface_handle, &dev_desc)) { 307 printf("\n+++ Device descriptor:"); 308 printf("\n bLength = %u", dev_desc.bLength); 309 printf("\n bDescriptorType = %u", dev_desc.bDescriptorType); 310 printf("\n bcdUSB = %u", dev_desc.bcdUSB); 311 printf("\n bDeviceClass = %u", dev_desc.bDeviceClass); 312 printf("\n bDeviceSubClass = %u", dev_desc.bDeviceSubClass); 313 printf("\n bDeviceProtocol = %u", dev_desc.bDeviceProtocol); 314 printf("\n bMaxPacketSize0 = %u", dev_desc.bMaxPacketSize0); 315 printf("\n idVendor = %X", dev_desc.idVendor); 316 printf("\n idProduct = %X", dev_desc.idProduct); 317 printf("\n bcdDevice = %u", dev_desc.bcdDevice); 318 printf("\n iManufacturer = %u", dev_desc.iManufacturer); 319 printf("\n iProduct = %u", dev_desc.iProduct); 320 printf("\n iSerialNumber = %u", dev_desc.iSerialNumber); 321 printf("\n bNumConfigurations = %u", dev_desc.bNumConfigurations); 322 } else { 323 printf("\n--- AdbGetUsbDeviceDescriptor failure %u", GetLastError()); 324 return false; 325 } 326 327 // Get configuration descriptor for the interface 328 USB_CONFIGURATION_DESCRIPTOR config_desc; 329 if (AdbGetUsbConfigurationDescriptor(interface_handle, &config_desc)) { 330 printf("\n+++ Configuration descriptor:"); 331 printf("\n bLength = %u", config_desc.bLength); 332 printf("\n bDescriptorType = %u", config_desc.bDescriptorType); 333 printf("\n wTotalLength = %u", config_desc.wTotalLength); 334 printf("\n bNumInterfaces = %u", config_desc.bNumInterfaces); 335 printf("\n bConfigurationValue = %u", config_desc.bConfigurationValue); 336 printf("\n iConfiguration = %u", config_desc.iConfiguration); 337 printf("\n bmAttributes = %u", config_desc.bmAttributes); 338 printf("\n MaxPower = %u", config_desc.MaxPower); 339 } else { 340 printf("\n--- AdbGetUsbConfigurationDescriptor failure %u", GetLastError()); 341 return false; 342 } 343 344 // Get device serial number 345 char ser_num[1024]; 346 unsigned long ser_num_size = sizeof(ser_num); 347 if (AdbGetSerialNumber(interface_handle, ser_num, &ser_num_size, true)) { 348 printf("\n+++ Serial number: %s", ser_num); 349 } else { 350 printf("\n--- AdbGetSerialNumber failure %u", GetLastError()); 351 return false; 352 } 353 354 // Get interface descriptor 355 USB_INTERFACE_DESCRIPTOR intr_desc; 356 if (AdbGetUsbInterfaceDescriptor(interface_handle, &intr_desc)) { 357 printf("\n+++ Interface descriptor:"); 358 printf("\n bDescriptorType = %u", intr_desc.bDescriptorType); 359 printf("\n bInterfaceNumber = %u", intr_desc.bInterfaceNumber); 360 printf("\n bAlternateSetting = %u", intr_desc.bAlternateSetting); 361 printf("\n bNumEndpoints = %u", intr_desc.bNumEndpoints); 362 printf("\n bInterfaceClass = %u", intr_desc.bInterfaceClass); 363 if (intr_desc.bInterfaceClass == ADB_CLASS) { 364 printf(" (ADB_CLASS)"); 365 } 366 printf("\n bInterfaceSubClass = %u", intr_desc.bInterfaceSubClass); 367 if (intr_desc.bInterfaceSubClass == ADB_SUBCLASS) { 368 printf(" (ADB_SUBCLASS)"); 369 } 370 printf("\n bInterfaceProtocol = %u", intr_desc.bInterfaceProtocol); 371 if (intr_desc.bInterfaceProtocol == ADB_PROTOCOL) { 372 printf(" (ADB_PROTOCOL)"); 373 } 374 printf("\n iInterface = %u", intr_desc.iInterface); 375 } else { 376 printf("\n--- AdbGetUsbInterfaceDescriptor failure %u", GetLastError()); 377 return false; 378 } 379 380 // Enumerate interface's endpoints 381 AdbEndpointInformation pipe_info; 382 for (UCHAR pipe = 0; pipe < intr_desc.bNumEndpoints; pipe++) { 383 if (AdbGetEndpointInformation(interface_handle, pipe, &pipe_info)) { 384 printf("\n PIPE %u info:", pipe); 385 DumpEndpointInformation(&pipe_info); 386 } else { 387 printf("\n--- AdbGetEndpointInformation(%u) failure %u", pipe, 388 GetLastError()); 389 return false; 390 } 391 } 392 393 // Get default bulk read endpoint info 394 if (AdbGetDefaultBulkReadEndpointInformation(interface_handle, &pipe_info)) { 395 printf("\n Default Bulk Read Pipe info:"); 396 DumpEndpointInformation(&pipe_info); 397 } else { 398 printf("\n--- AdbGetDefaultBulkReadEndpointInformation failure %u", 399 GetLastError()); 400 return false; 401 } 402 403 // Get default bulk write endpoint info 404 if (AdbGetDefaultBulkWriteEndpointInformation(interface_handle, &pipe_info)) { 405 printf("\n Default Bulk Write Pipe info:"); 406 DumpEndpointInformation(&pipe_info); 407 } else { 408 printf("\n--- AdbGetDefaultBulkWriteEndpointInformation failure %u", 409 GetLastError()); 410 return false; 411 } 412 413 // Test a handshake on that interface 414 DeviceHandShake(interface_handle); 415 416 return true; 417 } 418 419 void HexDump(const void* data, const size_t read_bytes) { 420 const unsigned char* buf = reinterpret_cast<const unsigned char*>(data); 421 const size_t line_length = 16; 422 for (size_t n = 0; n < read_bytes; n += line_length) { 423 const unsigned char* line = &buf[n]; 424 const size_t max_line = min(line_length, read_bytes - n); 425 426 printf("\n "); 427 for (size_t i = 0; i < line_length; ++i) { 428 if (i >= max_line) { 429 printf(" "); 430 } else { 431 printf("%02X ", line[i]); 432 } 433 } 434 printf(" "); 435 for (size_t i = 0; i < max_line; ++i) { 436 if (isprint(line[i])) { 437 printf("%c", line[i]); 438 } else { 439 printf("."); 440 } 441 } 442 } 443 } 444 445 void DumpMessageArg0(unsigned int command, unsigned int arg0) { 446 if (command == A_AUTH) { 447 const char* desc = NULL; 448 switch (arg0) { 449 #define CASE_ARG0(arg) case arg: desc = # arg; break 450 CASE_ARG0(ADB_AUTH_TOKEN); 451 CASE_ARG0(ADB_AUTH_SIGNATURE); 452 CASE_ARG0(ADB_AUTH_RSAPUBLICKEY); 453 #undef CASE_ARG0 454 } 455 if (desc != NULL) { 456 printf(" (%s)", desc); 457 } 458 } 459 } 460 461 bool DeviceHandShake(ADBAPIHANDLE adb_interface) { 462 // Get interface name 463 char interf_name[512]; 464 unsigned long name_size = sizeof(interf_name); 465 if (!AdbGetInterfaceName(adb_interface, interf_name, &name_size, true)) { 466 printf("\nDeviceHandShake: AdbGetInterfaceName returned error %u", 467 GetLastError()); 468 return false; 469 } 470 471 printf("\n\nDeviceHandShake on %s", interf_name); 472 473 char* ser_num = NULL; 474 name_size = 0; 475 if (!AdbGetSerialNumber(adb_interface, ser_num, &name_size, true)) { 476 ser_num = reinterpret_cast<char*>(malloc(name_size)); 477 if (NULL != ser_num) { 478 if (!AdbGetSerialNumber(adb_interface, ser_num, &name_size, true)) { 479 printf("\n AdbGetSerialNumber returned error %u", GetLastError()); 480 AdbCloseHandle(adb_interface); 481 return false; 482 } 483 printf("\nInterface serial number is %s", ser_num); 484 free(ser_num); 485 } 486 } 487 488 // Get default read endpoint 489 ADBAPIHANDLE adb_read = AdbOpenDefaultBulkReadEndpoint(adb_interface, 490 AdbOpenAccessTypeReadWrite, 491 AdbOpenSharingModeReadWrite); 492 if (NULL == adb_read) { 493 printf("\n AdbOpenDefaultBulkReadEndpoint returned error %u", GetLastError()); 494 return false; 495 } 496 497 // Get default write endpoint 498 ADBAPIHANDLE adb_write = AdbOpenDefaultBulkWriteEndpoint(adb_interface, 499 AdbOpenAccessTypeReadWrite, 500 AdbOpenSharingModeReadWrite); 501 if (NULL == adb_write) { 502 printf("\n AdbOpenDefaultBulkWriteEndpoint returned error %u", GetLastError()); 503 AdbCloseHandle(adb_read); 504 return false; 505 } 506 507 // Send connect message 508 message msg_send; 509 msg_send.command = A_CNXN; 510 msg_send.arg0 = A_VERSION; 511 msg_send.arg1 = MAX_PAYLOAD; 512 msg_send.data_length = 0; 513 msg_send.data_crc32 = 0; 514 msg_send.magic = msg_send.command ^ 0xffffffff; 515 516 ULONG written_bytes = 0; 517 bool write_res = AdbWriteEndpointSync(adb_write, &msg_send, sizeof(msg_send), &written_bytes, 500); 518 if (!write_res) { 519 printf("\n AdbWriteEndpointSync returned error %u", GetLastError()); 520 AdbCloseHandle(adb_write); 521 AdbCloseHandle(adb_read); 522 return false; 523 } 524 525 // Receive handshake 526 message msg_rcv; 527 ULONG read_bytes = 0; 528 bool read_res = AdbReadEndpointSync(adb_read, &msg_rcv, sizeof(msg_rcv), &read_bytes, 512); 529 if (!read_res) { 530 printf("\n AdbReadEndpointSync returned error %u", GetLastError()); 531 AdbCloseHandle(adb_write); 532 AdbCloseHandle(adb_read); 533 return false; 534 } 535 536 printf("\n Read handshake: %u bytes received", read_bytes); 537 char* cmd_ansi = reinterpret_cast<char*>(&msg_rcv.command); 538 printf("\n command = %08X (%c%c%c%c)", msg_rcv.command, 539 cmd_ansi[0], cmd_ansi[1], cmd_ansi[2], cmd_ansi[3]); 540 printf("\n arg0 = %08X", msg_rcv.arg0); 541 DumpMessageArg0(msg_rcv.command, msg_rcv.arg0); 542 printf("\n arg1 = %08X", msg_rcv.arg1); 543 printf("\n data_length = %u", msg_rcv.data_length); 544 printf("\n data_crc32 = %08X", msg_rcv.data_crc32); 545 printf("\n magic = %08X", msg_rcv.magic); 546 printf(" (%s)", (msg_rcv.magic == (msg_rcv.command ^ 0xffffffff)) ? 547 "valid" : "invalid"); 548 549 if (0 != msg_rcv.data_length) { 550 char* buf = reinterpret_cast<char*>(malloc(msg_rcv.data_length)); 551 read_res = AdbReadEndpointSync(adb_read, buf, msg_rcv.data_length, &read_bytes, 512); 552 if (!read_res) { 553 printf("\n AdbReadEndpointSync (data) returned error %u", GetLastError()); 554 free(buf); 555 AdbCloseHandle(adb_write); 556 AdbCloseHandle(adb_read); 557 return false; 558 } 559 560 HexDump(buf, read_bytes); 561 562 free(buf); 563 } 564 565 if (!AdbCloseHandle(adb_write)) { 566 printf("\n--- AdbCloseHandle failure %u", GetLastError()); 567 } 568 if (!AdbCloseHandle(adb_read)) { 569 printf("\n--- AdbCloseHandle failure %u", GetLastError()); 570 } 571 572 return true; 573 } 574 575 // Randomly delay the current thread. 576 class RandomDelayer { 577 public: 578 // Prepare for a call to Delay() by getting random data. This call might grab 579 // locks, causing serialization, so this should be called before 580 // time-sensitive code. 581 void SeedRandom() { 582 r_ = rand(); 583 } 584 585 // Randomly delay the current thread based on a previous call to SeedRandom(). 586 void Delay() { 587 switch (r_ % 5) { 588 case 0: 589 Sleep(0); // Give up time slice to another read-to-run thread. 590 break; 591 case 1: 592 // Try to sleep for 1 ms, but probably more based on OS scheduler 593 // minimum granularity. 594 Sleep(1); 595 break; 596 case 2: 597 // Yield to another thread ready-to-run on the current processor. 598 SwitchToThread(); 599 break; 600 case 3: 601 // Busy-wait for a random amount of time. 602 for (int i = 0; i < r_; ++i) { 603 GetLastError(); 604 } 605 break; 606 case 4: 607 break; // Do nothing, no delay. 608 } 609 } 610 611 private: 612 int r_; 613 }; 614 615 volatile ADBAPIHANDLE g_read_handle; 616 volatile ADBAPIHANDLE g_interface_handle; 617 volatile bool g_stop_close_race_thread; 618 619 unsigned __stdcall CloseRaceThread(void*) { 620 RandomDelayer r; 621 622 while (!g_stop_close_race_thread) { 623 r.SeedRandom(); 624 625 // Do volatile reads of both globals 626 ADBAPIHANDLE read_handle = g_read_handle; 627 ADBAPIHANDLE interface_handle = g_interface_handle; 628 629 // If we got both handles, close them and clear the globals 630 if (read_handle != NULL && interface_handle != NULL) { 631 // Delay random amount before calling the API that conflicts with 632 // Adb{Read,Write}EndpointSync(). 633 r.Delay(); 634 635 if (!AdbCloseHandle(read_handle)) { 636 printf("\nAdbCloseHandle(read) failure: %u", GetLastError()); 637 } 638 if (!AdbCloseHandle(interface_handle)) { 639 printf("\nAdbCloseHandle(interface) failure: %u", GetLastError()); 640 } 641 642 // Clear globals so that read thread is free to set them. 643 g_read_handle = NULL; 644 g_interface_handle = NULL; 645 } 646 } 647 return 0; 648 } 649 650 #define EXPECTED_ERROR_LIST(FOR_EACH) \ 651 FOR_EACH(ERROR_INVALID_HANDLE) \ 652 FOR_EACH(ERROR_HANDLES_CLOSED) \ 653 FOR_EACH(ERROR_OPERATION_ABORTED) 654 655 #define MAKE_ARRAY_ITEM(x) x, 656 const DWORD g_expected_errors[] = { 657 EXPECTED_ERROR_LIST(MAKE_ARRAY_ITEM) 658 }; 659 #undef MAKE_ARRAY_ITEM 660 661 #define MAKE_STRING_ITEM(x) #x, 662 const char* g_expected_error_strings[] = { 663 EXPECTED_ERROR_LIST(MAKE_STRING_ITEM) 664 }; 665 #undef MAKE_STRING_ITEM 666 667 std::string get_error_description(const DWORD err) { 668 const DWORD* end = g_expected_errors + ARRAYSIZE(g_expected_errors); 669 const DWORD* found = std::find(g_expected_errors, end, err); 670 if (found != end) { 671 return g_expected_error_strings[found - g_expected_errors]; 672 } else { 673 char buf[64]; 674 _snprintf(buf, sizeof(buf), "%u", err); 675 return std::string(buf); 676 } 677 } 678 679 bool is_expected_error(const DWORD err) { 680 const DWORD* end = g_expected_errors + ARRAYSIZE(g_expected_errors); 681 return std::find(g_expected_errors, end, err) != end; 682 } 683 684 // Test to reproduce https://code.google.com/p/android/issues/detail?id=161890 685 bool TestCloseRaceCondition() { 686 const DWORD test_duration_sec = 10; 687 printf("\nTesting close race condition for %u seconds... ", 688 test_duration_sec); 689 690 ADBAPIHANDLE enum_handle = 691 AdbEnumInterfaces(kAdbInterfaceId, true, true, true); 692 if (NULL == enum_handle) { 693 printf("\nUnable to enumerate ADB interfaces: %u", GetLastError()); 694 return false; 695 } 696 697 union { 698 AdbInterfaceInfo interface_info; 699 char buf[4096]; 700 }; 701 unsigned long buf_size = sizeof(buf); 702 703 // Get the first interface 704 if (!AdbNextInterface(enum_handle, &interface_info, &buf_size)) { 705 printf("\n--- AdbNextInterface failure %u", GetLastError()); 706 return false; 707 } 708 709 if (!AdbCloseHandle(enum_handle)) { 710 printf("\nAdbCloseHandle(enum_handle) failure: %u", GetLastError()); 711 } 712 713 HANDLE thread_handle = reinterpret_cast<HANDLE>( 714 _beginthreadex(NULL, 0, CloseRaceThread, NULL, 0, NULL)); 715 if (thread_handle == NULL) { 716 printf("\n--- _beginthreadex failure %u", errno); 717 return false; 718 } 719 720 // Run the test for 10 seconds. It usually reproduces the crash in 1 second. 721 const DWORD tick_start = GetTickCount(); 722 const DWORD test_duration_ticks = test_duration_sec * 1000; 723 RandomDelayer r; 724 725 std::map<DWORD, size_t> read_errors; 726 727 while (GetTickCount() < tick_start + test_duration_ticks) { 728 // Busy-wait until close thread has cleared the handles, so that we don't 729 // leak handles during the test. 730 while (g_read_handle != NULL) {} 731 while (g_interface_handle != NULL) {} 732 733 ADBAPIHANDLE interface_handle = AdbCreateInterfaceByName( 734 interface_info.device_name); 735 if (interface_handle == NULL) { 736 // Not really expected to encounter an error here. 737 printf("\n--- AdbCreateInterfaceByName failure %u", GetLastError()); 738 continue; // try again 739 } 740 ADBAPIHANDLE read_handle = AdbOpenDefaultBulkReadEndpoint( 741 interface_handle, AdbOpenAccessTypeReadWrite, 742 AdbOpenSharingModeReadWrite); 743 if (read_handle == NULL) { 744 // Not really expected to encounter an error here, so report, cleanup, 745 // and retry. 746 printf("\n--- AdbOpenDefaultBulkReadEndpoint failure %u", GetLastError()); 747 AdbCloseHandle(interface_handle); 748 continue; 749 } 750 751 r.SeedRandom(); 752 753 // Set handles to allow other thread to close them. 754 g_read_handle = read_handle; 755 g_interface_handle = interface_handle; 756 757 // Delay random amount before calling the API that conflicts with 758 // AdbCloseHandle(). 759 r.Delay(); 760 761 message msg_rcv; 762 ULONG read_bytes = 0; 763 764 while (AdbReadEndpointSync(read_handle, &msg_rcv, sizeof(msg_rcv), 765 &read_bytes, 0 /* infinite timeout */)) { 766 // Keep reading until a crash or we're broken out of the read 767 // (with an error) by the CloseRaceThread. 768 } 769 read_errors[GetLastError()]++; 770 } 771 772 g_stop_close_race_thread = true; 773 if (WaitForSingleObject(thread_handle, INFINITE) != WAIT_OBJECT_0) { 774 printf("\n--- WaitForSingleObject failure %u", GetLastError()); 775 } 776 if (!CloseHandle(thread_handle)) { 777 printf("\n--- CloseHandle failure %u", GetLastError()); 778 } 779 780 // The expected errors are the errors that would be encountered if the code 781 // had all the major concurrent interleavings. So the test only passes if 782 // we encountered all the expected errors, and thus stress tested all the 783 // possible major concurrent interleavings. 784 bool pass = true; 785 for (size_t i = 0; i < ARRAYSIZE(g_expected_errors); ++i) { 786 // If we didn't encounter the expected error code, then the test failed. 787 if (read_errors.count(g_expected_errors[i]) == 0) { 788 pass = false; 789 break; 790 } 791 } 792 793 if (pass) { 794 printf("passed"); 795 } else { 796 printf("failed."); 797 printf("\nPerhaps you just need to run the test longer or again."); 798 } 799 800 printf("\nRead Error Code\t\tCount"); 801 printf("\n============================="); 802 803 for (std::map<DWORD, size_t>::iterator it = read_errors.begin(); 804 it != read_errors.end(); ++it) { 805 printf("\n%s\t%u%s", get_error_description(it->first).c_str(), it->second, 806 is_expected_error(it->first) ? " (expected)" : ""); 807 } 808 809 for (size_t i = 0; i < ARRAYSIZE(g_expected_errors); ++i) { 810 if (read_errors.count(g_expected_errors[i]) == 0) { 811 printf("\n%s\t%u (was not encountered, but was expected)", 812 get_error_description(g_expected_errors[i]).c_str(), 0); 813 } 814 } 815 816 return pass; 817 } 818