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 ¶m, 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