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