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*/
39PFN_INSTWINUSBINTERFACE InstantiateWinUsbInterface = NULL;
40
41ADBAPIHANDLE __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
69bool __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
91bool __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
106ADBAPIHANDLE __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
142ADBAPIHANDLE __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
199bool __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
218bool __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
237bool __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
254bool __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
271bool __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
288bool __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
306bool __cdecl AdbGetDefaultBulkReadEndpointInformation(ADBAPIHANDLE adb_interface,
307                                              AdbEndpointInformation* info) {
308  return AdbGetEndpointInformation(adb_interface,
309                                   ADB_QUERY_BULK_READ_ENDPOINT_INDEX,
310                                   info);
311}
312
313bool __cdecl AdbGetDefaultBulkWriteEndpointInformation(ADBAPIHANDLE adb_interface,
314                                               AdbEndpointInformation* info) {
315  return AdbGetEndpointInformation(adb_interface,
316                                   ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX,
317                                   info);
318}
319
320ADBAPIHANDLE __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
340ADBAPIHANDLE __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
349ADBAPIHANDLE __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
358ADBAPIHANDLE __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
374bool __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
391ADBAPIHANDLE __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
416ADBAPIHANDLE __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
441bool __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
462bool __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
483bool __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
503bool __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
520bool __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