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