• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
_tmain(int argc,TCHAR * argv[],TCHAR * envp[])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 
TestEnumInterfaces()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 
TestInterfaces()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 
TestInterface(const wchar_t * device_name)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 
TestInterfaceName(ADBAPIHANDLE interface_handle)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 
DumpEndpointInformation(const AdbEndpointInformation * pipe_info)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 
TestInterfaceHandle(ADBAPIHANDLE interface_handle)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 
HexDump(const void * data,const size_t read_bytes)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 
DumpMessageArg0(unsigned int command,unsigned int arg0)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 
DeviceHandShake(ADBAPIHANDLE adb_interface)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.
SeedRandom()581   void SeedRandom() {
582     r_ = rand();
583   }
584 
585   // Randomly delay the current thread based on a previous call to SeedRandom().
Delay()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 
CloseRaceThread(void *)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 
get_error_description(const DWORD err)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 
is_expected_error(const DWORD err)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
TestCloseRaceCondition()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