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 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 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 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 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 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 WdfUsbTargetDeviceAllocAndQueryString(wdf_target_device(), 249 WDF_NO_OBJECT_ATTRIBUTES, 251 &serial_number_handle_, 253 &serial_number_char_len_, 255 usb_device_descriptor_.iSerialNumber, 257 0x0409); // English (US) 259 if (!NT_SUCCESS(status)) 261 return status; 263 265 #if DBG 267 UNICODE_STRING ser_num; 269 ser_num.Length = serial_number_byte_len(); 271 ser_num.MaximumLength = ser_num.Length; 273 ser_num.Buffer = const_cast<WCHAR*> 275 (serial_number()); 277 GoogleDbgPrint("\n*** Device serial number %wZ", &ser_num); 279 #endif // DBG 281 283 // 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()) 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(); 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); 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) ? 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 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, 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, 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()); 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 } 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, 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)); 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, 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)); 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 = 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; 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 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)); 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()); 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') || 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. 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() 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", 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); 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."); 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