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