• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2009 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 class AdbLegacyInterfaceObject
19    that encapsulates an interface on our USB device that is accessible
20  */
21  
22  #include "stdafx.h"
23  #include "adb_api_legacy.h"
24  #include "adb_legacy_interface.h"
25  #include "adb_legacy_endpoint_object.h"
26  
AdbLegacyInterfaceObject(const wchar_t * interf_name)27  AdbLegacyInterfaceObject::AdbLegacyInterfaceObject(const wchar_t* interf_name)
28      : AdbInterfaceObject(interf_name),
29        def_read_endpoint_(0xFF),
30        read_endpoint_id_(0xFF),
31        def_write_endpoint_(0xFF),
32        write_endpoint_id_(0xFF) {
33  }
34  
~AdbLegacyInterfaceObject()35  AdbLegacyInterfaceObject::~AdbLegacyInterfaceObject() {
36  }
37  
CreateHandle()38  ADBAPIHANDLE AdbLegacyInterfaceObject::CreateHandle() {
39    // Open USB device for this intefface
40    HANDLE usb_device_handle = CreateFile(interface_name().c_str(),
41                                          GENERIC_READ | GENERIC_WRITE,
42                                          FILE_SHARE_READ | FILE_SHARE_WRITE,
43                                          NULL,
44                                          OPEN_EXISTING,
45                                          0,
46                                          NULL);
47    if (INVALID_HANDLE_VALUE == usb_device_handle) {
48      return NULL;
49    }
50  
51    // Now, we ensured that our usb device / interface is up and running.
52    // Lets collect device, interface and pipe information
53    bool ok = true;
54    if (!CacheUsbDeviceDescriptor(usb_device_handle) ||
55        !CacheUsbConfigurationDescriptor(usb_device_handle) ||
56        !CacheUsbInterfaceDescriptor(usb_device_handle)) {
57      ok = false;
58    }
59  
60    // Preserve error accross handle close
61    ULONG error = ok ? NO_ERROR : GetLastError();
62  
63    ::CloseHandle(usb_device_handle);
64  
65    if (NO_ERROR != error) {
66      SetLastError(error);
67    }
68  
69    if (!ok) {
70      return false;
71    }
72  
73    // Save indexes and IDs for bulk read / write endpoints. We will use them to
74    // convert ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX and
75    // ADB_QUERY_BULK_READ_ENDPOINT_INDEX into actual endpoint indexes and IDs.
76    for (UCHAR endpoint = 0; endpoint < usb_interface_descriptor_.bNumEndpoints;
77         endpoint++) {
78      // Get endpoint information
79      AdbEndpointInformation pipe_info;
80      if (!GetEndpointInformation(endpoint, &pipe_info)) {
81        return false;
82      }
83  
84      if (AdbEndpointTypeBulk == pipe_info.endpoint_type) {
85        // This is a bulk endpoint. Cache its index and ID.
86        if (0 != (pipe_info.endpoint_address & USB_ENDPOINT_DIRECTION_MASK)) {
87          // Use this endpoint as default bulk read endpoint
88          ATLASSERT(0xFF == def_read_endpoint_);
89          def_read_endpoint_ = endpoint;
90          read_endpoint_id_ = pipe_info.endpoint_address;
91        } else {
92          // Use this endpoint as default bulk write endpoint
93          ATLASSERT(0xFF == def_write_endpoint_);
94          def_write_endpoint_ = endpoint;
95          write_endpoint_id_ = pipe_info.endpoint_address;
96        }
97      }
98    }
99  
100    return AdbObjectHandle::CreateHandle();
101  }
102  
GetSerialNumber(void * buffer,unsigned long * buffer_char_size,bool ansi)103  bool AdbLegacyInterfaceObject::GetSerialNumber(void* buffer,
104                                                 unsigned long* buffer_char_size,
105                                                 bool ansi) {
106    if (!IsOpened()) {
107      SetLastError(ERROR_INVALID_HANDLE);
108      return false;
109    }
110  
111    // Open USB device for this intefface
112    HANDLE usb_device_handle = CreateFile(interface_name().c_str(),
113                                          GENERIC_READ,
114                                          FILE_SHARE_READ | FILE_SHARE_WRITE,
115                                          NULL,
116                                          OPEN_EXISTING,
117                                          0,
118                                          NULL);
119    if (INVALID_HANDLE_VALUE == usb_device_handle) {
120      return NULL;
121    }
122  
123    WCHAR serial_number[512];
124  
125    // Send IOCTL
126    DWORD ret_bytes = 0;
127    BOOL ret = DeviceIoControl(usb_device_handle,
128                               ADB_IOCTL_GET_SERIAL_NUMBER,
129                               NULL, 0,
130                               serial_number, sizeof(serial_number),
131                               &ret_bytes,
132                               NULL);
133  
134    // Preserve error accross CloseHandle
135    ULONG error = ret ? NO_ERROR : GetLastError();
136  
137    ::CloseHandle(usb_device_handle);
138  
139    if (NO_ERROR != error) {
140      SetLastError(error);
141      return false;
142    }
143  
144    unsigned long str_len =
145      static_cast<unsigned long>(wcslen(serial_number) + 1);
146  
147    if ((NULL == buffer) || (*buffer_char_size < str_len)) {
148      *buffer_char_size = str_len;
149      SetLastError(ERROR_INSUFFICIENT_BUFFER);
150      return false;
151    }
152  
153    if (!ansi) {
154      // If user asked for wide char name just return it
155      wcscpy(reinterpret_cast<wchar_t*>(buffer), serial_number);
156      return true;
157    }
158  
159    // We need to convert name from wide char to ansi string
160    int res = WideCharToMultiByte(CP_ACP,
161                                  0,
162                                  serial_number,
163                                  static_cast<int>(str_len),
164                                  reinterpret_cast<PSTR>(buffer),
165                                  static_cast<int>(*buffer_char_size),
166                                  NULL,
167                                  NULL);
168    return (res != 0);
169  }
170  
GetEndpointInformation(UCHAR endpoint_index,AdbEndpointInformation * info)171  bool AdbLegacyInterfaceObject::GetEndpointInformation(
172      UCHAR endpoint_index,
173      AdbEndpointInformation* info) {
174    // Open USB device for this intefface
175    HANDLE usb_device_handle = CreateFile(interface_name().c_str(),
176                                          GENERIC_READ,
177                                          FILE_SHARE_READ | FILE_SHARE_WRITE,
178                                          NULL,
179                                          OPEN_EXISTING,
180                                          0,
181                                          NULL);
182    if (INVALID_HANDLE_VALUE == usb_device_handle) {
183      return NULL;
184    }
185  
186    // Init ICTL param
187    AdbQueryEndpointInformation param;
188    param.endpoint_index = endpoint_index;
189  
190    // Send IOCTL
191    DWORD ret_bytes = 0;
192    BOOL ret = DeviceIoControl(usb_device_handle,
193                               ADB_IOCTL_GET_ENDPOINT_INFORMATION,
194                               &param, sizeof(param),
195                               info, sizeof(AdbEndpointInformation),
196                               &ret_bytes,
197                               NULL);
198    ATLASSERT(!ret || (sizeof(AdbEndpointInformation) == ret_bytes));
199  
200    // Preserve error accross CloseHandle
201    ULONG error = ret ? NO_ERROR : GetLastError();
202  
203    ::CloseHandle(usb_device_handle);
204  
205    if (NO_ERROR != error) {
206      SetLastError(error);
207    }
208  
209    return ret ? true : false;
210  }
211  
OpenEndpoint(UCHAR endpoint_index,AdbOpenAccessType access_type,AdbOpenSharingMode sharing_mode)212  ADBAPIHANDLE AdbLegacyInterfaceObject::OpenEndpoint(
213      UCHAR endpoint_index,
214      AdbOpenAccessType access_type,
215      AdbOpenSharingMode sharing_mode) {
216    // Convert index into name and ID.
217    std::wstring endpoint_name;
218    UCHAR endpoint_id;
219  
220    try {
221      if ((ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index) ||
222          (def_read_endpoint_ == endpoint_index)) {
223        endpoint_name = DEVICE_BULK_READ_PIPE_NAME;
224        endpoint_id = read_endpoint_id_;
225        endpoint_index = def_read_endpoint_;
226      } else if ((ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX == endpoint_index) ||
227                 (def_write_endpoint_ == endpoint_index)) {
228        endpoint_name = DEVICE_BULK_WRITE_PIPE_NAME;
229        endpoint_id = write_endpoint_id_;
230        endpoint_index = def_write_endpoint_;
231      } else {
232        SetLastError(ERROR_INVALID_PARAMETER);
233        return false;
234      }
235    } catch (...) {
236      // We don't expect exceptions other than OOM thrown here.
237      SetLastError(ERROR_OUTOFMEMORY);
238      return NULL;
239    }
240  
241    return OpenEndpoint(endpoint_name.c_str(), endpoint_id, endpoint_index,
242                        access_type, sharing_mode);
243  }
244  
OpenEndpoint(const wchar_t * endpoint_name,UCHAR endpoint_id,UCHAR endpoint_index,AdbOpenAccessType access_type,AdbOpenSharingMode sharing_mode)245  ADBAPIHANDLE AdbLegacyInterfaceObject::OpenEndpoint(
246      const wchar_t* endpoint_name,
247      UCHAR endpoint_id,
248      UCHAR endpoint_index,
249      AdbOpenAccessType access_type,
250      AdbOpenSharingMode sharing_mode) {
251    if (!IsOpened()) {
252      SetLastError(ERROR_INVALID_HANDLE);
253      return false;
254    }
255  
256    AdbLegacyEndpointObject* adb_endpoint = NULL;
257  
258    try {
259      adb_endpoint =
260          new AdbLegacyEndpointObject(this, endpoint_id, endpoint_index);
261    } catch (...) {
262      // We don't expect exceptions other than OOM thrown here.
263      SetLastError(ERROR_OUTOFMEMORY);
264      return NULL;
265    }
266  
267    // Build full path to the object
268    std::wstring endpoint_path = interface_name();
269    endpoint_path += L"\\";
270    endpoint_path += endpoint_name;
271  
272    ADBAPIHANDLE ret = adb_endpoint->CreateHandle(endpoint_path.c_str(),
273                                                  access_type,
274                                                  sharing_mode);
275  
276    adb_endpoint->Release();
277  
278    return ret;
279  }
280  
CacheUsbDeviceDescriptor(HANDLE usb_device_handle)281  bool AdbLegacyInterfaceObject::CacheUsbDeviceDescriptor(
282      HANDLE usb_device_handle) {
283    DWORD ret_bytes = 0;
284    BOOL ret = DeviceIoControl(usb_device_handle,
285                               ADB_IOCTL_GET_USB_DEVICE_DESCRIPTOR,
286                               NULL, 0,
287                               &usb_device_descriptor_,
288                               sizeof(usb_device_descriptor_),
289                               &ret_bytes,
290                               NULL);
291    ATLASSERT(!ret || (sizeof(USB_DEVICE_DESCRIPTOR) == ret_bytes));
292  
293    return ret ? true : false;
294  }
295  
CacheUsbConfigurationDescriptor(HANDLE usb_device_handle)296  bool AdbLegacyInterfaceObject::CacheUsbConfigurationDescriptor(
297      HANDLE usb_device_handle) {
298    DWORD ret_bytes = 0;
299    BOOL ret = DeviceIoControl(usb_device_handle,
300                               ADB_IOCTL_GET_USB_CONFIGURATION_DESCRIPTOR,
301                               NULL, 0,
302                               &usb_config_descriptor_,
303                               sizeof(usb_config_descriptor_),
304                               &ret_bytes,
305                               NULL);
306    ATLASSERT(!ret || (sizeof(USB_CONFIGURATION_DESCRIPTOR) == ret_bytes));
307  
308    return ret ? true : false;
309  }
310  
CacheUsbInterfaceDescriptor(HANDLE usb_device_handle)311  bool AdbLegacyInterfaceObject::CacheUsbInterfaceDescriptor(
312      HANDLE usb_device_handle) {
313    DWORD ret_bytes = 0;
314    BOOL ret = DeviceIoControl(usb_device_handle,
315                               ADB_IOCTL_GET_USB_INTERFACE_DESCRIPTOR,
316                               NULL, 0,
317                               &usb_interface_descriptor_,
318                               sizeof(usb_interface_descriptor_),
319                               &ret_bytes,
320                               NULL);
321    ATLASSERT(!ret || (sizeof(USB_INTERFACE_DESCRIPTOR) == ret_bytes));
322  
323    return ret ? true : false;
324  }
325