Home | History | Annotate | Download | only in adb_winapi_test
      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