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 AndroidUsbDeviceObject that
19 encapsulates an extension for KMDF device (FDO) object.
20 */
21 #pragma data_seg()
22 #pragma code_seg()
23
24 #include "precomp.h"
25 #include "android_usb_device_object.h"
26 #include "android_usb_file_object.h"
27 #include "android_usb_device_file_object.h"
28 #include "android_usb_pipe_file_object.h"
29 #include "android_usb_bulk_file_object.h"
30 #include "android_usb_interrupt_file_object.h"
31
32 #pragma data_seg()
33
34 /// Buffer for bulk read pipe name
35 const WCHAR bulk_read_pipe_str[] = L"\\" DEVICE_BULK_READ_PIPE_NAME;
36
37 /// Unicode string for bulk read pipe name
38 UNICODE_STRING bulk_read_pipe_name = {
39 sizeof(bulk_read_pipe_str) - sizeof(WCHAR),
40 sizeof(bulk_read_pipe_str) - sizeof(WCHAR),
41 const_cast<PWSTR>(bulk_read_pipe_str)
42 };
43
44 /// Buffer for bulk write pipe name
45 const WCHAR bulk_write_pipe_str[] = L"\\" DEVICE_BULK_WRITE_PIPE_NAME;
46
47 /// Unicode string for bulk write pipe name
48 UNICODE_STRING bulk_write_pipe_name = {
49 sizeof(bulk_write_pipe_str) - sizeof(WCHAR),
50 sizeof(bulk_write_pipe_str) - sizeof(WCHAR),
51 const_cast<PWSTR>(bulk_write_pipe_str)
52 };
53
54 /// Buffer for an index-based pipe name prefix
55 const WCHAR index_pipe_prefix_str[] = L"\\" DEVICE_PIPE_NAME_PREFIX;
56
57 /// Unicode string for index-based pipe name prefix
58 UNICODE_STRING index_pipe_prefix = {
59 sizeof(index_pipe_prefix_str) - sizeof(WCHAR),
60 sizeof(index_pipe_prefix_str) - sizeof(WCHAR),
61 const_cast<PWSTR>(index_pipe_prefix_str)
62 };
63
64 /// GUID that sets class ID for our device
65 const GUID android_guid = ANDROID_USB_CLASS_ID;
66
67 #pragma code_seg("PAGE")
68
AndroidUsbDeviceObject()69 AndroidUsbDeviceObject::AndroidUsbDeviceObject()
70 : AndroidUsbWdfObject(AndroidUsbWdfObjectTypeDevice),
71 wdf_target_device_(NULL),
72 wdf_usb_interface_(NULL),
73 serial_number_handle_(NULL),
74 serial_number_char_len_(0),
75 configured_pipes_num_(0),
76 bulk_read_pipe_index_(INVALID_UCHAR),
77 bulk_write_pipe_index_(INVALID_UCHAR),
78 configuration_descriptor_(NULL) {
79 ASSERT_IRQL_PASSIVE();
80 }
81
82 #pragma code_seg()
83
~AndroidUsbDeviceObject()84 AndroidUsbDeviceObject::~AndroidUsbDeviceObject() {
85 ASSERT_IRQL_LOW_OR_DISPATCH();
86 if (NULL != serial_number_handle_)
87 WdfObjectDelete(serial_number_handle_);
88 }
89
90 #pragma code_seg("PAGE")
91
CreateFDODevice(PWDFDEVICE_INIT device_init)92 NTSTATUS AndroidUsbDeviceObject::CreateFDODevice(PWDFDEVICE_INIT device_init) {
93 ASSERT_IRQL_PASSIVE();
94
95 ASSERT(!IsTaretDeviceCreated());
96 if (IsTaretDeviceCreated())
97 return STATUS_INTERNAL_ERROR;
98
99 // Initialize our object attributes first
100 WDF_OBJECT_ATTRIBUTES device_attr;
101 NTSTATUS status = InitObjectAttributes(&device_attr, NULL);
102 ASSERT(NT_SUCCESS(status));
103 if (!NT_SUCCESS(status))
104 return status;
105
106 // Initialize the pnp_power_callbacks structure. Callback events for PnP
107 // and Power are specified here. If we don't supply any callbacks, the
108 // KMDF will take appropriate default actions for an FDO device object.
109 // EvtDevicePrepareHardware and EvtDeviceReleaseHardware are major entry
110 // points for initializing / cleaning up our device. Probably, we can leave
111 // the rest to the framework.
112 WDF_PNPPOWER_EVENT_CALLBACKS pnp_power_callbacks;
113 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnp_power_callbacks);
114 pnp_power_callbacks.EvtDevicePrepareHardware =
115 EvtDevicePrepareHardwareEntry;
116 pnp_power_callbacks.EvtDeviceReleaseHardware =
117 EvtDeviceReleaseHardwareEntry;
118 WdfDeviceInitSetPnpPowerEventCallbacks(device_init, &pnp_power_callbacks);
119
120 // Initialize the request attributes to specify the context size and type
121 // for every request created by framework for this device.
122 WDF_OBJECT_ATTRIBUTES request_attr;
123 WDF_OBJECT_ATTRIBUTES_INIT(&request_attr);
124 WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&request_attr, AndroidUsbWdfRequestContext);
125 WdfDeviceInitSetRequestAttributes(device_init, &request_attr);
126
127 // Initialize WDF_FILEOBJECT_CONFIG_INIT struct to tell the KMDF that we are
128 // interested in handling Create requests that get genereated when an
129 // application or another kernel component opens a handle through the device.
130 // We are not interested in receiving cleanup / close IRPs at this point.
131 WDF_FILEOBJECT_CONFIG file_config;
132 WDF_OBJECT_ATTRIBUTES file_attr;
133 WDF_FILEOBJECT_CONFIG_INIT(&file_config,
134 EvtDeviceFileCreateEntry,
135 WDF_NO_EVENT_CALLBACK,
136 WDF_NO_EVENT_CALLBACK);
137 WDF_OBJECT_ATTRIBUTES_INIT(&file_attr);
138 WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&file_attr,
139 AndroidUsbWdfObjectContext);
140 file_attr.EvtCleanupCallback = AndroidUsbWdfObject::EvtCleanupCallbackEntry;
141 file_attr.EvtDestroyCallback = AndroidUsbWdfObject::EvtDestroyCallbackEntry;
142 // We will provide our own synchronization for file access
143 file_attr.SynchronizationScope = WdfSynchronizationScopeNone;
144 WdfDeviceInitSetFileObjectConfig(device_init, &file_config, &file_attr);
145
146 // I/O type is buffered by default. It could be very inefficient if we have
147 // large reads / writes through our device.
148 WdfDeviceInitSetIoType(device_init, WdfDeviceIoDirect);
149
150 // DeviceInit is completely initialized. So call the framework
151 // to create the device and attach it to the lower stack.
152 WDFDEVICE wdf_dev = NULL;
153 status = WdfDeviceCreate(&device_init, &device_attr, &wdf_dev);
154 ASSERT(NT_SUCCESS(status) && (NULL != wdf_dev));
155 if (!NT_SUCCESS(status))
156 return status;
157
158 // Save handle to the created device
159 set_wdf_object(wdf_dev);
160
161 // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so
162 // that we don't get the popup in usermode (on Win2K) when we surprise
163 // remove the device.
164 WDF_DEVICE_PNP_CAPABILITIES pnp_caps;
165 WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnp_caps);
166 pnp_caps.SurpriseRemovalOK = WdfTrue;
167 WdfDeviceSetPnpCapabilities(wdf_device(), &pnp_caps);
168
169 // Create our default queue object for this device to start receiving I/O
170 status = CreateDefaultQueue();
171 ASSERT(NT_SUCCESS(status));
172 if (!NT_SUCCESS(status))
173 return status;
174
175 // Register a device interface so that app can find our device and talk to it.
176 status = WdfDeviceCreateDeviceInterface(wdf_device(), &android_guid, NULL);
177 ASSERT(NT_SUCCESS(status));
178 if (!NT_SUCCESS(status))
179 return status;
180
181 // Initialize our extension to that device. We will do this at the very end
182 // so we know that we successfully passed entire device create chain when
183 // we are called with other callbacks to that device.
184 status = InitializeContext();
185 ASSERT(NT_SUCCESS(status));
186 if (!NT_SUCCESS(status))
187 return status;
188
189 return STATUS_SUCCESS;
190 }
191
ResetDevice()192 NTSTATUS AndroidUsbDeviceObject::ResetDevice() {
193 ASSERT_IRQL_PASSIVE();
194
195 if (!IsTaretDeviceCreated())
196 return STATUS_SUCCESS;
197
198 // Reset the device
199 NTSTATUS status =
200 status = WdfUsbTargetDeviceResetPortSynchronously(wdf_target_device());
201
202 // !!!!! Note that after the call to WdfUsbTargetDeviceResetPortSynchronously
203 // this object may be no longer valid !!!!!
204
205 if (!NT_SUCCESS(status))
206 GoogleDbgPrint("\n!!!!! AndroidUsbDeviceObject::ResetDevice failed %X", status);
207
208 return status;
209 }
210
OnEvtDevicePrepareHardware(WDFCMRESLIST resources_raw,WDFCMRESLIST resources_translated)211 NTSTATUS AndroidUsbDeviceObject::OnEvtDevicePrepareHardware(
212 WDFCMRESLIST resources_raw,
213 WDFCMRESLIST resources_translated) {
214 ASSERT_IRQL_PASSIVE();
215
216 // Create a USB device handle so that we can communicate with the underlying
217 // USB stack. The wdf_target_device_ handle is used to query, configure, and
218 // manage all aspects of the USB device. These aspects include device
219 // properties, bus properties, and I/O creation and synchronization. This
220 // call gets the device and configuration descriptors and stores them in
221 // wdf_target_device_ object.
222 NTSTATUS status = WdfUsbTargetDeviceCreate(wdf_device(),
223 WDF_NO_OBJECT_ATTRIBUTES,
224 &wdf_target_device_);
225 ASSERT(NT_SUCCESS(status) && (NULL != wdf_target_device_));
226 if (!NT_SUCCESS(status))
227 return status;
228
229 // Retrieve USBD version information, port driver capabilites and device
230 // capabilites such as speed, power, etc.
231 WDF_USB_DEVICE_INFORMATION_INIT(&usb_device_info_);
232 status = WdfUsbTargetDeviceRetrieveInformation(wdf_target_device(),
233 &usb_device_info_);
234 ASSERT(NT_SUCCESS(status));
235 if (!NT_SUCCESS(status))
236 return status;
237
238 WdfUsbTargetDeviceGetDeviceDescriptor(wdf_target_device(),
239 &usb_device_descriptor_);
240 #if DBG
241 PrintUsbTargedDeviceInformation(usb_device_info());
242 PrintUsbDeviceDescriptor(&usb_device_descriptor_);
243 #endif // DBG
244
245 // Save device serial number
246 status =
247
248 WdfUsbTargetDeviceAllocAndQueryString(wdf_target_device(),
249
250 WDF_NO_OBJECT_ATTRIBUTES,
251
252 &serial_number_handle_,
253
254 &serial_number_char_len_,
255
256 usb_device_descriptor_.iSerialNumber,
257
258 0x0409); // English (US)
259
260 if (!NT_SUCCESS(status))
261
262 return status;
263
264
265
266 #if DBG
267
268 UNICODE_STRING ser_num;
269
270 ser_num.Length = serial_number_byte_len();
271
272 ser_num.MaximumLength = ser_num.Length;
273
274 ser_num.Buffer = const_cast<WCHAR*>
275
276 (serial_number());
277
278 GoogleDbgPrint("\n*** Device serial number %wZ", &ser_num);
279
280 #endif // DBG
281
282
283
284 // Configure our device now
285 status = ConfigureDevice();
286 ASSERT(NT_SUCCESS(status));
287 if (!NT_SUCCESS(status))
288 return status;
289
290 // Select device interfaces
291 status = SelectInterfaces();
292 if (!NT_SUCCESS(status))
293 return status;
294
295 return status;
296 }
297
298 NTSTATUS AndroidUsbDeviceObject::OnEvtDeviceReleaseHardware(
299 WDFCMRESLIST resources_translated) {
300 ASSERT_IRQL_PASSIVE();
301
302 // It's possible that Preparehardware failed half way thru. So make
303 // sure the target device exists.
304 if (!IsTaretDeviceCreated())
OnEvtDeviceFileCreate(WDFREQUEST request,WDFFILEOBJECT wdf_fo)305 return STATUS_SUCCESS;
306
307 // Cancel all the currently queued I/O. This is better than sending an
308 // explicit USB abort request down because release hardware gets
309 // called even when the device surprise-removed.
310 WdfIoTargetStop(WdfUsbTargetDeviceGetIoTarget(wdf_target_device()),
311 WdfIoTargetCancelSentIo);
312
313 // Unselect all selected configurations
314 WDF_USB_DEVICE_SELECT_CONFIG_PARAMS config_params;
315 WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_DECONFIG(&config_params);
316
317 NTSTATUS status = WdfUsbTargetDeviceSelectConfig(wdf_target_device(),
318 WDF_NO_OBJECT_ATTRIBUTES,
319 &config_params);
320 ASSERT(NT_SUCCESS(status) || (STATUS_DEVICE_NOT_CONNECTED == status));
321 return status;
322 }
323
324 void AndroidUsbDeviceObject::OnEvtDeviceFileCreate(WDFREQUEST request,
325 WDFFILEOBJECT wdf_fo) {
326 ASSERT_IRQL_PASSIVE();
327 ASSERT(IsInterfaceSelected());
328 if (!IsInterfaceSelected()) {
329 WdfRequestComplete(request, STATUS_INVALID_DEVICE_STATE);
330 return;
331 }
332
333 PUNICODE_STRING file_name = WdfFileObjectGetFileName(wdf_fo);
334 ASSERT(NULL != file_name);
335 if (NULL == file_name) {
336 WdfRequestComplete(request, STATUS_OBJECT_NAME_INVALID);
337 return;
338 }
339
340 WDFUSBPIPE wdf_pipe_obj = NULL;
341 WDF_USB_PIPE_INFORMATION pipe_info;
342
343 // TODO: Share / access check here?
344
345 // Lets see if this is a device open
346 if (0 != file_name->Length) {
347 // This is a pipe open. Lets retrieve pipe index from the name
348 UCHAR pipe_index = GetPipeIndexFromFileName(file_name);
349 if (INVALID_UCHAR == pipe_index) {
350 GoogleDbgPrint("\n!!!!! There is no pipe index for file %wZ", file_name);
351 WdfRequestComplete(request, STATUS_OBJECT_NAME_INVALID);
352 return;
353 }
354
355 // Make sure that pipe index doesn't exceed number of pipes
356 if (pipe_index >= configured_pipes_num()) {
357 WdfRequestComplete(request, STATUS_OBJECT_NAME_NOT_FOUND);
358 return;
359 }
360
361 // Retrieve the pipe along with the pipe info
362 WDF_USB_PIPE_INFORMATION_INIT(&pipe_info);
363 wdf_pipe_obj = WdfUsbInterfaceGetConfiguredPipe(wdf_usb_interface(),
364 pipe_index,
365 &pipe_info);
366 if (NULL == wdf_pipe_obj) {
367 GoogleDbgPrint("\n!!!!! There is no pipe for index %u for file %wZ",
368 pipe_index, file_name);
369 WdfRequestComplete(request, STATUS_OBJECT_NAME_NOT_FOUND);
370 return;
371 }
372 }
373
374 // If we're here this must be either device open or pipe open
375 ASSERT((NULL != wdf_pipe_obj) || (0 == file_name->Length));
376
377 // Create our file object extension for this file
378 AndroidUsbFileObject* wdf_file_ext = NULL;
379 NTSTATUS status;
380
381 if (0 == file_name->Length) {
382 // This is a device FO. Create wrapper for device FO
383 ASSERT(NULL == wdf_pipe_obj);
384 wdf_file_ext = new(NonPagedPool, GANDR_POOL_TAG_DEVICE_FO)
385 AndroidUsbDeviceFileObject(this, wdf_fo);
386 ASSERT(NULL != wdf_file_ext);
387 if (NULL == wdf_file_ext) {
388 WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
389 return;
390 }
391
392 // Initialize extension
393 status = wdf_file_ext->Initialize();
EvtDevicePrepareHardwareEntry(WDFDEVICE wdf_dev,WDFCMRESLIST resources_raw,WDFCMRESLIST resources_translated)394 if (!NT_SUCCESS(status)) {
395 delete wdf_file_ext;
396 WdfRequestComplete(request, status);
397 return;
398 }
399 } else {
400 // This is a pipe file. Create and initialize appropriate extension for it.
401 status =
402 CreatePipeFileObjectExt(wdf_fo, wdf_pipe_obj, &pipe_info, &wdf_file_ext);
403 ASSERT((NULL != wdf_file_ext) || !NT_SUCCESS(status));
404 if (!NT_SUCCESS(status)) {
405 WdfRequestComplete(request, status);
406 return;
407 }
408 }
409 ASSERT(GetAndroidUsbFileObjectFromHandle(wdf_fo) == wdf_file_ext);
EvtDeviceReleaseHardwareEntry(WDFDEVICE wdf_dev,WDFCMRESLIST resources_translated)410 WdfRequestComplete(request, STATUS_SUCCESS);
411 }
412
413 NTSTATUS AndroidUsbDeviceObject::EvtDevicePrepareHardwareEntry(
414 WDFDEVICE wdf_dev,
415 WDFCMRESLIST resources_raw,
416 WDFCMRESLIST resources_translated) {
417 ASSERT_IRQL_PASSIVE();
418
419 // Get our wrapper for the device and redirect event to its handler
420 AndroidUsbDeviceObject* wdf_device_ext =
421 GetAndroidUsbDeviceObjectFromHandle(wdf_dev);
422 ASSERT(NULL != wdf_device_ext);
423 return (NULL != wdf_device_ext) ?
EvtDeviceFileCreateEntry(WDFDEVICE wdf_dev,WDFREQUEST request,WDFFILEOBJECT wdf_fo)424 wdf_device_ext->OnEvtDevicePrepareHardware(resources_raw,
425 resources_translated) :
426 STATUS_INVALID_DEVICE_REQUEST;
427 }
428
429 NTSTATUS AndroidUsbDeviceObject::EvtDeviceReleaseHardwareEntry(
430 WDFDEVICE wdf_dev,
431 WDFCMRESLIST resources_translated) {
432 ASSERT_IRQL_PASSIVE();
433
434 // Get our wrapper for the device and redirect event to its handler
435 AndroidUsbDeviceObject* wdf_device_ext =
436 GetAndroidUsbDeviceObjectFromHandle(wdf_dev);
437 ASSERT(NULL != wdf_device_ext);
438 return (NULL != wdf_device_ext) ?
439 wdf_device_ext->OnEvtDeviceReleaseHardware(resources_translated) :
440 STATUS_INVALID_DEVICE_REQUEST;
441 }
442
443 void AndroidUsbDeviceObject::EvtDeviceFileCreateEntry(
444 WDFDEVICE wdf_dev,
445 WDFREQUEST request,
446 WDFFILEOBJECT wdf_fo) {
447 ASSERT_IRQL_PASSIVE();
448
OnEvtIoRead(WDFREQUEST request,size_t length)449 ASSERT(NULL != wdf_fo);
450 if (NULL == wdf_fo) {
451 WdfRequestComplete(request, STATUS_INVALID_PARAMETER);
452 return;
453 }
454
455 // Get our wrapper for the device and redirect event to its handler
456 AndroidUsbDeviceObject* wdf_device_ext =
457 GetAndroidUsbDeviceObjectFromHandle(wdf_dev);
458 ASSERT(NULL != wdf_device_ext);
459 if (NULL != wdf_device_ext) {
460 wdf_device_ext->OnEvtDeviceFileCreate(request, wdf_fo);
461 } else {
462 WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
463 }
464 }
465
466 #pragma code_seg()
467
468 void AndroidUsbDeviceObject::OnEvtIoRead(WDFREQUEST request,
OnEvtIoWrite(WDFREQUEST request,size_t length)469 size_t length) {
470 ASSERT_IRQL_LOW_OR_DISPATCH();
471 ASSERT(IsInterfaceSelected());
472 if (!IsInterfaceSelected()) {
473 WdfRequestComplete(request, STATUS_INVALID_DEVICE_STATE);
474 return;
475 }
476
477 // Get our file extension and dispatch this event to its handler
478 AndroidUsbFileObject* wdf_file_ext =
479 GetAndroidUsbFileObjectForRequest(request);
480 ASSERT(NULL != wdf_file_ext);
481 if (NULL != wdf_file_ext) {
482 wdf_file_ext->OnEvtIoRead(request, length);
483 } else {
484 WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
485 }
486 }
487
488 void AndroidUsbDeviceObject::OnEvtIoWrite(WDFREQUEST request,
OnEvtIoDeviceControl(WDFREQUEST request,size_t output_buf_len,size_t input_buf_len,ULONG ioctl_code)489 size_t length) {
490 ASSERT_IRQL_LOW_OR_DISPATCH();
491 ASSERT(IsInterfaceSelected());
492 if (!IsInterfaceSelected()) {
493 WdfRequestComplete(request, STATUS_INVALID_DEVICE_STATE);
494 return;
495 }
496
497 // Get our file extension and dispatch this event to its handler
498 AndroidUsbFileObject* wdf_file_ext =
499 GetAndroidUsbFileObjectForRequest(request);
500 ASSERT(NULL != wdf_file_ext);
501 if (NULL != wdf_file_ext) {
502 wdf_file_ext->OnEvtIoWrite(request, length);
503 } else {
504 WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
505 }
506 }
507
508 void AndroidUsbDeviceObject::OnEvtIoDeviceControl(WDFREQUEST request,
509 size_t output_buf_len,
510 size_t input_buf_len,
511 ULONG ioctl_code) {
512 ASSERT_IRQL_LOW_OR_DISPATCH();
513 ASSERT(IsInterfaceSelected());
EvtIoReadEntry(WDFQUEUE queue,WDFREQUEST request,size_t length)514 if (!IsInterfaceSelected()) {
515 WdfRequestComplete(request, STATUS_INVALID_DEVICE_STATE);
516 return;
517 }
518
519 // Get our file extension and dispatch this event to its handler
520 AndroidUsbFileObject* wdf_file_ext =
521 GetAndroidUsbFileObjectForRequest(request);
522 ASSERT(NULL != wdf_file_ext);
523 if (NULL != wdf_file_ext) {
524 wdf_file_ext->OnEvtIoDeviceControl(request,
525 output_buf_len,
526 input_buf_len,
527 ioctl_code);
528 } else {
529 WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
530 }
EvtIoWriteEntry(WDFQUEUE queue,WDFREQUEST request,size_t length)531 }
532
533 void AndroidUsbDeviceObject::EvtIoReadEntry(WDFQUEUE queue,
534 WDFREQUEST request,
535 size_t length) {
536 ASSERT_IRQL_LOW_OR_DISPATCH();
537
538 // Get our file extension and dispatch this event to the appropriate handler
539 // inside our device extension.
540 AndroidUsbFileObject* wdf_file_ext =
541 GetAndroidUsbFileObjectForRequest(request);
542 ASSERT(NULL != wdf_file_ext);
543 if (NULL != wdf_file_ext) {
544 wdf_file_ext->device_object()->OnEvtIoRead(request, length);
545 } else {
546 WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
547 }
548 }
549
550 void AndroidUsbDeviceObject::EvtIoWriteEntry(WDFQUEUE queue,
551 WDFREQUEST request,
552 size_t length) {
553 ASSERT_IRQL_LOW_OR_DISPATCH();
554
555 // Get our file extension and dispatch this event to the appropriate handler
556 // inside our device extension.
557 AndroidUsbFileObject* wdf_file_ext =
558 GetAndroidUsbFileObjectForRequest(request);
559 ASSERT(NULL != wdf_file_ext);
560 if (NULL != wdf_file_ext) {
561 wdf_file_ext->device_object()->OnEvtIoWrite(request, length);
562 } else {
563 WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
564 }
565 }
566
567 void AndroidUsbDeviceObject::EvtIoDeviceControlEntry(WDFQUEUE queue,
568 WDFREQUEST request,
569 size_t output_buf_len,
OnGetUsbDeviceDescriptorCtl(WDFREQUEST request,size_t output_buf_len)570 size_t input_buf_len,
571 ULONG ioctl_code) {
572 ASSERT_IRQL_LOW_OR_DISPATCH();
573
574 // Get our file extension and dispatch this event to the appropriate handler
575 // inside our device extension.
576 AndroidUsbFileObject* wdf_file_ext =
577 GetAndroidUsbFileObjectForRequest(request);
578 ASSERT(NULL != wdf_file_ext);
579 if (NULL != wdf_file_ext) {
580 wdf_file_ext->device_object()->OnEvtIoDeviceControl(request,
581 output_buf_len,
582 input_buf_len,
583 ioctl_code);
584 } else {
585 WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
586 }
587 }
588
589 void AndroidUsbDeviceObject::OnGetUsbDeviceDescriptorCtl(WDFREQUEST request,
590 size_t output_buf_len) {
591 ASSERT_IRQL_LOW_OR_DISPATCH();
592
593 // Check the buffer first
594 if (output_buf_len >= sizeof(USB_DEVICE_DESCRIPTOR)) {
595 // Get the output buffer
596 NTSTATUS status;
597 void* ret_info = OutAddress(request, &status);
598 ASSERT(NT_SUCCESS(status) && (NULL != ret_info));
OnGetUsbConfigDescriptorCtl(WDFREQUEST request,size_t output_buf_len)599 if (NT_SUCCESS(status)) {
600 // Copy requested info into output buffer and complete request
601 RtlCopyMemory(ret_info,
602 usb_device_descriptor(),
603 sizeof(USB_DEVICE_DESCRIPTOR));
604
605 WdfRequestCompleteWithInformation(request,
606 STATUS_SUCCESS,
607 sizeof(USB_DEVICE_DESCRIPTOR));
608 } else {
609 WdfRequestComplete(request, status);
610 }
611 } else {
612 WdfRequestCompleteWithInformation(request,
613 STATUS_BUFFER_TOO_SMALL,
614 sizeof(USB_DEVICE_DESCRIPTOR));
615 }
616 }
617
618 void AndroidUsbDeviceObject::OnGetUsbConfigDescriptorCtl(WDFREQUEST request,
619 size_t output_buf_len) {
620 ASSERT_IRQL_LOW_OR_DISPATCH();
621
622 if (NULL != configuration_descriptor()) {
623 // Check the buffer first
624 if (output_buf_len >= sizeof(USB_CONFIGURATION_DESCRIPTOR)) {
625 // Get the output buffer
626 NTSTATUS status;
627 void* ret_info = OutAddress(request, &status);
628 ASSERT(NT_SUCCESS(status) && (NULL != ret_info));
629 if (NT_SUCCESS(status)) {
630 // Copy requested info into output buffer and complete request
631 RtlCopyMemory(ret_info,
OnGetUsbInterfaceDescriptorCtl(WDFREQUEST request,size_t output_buf_len)632 configuration_descriptor(),
633 sizeof(USB_CONFIGURATION_DESCRIPTOR));
634
635 WdfRequestCompleteWithInformation(request,
636 STATUS_SUCCESS,
637 sizeof(USB_CONFIGURATION_DESCRIPTOR));
638 } else {
639 WdfRequestComplete(request, status);
640 }
641 } else {
642 WdfRequestCompleteWithInformation(request,
643 STATUS_BUFFER_TOO_SMALL,
644 sizeof(USB_CONFIGURATION_DESCRIPTOR));
645 }
646 } else {
647 WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
648 }
649 }
650
651 void AndroidUsbDeviceObject::OnGetUsbInterfaceDescriptorCtl(WDFREQUEST request,
652 size_t output_buf_len) {
653 ASSERT_IRQL_LOW_OR_DISPATCH();
654
655 // Check the buffer first
656 if (output_buf_len >= sizeof(USB_INTERFACE_DESCRIPTOR)) {
657 // Get the output buffer
658 NTSTATUS status;
659 void* ret_info = OutAddress(request, &status);
660 ASSERT(NT_SUCCESS(status) && (NULL != ret_info));
OnGetEndpointInformationCtl(WDFREQUEST request,size_t input_buf_len,size_t output_buf_len)661 if (NT_SUCCESS(status)) {
662 // Copy requested info into output buffer and complete request
663 RtlCopyMemory(ret_info,
664 interface_descriptor(),
665 sizeof(USB_INTERFACE_DESCRIPTOR));
666
667 WdfRequestCompleteWithInformation(request,
668 STATUS_SUCCESS,
669 sizeof(USB_INTERFACE_DESCRIPTOR));
670 } else {
671 WdfRequestComplete(request, status);
672 }
673 } else {
674 WdfRequestCompleteWithInformation(request,
675 STATUS_BUFFER_TOO_SMALL,
676 sizeof(USB_INTERFACE_DESCRIPTOR));
677 }
678 }
679
680 void AndroidUsbDeviceObject::OnGetEndpointInformationCtl(
681 WDFREQUEST request,
682 size_t input_buf_len,
683 size_t output_buf_len) {
684 ASSERT_IRQL_LOW_OR_DISPATCH();
685
686 // Check the buffers first
687 if (input_buf_len < sizeof(AdbQueryEndpointInformation)) {
688 WdfRequestComplete(request, STATUS_INVALID_BUFFER_SIZE);
689 return;
690 }
691
692 if (output_buf_len < sizeof(AdbEndpointInformation)) {
693 WdfRequestCompleteWithInformation(request,
694 STATUS_BUFFER_TOO_SMALL,
695 sizeof(AdbEndpointInformation));
696 return;
697 }
698
699 // Get the output buffer
700 NTSTATUS status;
701 AdbEndpointInformation* ret_info = reinterpret_cast<AdbEndpointInformation*>
702 (OutAddress(request, &status));
703 ASSERT(NT_SUCCESS(status) && (NULL != ret_info));
704 if (!NT_SUCCESS(status)) {
705 WdfRequestComplete(request, status);
706 return;
707 }
708
709 // Get the input buffer
710 AdbQueryEndpointInformation* in = reinterpret_cast<AdbQueryEndpointInformation*>
711 (InAddress(request, &status));
712 ASSERT(NT_SUCCESS(status) && (NULL != in));
713 if (!NT_SUCCESS(status)) {
714 WdfRequestComplete(request, status);
715 return;
716 }
717
718 // Lets see what exactly is queried
719 UCHAR endpoint_index = in->endpoint_index;
720 if (ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX == endpoint_index)
721 endpoint_index = bulk_write_pipe_index();
722 else if (ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index)
723 endpoint_index = bulk_read_pipe_index();
724
725 // Make sure index is valid and within interface range
726 if ((INVALID_UCHAR == endpoint_index) ||
727 (endpoint_index >= configured_pipes_num())) {
728 WdfRequestComplete(request, STATUS_NOT_FOUND);
729 return;
730 }
731
732 // Get endpoint information
733 WDF_USB_PIPE_INFORMATION pipe_info;
734 WDF_USB_PIPE_INFORMATION_INIT(&pipe_info);
735 WDFUSBPIPE wdf_pipe_obj =
OnGetSerialNumberCtl(WDFREQUEST request,size_t output_buf_len)736 WdfUsbInterfaceGetConfiguredPipe(wdf_usb_interface(), endpoint_index, &pipe_info);
737 if (NULL == wdf_pipe_obj) {
738 WdfRequestComplete(request, STATUS_NOT_FOUND);
739 return;
740 }
741
742 // Copy endpoint info to the output
743 ret_info->max_packet_size = pipe_info.MaximumPacketSize;
744 ret_info->endpoint_address = pipe_info.EndpointAddress;
745 ret_info->polling_interval = pipe_info.Interval;
746 ret_info->setting_index = pipe_info.SettingIndex;
747 ret_info->endpoint_type = static_cast<AdbEndpointType>(pipe_info.PipeType);
748 ret_info->max_transfer_size = pipe_info.MaximumTransferSize;
749
750 WdfRequestCompleteWithInformation(request,
751 STATUS_SUCCESS,
752 sizeof(AdbEndpointInformation));
753 }
754
755 void AndroidUsbDeviceObject::OnGetSerialNumberCtl(WDFREQUEST request,
756 size_t output_buf_len) {
757 ASSERT_IRQL_LOW();
758
759 if (NULL == serial_number()) {
760 // There is no serial number saved for this device!
761 WdfRequestComplete(request, STATUS_INTERNAL_ERROR);
762 return;
763 }
764
765 size_t expected_len = serial_number_byte_len() + sizeof(WCHAR);
766
767 // Check the buffer first
768 if (output_buf_len >= expected_len) {
769 // Get the output buffer
770 NTSTATUS status;
CreateDefaultQueue()771 WCHAR* ret_info = reinterpret_cast<WCHAR*>(OutAddress(request, &status));
772 ASSERT(NT_SUCCESS(status) && (NULL != ret_info));
773 if (NT_SUCCESS(status)) {
774 // Copy serial number
775 RtlCopyMemory(ret_info, serial_number(), serial_number_byte_len());
776 ret_info[serial_number_char_len()] = L'\0';
777 WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, expected_len);
778 } else {
779 WdfRequestComplete(request, status);
780 }
781 } else {
782 WdfRequestCompleteWithInformation(request,
783 STATUS_BUFFER_TOO_SMALL,
784 sizeof(expected_len));
785 }
786 }
787
788 #pragma code_seg("PAGE")
789
790 NTSTATUS AndroidUsbDeviceObject::CreateDefaultQueue() {
791 ASSERT_IRQL_PASSIVE();
792
793 // Register I/O callbacks to tell the framework that we are interested
794 // in handling WdfRequestTypeRead, WdfRequestTypeWrite, and
795 // WdfRequestTypeDeviceControl requests. WdfIoQueueDispatchParallel means
796 // that we are capable of handling all the I/O request simultaneously and we
797 // are responsible for protecting data that could be accessed by these
798 // callbacks simultaneously. This queue will be, by default, automanaged by
799 // the framework with respect to PnP and Power events. That is, framework
800 // will take care of queuing, failing, dispatching incoming requests based
801 // on the current PnP / Power state of the device. We also need to register
802 // a EvtIoStop handler so that we can acknowledge requests that are pending
803 // at the target driver.
804 WDF_IO_QUEUE_CONFIG io_queue_config;
805 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&io_queue_config,
806 WdfIoQueueDispatchParallel);
807
ConfigureDevice()808 io_queue_config.EvtIoDeviceControl = EvtIoDeviceControlEntry;
809 io_queue_config.EvtIoRead = EvtIoReadEntry;
810 io_queue_config.EvtIoWrite = EvtIoWriteEntry;
811 io_queue_config.AllowZeroLengthRequests = TRUE;
812 // By default KMDF will take care of the power management of this queue
813 io_queue_config.PowerManaged = WdfUseDefault;
814
815 // Create queue object
816 WDFQUEUE wdf_queue_obj = NULL;
817 NTSTATUS status = WdfIoQueueCreate(wdf_device(),
818 &io_queue_config,
819 WDF_NO_OBJECT_ATTRIBUTES,
820 &wdf_queue_obj);
821 ASSERT(NT_SUCCESS(status) && (NULL != wdf_queue_obj));
822 if (!NT_SUCCESS(status))
823 return status;
824 return STATUS_SUCCESS;
825 }
826
827 NTSTATUS AndroidUsbDeviceObject::ConfigureDevice() {
828 ASSERT_IRQL_PASSIVE();
829
830 ASSERT(IsTaretDeviceCreated());
831 if (!IsTaretDeviceCreated())
832 return STATUS_INTERNAL_ERROR;
833
834 // In order to get the configuration descriptor we must first query for its
835 // size (by supplying NULL for the descriptor's address), allocate enough
836 // memory and then retrieve the descriptor.
837 USHORT size = 0;
838
839 // Query descriptor size first
840 NTSTATUS status =
841 WdfUsbTargetDeviceRetrieveConfigDescriptor(wdf_target_device(),
842 WDF_NO_HANDLE,
843 &size);
844 ASSERT((status == STATUS_BUFFER_TOO_SMALL) || !NT_SUCCESS(status));
845 if (status != STATUS_BUFFER_TOO_SMALL)
846 return status;
847
848 // Create a memory object and specify our device as the parent so that
849 // it will be freed automatically along with our device.
850 WDFMEMORY memory = NULL;
851 WDF_OBJECT_ATTRIBUTES attributes;
852 WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
853 attributes.ParentObject = wdf_device();
854 status = WdfMemoryCreate(&attributes,
855 NonPagedPool,
856 GANDR_POOL_TAG_DEV_CFG_DESC,
857 size,
858 &memory,
859 reinterpret_cast<PVOID*>(&configuration_descriptor_));
860 ASSERT(NT_SUCCESS(status));
SelectInterfaces()861 if (!NT_SUCCESS(status))
862 return status;
863
864 // Now retrieve configuration descriptor
865 status =
866 WdfUsbTargetDeviceRetrieveConfigDescriptor(wdf_target_device(),
867 configuration_descriptor_,
868 &size);
869 ASSERT(NT_SUCCESS(status) && (NULL != configuration_descriptor_));
870 if (!NT_SUCCESS(status))
871 return status;
872
873 #if DBG
874 PrintConfigDescriptor(configuration_descriptor(), size);
875 #endif // DBG
876
877 return status;
878 }
879
880 NTSTATUS AndroidUsbDeviceObject::SelectInterfaces() {
881 ASSERT_IRQL_PASSIVE();
882
883 ASSERT(IsDeviceConfigured());
884 if (!IsDeviceConfigured())
885 return STATUS_INTERNAL_ERROR;
886
887 WDF_USB_DEVICE_SELECT_CONFIG_PARAMS config_params;
888 PWDF_USB_INTERFACE_SETTING_PAIR pairs = NULL;
889 // TODO: We need to find a way (possibly by looking at each
890 // interface descriptor) to get index of the ADB interface in multiinterface
891 // configuration.
892 UCHAR adb_interface_index = 0;
893
894 if (IsSingleInterfaceDevice()) {
895 // Our device has only one interface, so we don't have to bother with
896 // multiple interfaces at all.
897 GoogleDbgPrint("\n********** Device reports single interface");
898 // Select single interface configuration
899 WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&config_params);
900 } else {
901 // Configure multiple interfaces
902 ULONG num_interf = GetInterfaceCount();
903 GoogleDbgPrint("\n********** Device reports %u interfaces",
904 num_interf);
905
906 // Allocate pairs for each interface
907 pairs = new(PagedPool, GANDR_POOL_TAG_INTERF_PAIRS)
908 WDF_USB_INTERFACE_SETTING_PAIR[num_interf];
909 ASSERT(NULL != pairs);
910 if (NULL == pairs)
911 return STATUS_INSUFFICIENT_RESOURCES;
912
913 adb_interface_index = 1;
914 // Initialize each interface pair
915 for (UCHAR pair = 0; pair < num_interf; pair++) {
916 pairs[pair].SettingIndex = 0;
917 pairs[pair].UsbInterface =
918 WdfUsbTargetDeviceGetInterface(wdf_target_device(), pair);
919 ASSERT(NULL != pairs[pair].UsbInterface);
920 if (NULL == pairs[pair].UsbInterface) {
921 delete[] pairs;
922 return STATUS_INTERNAL_ERROR;
923 }
924 }
925
926 // Select multiinterface configuration
927 WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_MULTIPLE_INTERFACES(&config_params,
928 (UCHAR)num_interf,
929 pairs);
930 }
931
932 NTSTATUS status =
933 WdfUsbTargetDeviceSelectConfig(wdf_target_device(),
934 WDF_NO_OBJECT_ATTRIBUTES,
935 &config_params);
936 if (NULL != pairs)
937 delete[] pairs;
938
939 // ASSERT(NT_SUCCESS(status));
940 if (!NT_SUCCESS(status))
941 return status;
942
943 #if DBG
944 PrintSelectedConfig(&config_params);
945 #endif // DBG
946
947 wdf_usb_interface_ =
948 WdfUsbTargetDeviceGetInterface(wdf_target_device(), adb_interface_index);
949 ASSERT(NULL != wdf_usb_interface_);
950 if (NULL == wdf_usb_interface_)
951 return STATUS_INTERNAL_ERROR;
952
953 configured_pipes_num_ = WdfUsbInterfaceGetNumEndpoints(wdf_usb_interface(), 0);
954 ASSERT(0 != configured_pipes_num_);
955
956 // Cache selected interface descriptor
957 BYTE setting_index =
958 WdfUsbInterfaceGetConfiguredSettingIndex(wdf_usb_interface());
959
960 WdfUsbInterfaceGetDescriptor(wdf_usb_interface(),
961 setting_index,
962 &interface_descriptor_);
963
964 #if DBG
965 PrintInterfaceDescriptor(interface_descriptor());
966 #endif // DBG
967
968 // Iterate over pipes, decoding and saving info about bulk r/w pipes for
969 // easier and faster addressing later on when they get opened
970 for (UCHAR pipe = 0; pipe < configured_pipes_num(); pipe++) {
971 WDF_USB_PIPE_INFORMATION pipe_info;
972 WDF_USB_PIPE_INFORMATION_INIT(&pipe_info);
973 WDFUSBPIPE wdf_pipe_obj =
974 WdfUsbInterfaceGetConfiguredPipe(wdf_usb_interface(), pipe, &pipe_info);
975 ASSERT(NULL != wdf_pipe_obj);
976 if (NULL != wdf_pipe_obj) {
977 if ((WdfUsbPipeTypeBulk == pipe_info.PipeType) &&
978 WDF_USB_PIPE_DIRECTION_IN(pipe_info.EndpointAddress)) {
979 // This is a bulk read pipe
980 ASSERT(!IsBulkReadPipeKnown());
GetPipeIndexFromFileName(PUNICODE_STRING file_path)981 bulk_read_pipe_index_ = pipe;
982 } else {
983 ASSERT(!IsBulkWritePipeKnown());
984 bulk_write_pipe_index_ = pipe;
985 }
986 }
987 #if DBG
988 PrintPipeInformation(&pipe_info, pipe);
989 #endif // DBG
990 }
991
992 // At the end we must have calculated indexes for both,
993 // bulk read and write pipes
994 ASSERT(!NT_SUCCESS(status) || (IsBulkReadPipeKnown() &&
995 IsBulkWritePipeKnown()));
996
997 return status;
998 }
999
1000 UCHAR AndroidUsbDeviceObject::GetPipeIndexFromFileName(
1001 PUNICODE_STRING file_path) {
1002 ASSERT_IRQL_PASSIVE();
1003 ASSERT((NULL != file_path) && (0 != file_path->Length) && (NULL != file_path->Buffer));
1004 if ((NULL == file_path) ||
1005 (0 == file_path->Length) ||
1006 (NULL == file_path->Buffer)) {
1007 return INVALID_UCHAR;
1008 }
1009
1010 // Lets check for explicit r/w pipe names
1011 if (0 == RtlCompareUnicodeString(file_path, &bulk_read_pipe_name, TRUE))
1012 return bulk_read_pipe_index();
1013 if (0 == RtlCompareUnicodeString(file_path, &bulk_write_pipe_name, TRUE))
1014 return bulk_write_pipe_index();
1015
1016 // Lets check path format
1017 if (file_path->Length <= index_pipe_prefix.Length) {
1018 GoogleDbgPrint("\n!!!!! Bad format for pipe name: %wZ", file_path);
1019 return INVALID_UCHAR;
1020 }
1021
1022 // Now when whe know that file_path->Length is sufficient lets match this
1023 // path with the prefix
1024 UNICODE_STRING prefix_match = *file_path;
1025 prefix_match.Length = index_pipe_prefix.Length;
1026 prefix_match.MaximumLength = prefix_match.Length;
1027
1028 if (0 != RtlCompareUnicodeString(&prefix_match, &index_pipe_prefix, TRUE)) {
1029 GoogleDbgPrint("\n!!!!! Bad format for pipe name: %wZ", file_path);
1030 return INVALID_UCHAR;
1031 }
1032
1033 // Prefix matches. Make sure that remaining chars are all decimal digits.
1034 // Pipe index begins right after the prefix ends.
1035 const ULONG index_begins_at = WcharLen(index_pipe_prefix.Length);
1036 const ULONG name_len = WcharLen(file_path->Length);
1037 for (ULONG index = index_begins_at; index < name_len; index++) {
1038 if ((file_path->Buffer[index] > L'9') ||
CreatePipeFileObjectExt(WDFFILEOBJECT wdf_fo,WDFUSBPIPE wdf_pipe_obj,const WDF_USB_PIPE_INFORMATION * pipe_info,AndroidUsbFileObject ** wdf_file_ext)1039 (file_path->Buffer[index] < L'0')) {
1040 GoogleDbgPrint("\n!!!!! Bad format for pipe name: %wZ", file_path);
1041 return INVALID_UCHAR;
1042 }
1043 }
1044
1045 // Parse the pipe#
1046 ULONG uval = 0;
1047 ULONG umultiplier = 1;
1048
1049 // traversing least to most significant digits.
1050 for (ULONG index = name_len - 1; index >= index_begins_at; index--) {
1051 uval += (umultiplier * static_cast<ULONG>(file_path->Buffer[index] - L'0'));
1052 umultiplier *= 10;
1053 }
1054
1055 return static_cast<UCHAR>(uval);
1056 }
1057
1058 NTSTATUS AndroidUsbDeviceObject::CreatePipeFileObjectExt(
1059 WDFFILEOBJECT wdf_fo,
1060 WDFUSBPIPE wdf_pipe_obj,
1061 const WDF_USB_PIPE_INFORMATION* pipe_info,
1062 AndroidUsbFileObject** wdf_file_ext) {
1063 ASSERT_IRQL_PASSIVE();
1064 ASSERT((NULL != wdf_fo) && (NULL != wdf_pipe_obj) && (NULL != pipe_info) && (NULL != wdf_file_ext));
1065 if ((NULL == wdf_fo) || (NULL == wdf_pipe_obj) || (NULL == pipe_info) || (NULL == wdf_file_ext)) {
1066 return STATUS_INTERNAL_ERROR;
1067 }
1068 *wdf_file_ext = NULL;
1069
1070 AndroidUsbPipeFileObject* wdf_pipe_file_ext = NULL;
1071
1072 // We support only WdfUsbPipeTypeBulk and WdfUsbPipeTypeInterrupt files
1073 // at this point.
1074 switch (pipe_info->PipeType) {
1075 case WdfUsbPipeTypeBulk:
1076 wdf_pipe_file_ext = new(NonPagedPool, GANDR_POOL_TAG_BULK_FILE)
1077 AndroidUsbBulkPipeFileObject(this, wdf_fo, wdf_pipe_obj);
1078 break;
1079
1080 case WdfUsbPipeTypeInterrupt:
1081 wdf_pipe_file_ext = new(NonPagedPool, GANDR_POOL_TAG_INTERRUPT_FILE)
1082 AndroidUsbInterruptPipeFileObject(this, wdf_fo, wdf_pipe_obj);
1083 break;;
1084
1085 case WdfUsbPipeTypeIsochronous:
1086 case WdfUsbPipeTypeControl:
1087 case WdfUsbPipeTypeInvalid:
1088 default:
1089 return STATUS_OBJECT_TYPE_MISMATCH;
1090 }
1091
1092 // If we reached here instance of a file wrapper must be created.
PrintUsbDeviceDescriptor(const USB_DEVICE_DESCRIPTOR * desc)1093 ASSERT(NULL != wdf_pipe_file_ext);
1094 if (NULL == wdf_pipe_file_ext)
1095 return STATUS_INSUFFICIENT_RESOURCES;
1096
1097 // Initialize the wrapper.
1098 NTSTATUS status = wdf_pipe_file_ext->InitializePipe(pipe_info);
1099 ASSERT(NT_SUCCESS(status));
1100 if (NT_SUCCESS(status)) {
1101 *wdf_file_ext = wdf_pipe_file_ext;
1102 } else {
1103 delete wdf_pipe_file_ext;
1104 }
1105
1106 return STATUS_SUCCESS;
1107 }
1108
1109 #if DBG
1110 #pragma code_seg()
PrintUsbTargedDeviceInformation(const WDF_USB_DEVICE_INFORMATION * info)1111
1112 void AndroidUsbDeviceObject::PrintUsbDeviceDescriptor(
1113 const USB_DEVICE_DESCRIPTOR* desc) {
1114 GoogleDbgPrint("\n***** USB_DEVICE_DESCRIPTOR %p for device %p", desc, this);
1115 GoogleDbgPrint("\n bDescriptorType = %u", desc->bDescriptorType);
1116 GoogleDbgPrint("\n bcdUSB = x%02X", desc->bcdUSB);
1117 GoogleDbgPrint("\n bDeviceClass = x%02X", desc->bDeviceClass);
1118 GoogleDbgPrint("\n bDeviceSubClass = x%02X", desc->bDeviceSubClass);
1119 GoogleDbgPrint("\n bDeviceProtocol = x%02X", desc->bDeviceProtocol);
1120 GoogleDbgPrint("\n bMaxPacketSize = %u", desc->bMaxPacketSize0);
1121 GoogleDbgPrint("\n idVendor = x%04X", desc->idVendor);
1122 GoogleDbgPrint("\n idProduct = x%04X", desc->idProduct);
1123 GoogleDbgPrint("\n bcdDevice = x%02X", desc->bcdDevice);
1124 GoogleDbgPrint("\n iManufacturer = %u", desc->iManufacturer);
1125 GoogleDbgPrint("\n iProduct = %u", desc->iProduct);
1126 GoogleDbgPrint("\n iSerialNumber = %u", desc->iSerialNumber);
1127 GoogleDbgPrint("\n bNumConfigurations = %u", desc->bNumConfigurations);
1128 }
1129
1130 void AndroidUsbDeviceObject::PrintUsbTargedDeviceInformation(
1131 const WDF_USB_DEVICE_INFORMATION* info) {
1132 GoogleDbgPrint("\n***** WDF_USB_DEVICE_INFORMATION %p for device %p", info, this);
1133 GoogleDbgPrint("\n HcdPortCapabilities = x%08X", info->HcdPortCapabilities);
1134 GoogleDbgPrint("\n Traits = x%08X", info->Traits);
1135 GoogleDbgPrint("\n VersionInfo.USBDI_Version = x%08X",
PrintSelectedConfig(const WDF_USB_DEVICE_SELECT_CONFIG_PARAMS * config)1136 info->UsbdVersionInformation.USBDI_Version);
1137 GoogleDbgPrint("\n VersionInfo.Supported_USB_Version = x%08X",
1138 info->UsbdVersionInformation.Supported_USB_Version);
1139 }
1140
1141 void AndroidUsbDeviceObject::PrintConfigDescriptor(
1142 const USB_CONFIGURATION_DESCRIPTOR* desc,
1143 ULONG size) {
1144 GoogleDbgPrint("\n***** USB_CONFIGURATION_DESCRIPTOR %p for device %p size %u",
1145 desc, this, size);
1146 GoogleDbgPrint("\n bDescriptorType = %u", desc->bDescriptorType);
1147 GoogleDbgPrint("\n wTotalLength = %u", desc->wTotalLength);
1148 GoogleDbgPrint("\n bNumInterfaces = %u", desc->bNumInterfaces);
1149 GoogleDbgPrint("\n bConfigurationValue = %u", desc->bConfigurationValue);
1150 GoogleDbgPrint("\n iConfiguration = %u", desc->iConfiguration);
1151 GoogleDbgPrint("\n bmAttributes = %u", desc->bmAttributes);
1152 GoogleDbgPrint("\n MaxPower = %u", desc->MaxPower);
1153 }
1154
1155 void AndroidUsbDeviceObject::PrintSelectedConfig(
1156 const WDF_USB_DEVICE_SELECT_CONFIG_PARAMS* config) {
1157 GoogleDbgPrint("\n***** WDF_USB_DEVICE_SELECT_CONFIG_PARAMS %p for device %p", config, this);
1158 GoogleDbgPrint("\n Type = %u", config->Type);
1159 switch (config->Type) {
1160 case WdfUsbTargetDeviceSelectConfigTypeSingleInterface:
1161 GoogleDbgPrint("\n SingleInterface:");
1162 GoogleDbgPrint("\n NumberConfiguredPipes = %u",
1163 config->Types.SingleInterface.NumberConfiguredPipes);
1164 GoogleDbgPrint("\n ConfiguredUsbInterface = %p",
1165 config->Types.SingleInterface.ConfiguredUsbInterface);
1166 break;
1167
1168 case WdfUsbTargetDeviceSelectConfigTypeMultiInterface:
1169 GoogleDbgPrint("\n MultiInterface:");
1170 GoogleDbgPrint("\n NumberInterfaces = %u",
1171 config->Types.MultiInterface.NumberInterfaces);
1172 GoogleDbgPrint("\n NumberOfConfiguredInterfaces = %u",
1173 config->Types.MultiInterface.NumberOfConfiguredInterfaces);
1174 GoogleDbgPrint("\n Pairs = %p",
1175 config->Types.MultiInterface.Pairs);
1176 break;
1177
1178 case WdfUsbTargetDeviceSelectConfigTypeInterfacesDescriptor:
1179 GoogleDbgPrint("\n Descriptor:");
1180 GoogleDbgPrint("\n NumInterfaceDescriptors = %u",
1181 config->Types.Descriptor.NumInterfaceDescriptors);
1182 GoogleDbgPrint("\n ConfigurationDescriptor = %p",
1183 config->Types.Descriptor.ConfigurationDescriptor);
PrintInterfaceDescriptor(const USB_INTERFACE_DESCRIPTOR * desc)1184 GoogleDbgPrint("\n InterfaceDescriptors = %p",
1185 config->Types.Descriptor.InterfaceDescriptors);
1186 break;
1187
1188 case WdfUsbTargetDeviceSelectConfigTypeUrb:
1189 GoogleDbgPrint("\n Urb:");
1190 GoogleDbgPrint("\n Urb = %p",
1191 config->Types.Urb.Urb);
1192 break;
1193
1194 case WdfUsbTargetDeviceSelectConfigTypeInterfacesPairs:
1195 case WdfUsbTargetDeviceSelectConfigTypeInvalid:
1196 case WdfUsbTargetDeviceSelectConfigTypeDeconfig:
1197 default:
1198 GoogleDbgPrint("\n Config type is unknown or invalid or not printable.");
PrintPipeInformation(const WDF_USB_PIPE_INFORMATION * info,UCHAR pipe_index)1199 break;
1200 }
1201 }
1202
1203 void AndroidUsbDeviceObject::PrintInterfaceDescriptor(
1204 const USB_INTERFACE_DESCRIPTOR* desc) {
1205 GoogleDbgPrint("\n***** USB_INTERFACE_DESCRIPTOR %p for device %p",
1206 desc, this);
1207 GoogleDbgPrint("\n bLength = %u", desc->bLength);
1208 GoogleDbgPrint("\n bDescriptorType = %u", desc->bDescriptorType);
1209 GoogleDbgPrint("\n bInterfaceNumber = %u", desc->bInterfaceNumber);
1210 GoogleDbgPrint("\n bAlternateSetting = %u", desc->bAlternateSetting);
1211 GoogleDbgPrint("\n bNumEndpoints = %u", desc->bNumEndpoints);
1212 GoogleDbgPrint("\n bInterfaceClass = x%02X", desc->bInterfaceClass);
1213 GoogleDbgPrint("\n bInterfaceSubClass = x%02X", desc->bInterfaceSubClass);
1214 GoogleDbgPrint("\n bInterfaceProtocol = x%02X", desc->bInterfaceProtocol);
1215 GoogleDbgPrint("\n iInterface = %u", desc->iInterface);
1216 }
1217
1218 void AndroidUsbDeviceObject::PrintPipeInformation(
1219 const WDF_USB_PIPE_INFORMATION* info,
1220 UCHAR pipe_index) {
1221 GoogleDbgPrint("\n***** WDF_USB_PIPE_INFORMATION[%u] %p for device %p",
1222 pipe_index, info, this);
1223 GoogleDbgPrint("\n Size = %u", info->Size);
1224 GoogleDbgPrint("\n MaximumPacketSize = %u", info->MaximumPacketSize);
1225 GoogleDbgPrint("\n EndpointAddress = x%02X", info->EndpointAddress);
1226 GoogleDbgPrint("\n Interval = %u", info->Interval);
1227 GoogleDbgPrint("\n SettingIndex = %u", info->SettingIndex);
1228 GoogleDbgPrint("\n PipeType = %u", info->PipeType);
1229 GoogleDbgPrint("\n MaximumTransferSize = %u", info->MaximumTransferSize);
1230 }
1231
1232 #endif // DBG
1233
1234 #pragma data_seg()
1235 #pragma code_seg()
1236