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