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