OSDN Git Service

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