1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxUsbPipeAPI.cpp 8 9 Abstract: 10 11 12 Author: 13 14 Environment: 15 16 Both kernel and user mode 17 18 Revision History: 19 20 --*/ 21 22 #include "fxusbpch.hpp" 23 24 extern "C" { 25 #include "FxUsbPipeAPI.tmh" 26 } 27 28 // 29 // extern "C" the whole file since we are exporting the APIs by name 30 // 31 extern "C" { 32 33 __drv_maxIRQL(DISPATCH_LEVEL) 34 VOID 35 WDFAPI 36 WDFEXPORT(WdfUsbTargetPipeGetInformation)( 37 __in 38 PWDF_DRIVER_GLOBALS DriverGlobals, 39 __in 40 WDFUSBPIPE Pipe, 41 __out 42 PWDF_USB_PIPE_INFORMATION PipeInformation 43 ) 44 { 45 DDI_ENTRY(); 46 47 PFX_DRIVER_GLOBALS pFxDriverGlobals; 48 FxUsbPipe* pUsbPipe; 49 50 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 51 Pipe, 52 FX_TYPE_IO_TARGET_USB_PIPE, 53 (PVOID*) &pUsbPipe, 54 &pFxDriverGlobals); 55 56 FxPointerNotNull(pFxDriverGlobals, PipeInformation); 57 58 pUsbPipe->GetInformation(PipeInformation); 59 } 60 61 __drv_maxIRQL(DISPATCH_LEVEL) 62 BOOLEAN 63 WDFAPI 64 WDFEXPORT(WdfUsbTargetPipeIsInEndpoint)( 65 __in 66 PWDF_DRIVER_GLOBALS DriverGlobals, 67 __in 68 WDFUSBPIPE Pipe 69 ) 70 { 71 DDI_ENTRY(); 72 73 FxUsbPipe* pUsbPipe; 74 75 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 76 Pipe, 77 FX_TYPE_IO_TARGET_USB_PIPE, 78 (PVOID*) &pUsbPipe); 79 80 return pUsbPipe->IsInEndpoint(); 81 } 82 83 __drv_maxIRQL(DISPATCH_LEVEL) 84 BOOLEAN 85 WDFAPI 86 WDFEXPORT(WdfUsbTargetPipeIsOutEndpoint)( 87 __in 88 PWDF_DRIVER_GLOBALS DriverGlobals, 89 __in 90 WDFUSBPIPE Pipe 91 ) 92 { 93 DDI_ENTRY(); 94 95 FxUsbPipe* pUsbPipe; 96 97 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 98 Pipe, 99 FX_TYPE_IO_TARGET_USB_PIPE, 100 (PVOID*) &pUsbPipe); 101 102 return pUsbPipe->IsOutEndpoint(); 103 } 104 105 __drv_maxIRQL(DISPATCH_LEVEL) 106 WDF_USB_PIPE_TYPE 107 WDFAPI 108 WDFEXPORT(WdfUsbTargetPipeGetType)( 109 __in 110 PWDF_DRIVER_GLOBALS DriverGlobals, 111 __in 112 WDFUSBPIPE Pipe 113 ) 114 { 115 DDI_ENTRY(); 116 117 FxUsbPipe* pUsbPipe; 118 119 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 120 Pipe, 121 FX_TYPE_IO_TARGET_USB_PIPE, 122 (PVOID*) &pUsbPipe); 123 124 return pUsbPipe->GetType(); 125 } 126 127 __drv_maxIRQL(DISPATCH_LEVEL) 128 VOID 129 WDFAPI 130 WDFEXPORT(WdfUsbTargetPipeSetNoMaximumPacketSizeCheck)( 131 __in 132 PWDF_DRIVER_GLOBALS DriverGlobals, 133 __in 134 WDFUSBPIPE Pipe 135 ) 136 { 137 DDI_ENTRY(); 138 139 PFX_DRIVER_GLOBALS pFxDriverGlobals; 140 FxUsbPipe* pUsbPipe; 141 142 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 143 Pipe, 144 FX_TYPE_IO_TARGET_USB_PIPE, 145 (PVOID*) &pUsbPipe, 146 &pFxDriverGlobals); 147 148 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 149 "WDFUSBPIPE %p", Pipe); 150 151 pUsbPipe->SetNoCheckPacketSize(); 152 } 153 154 _Must_inspect_result_ 155 __drv_maxIRQL(PASSIVE_LEVEL) 156 NTSTATUS 157 WDFAPI 158 WDFEXPORT(WdfUsbTargetPipeWriteSynchronously)( 159 __in 160 PWDF_DRIVER_GLOBALS DriverGlobals, 161 __in 162 WDFUSBPIPE Pipe, 163 __in_opt 164 WDFREQUEST Request, 165 __in_opt 166 PWDF_REQUEST_SEND_OPTIONS RequestOptions, 167 __in_opt 168 PWDF_MEMORY_DESCRIPTOR MemoryDescriptor, 169 __out_opt 170 PULONG BytesWritten 171 ) 172 { 173 DDI_ENTRY(); 174 175 DoTraceLevelMessage( 176 GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 177 "WDFUSBPIPE %p", Pipe); 178 179 return FxUsbPipe::_SendTransfer(GetFxDriverGlobals(DriverGlobals), 180 Pipe, 181 Request, 182 RequestOptions, 183 MemoryDescriptor, 184 BytesWritten, 185 0); 186 } 187 188 _Must_inspect_result_ 189 __drv_maxIRQL(DISPATCH_LEVEL) 190 NTSTATUS 191 WDFAPI 192 WDFEXPORT(WdfUsbTargetPipeFormatRequestForWrite)( 193 __in 194 PWDF_DRIVER_GLOBALS DriverGlobals, 195 __in 196 WDFUSBPIPE Pipe, 197 __in 198 WDFREQUEST Request, 199 __in_opt 200 WDFMEMORY WriteMemory, 201 __in_opt 202 PWDFMEMORY_OFFSET WriteOffsets 203 ) 204 { 205 DDI_ENTRY(); 206 207 DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 208 "WDFUSBPIPE %p, WDFREQUEST %p, WDFMEMORY %p", 209 Pipe, Request, WriteMemory); 210 211 return FxUsbPipe::_FormatTransfer(GetFxDriverGlobals(DriverGlobals), 212 Pipe, 213 Request, 214 WriteMemory, 215 WriteOffsets, 216 0); 217 } 218 219 _Must_inspect_result_ 220 __drv_maxIRQL(PASSIVE_LEVEL) 221 NTSTATUS 222 WDFAPI 223 WDFEXPORT(WdfUsbTargetPipeReadSynchronously)( 224 __in 225 PWDF_DRIVER_GLOBALS DriverGlobals, 226 __in 227 WDFUSBPIPE Pipe, 228 __in_opt 229 WDFREQUEST Request, 230 __in_opt 231 PWDF_REQUEST_SEND_OPTIONS RequestOptions, 232 __in_opt 233 PWDF_MEMORY_DESCRIPTOR MemoryDescriptor, 234 __out_opt 235 PULONG BytesRead 236 ) 237 { 238 DDI_ENTRY(); 239 240 DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 241 "WDFUSBPIPE %p", Pipe); 242 243 return FxUsbPipe::_SendTransfer( 244 GetFxDriverGlobals(DriverGlobals), 245 Pipe, 246 Request, 247 RequestOptions, 248 MemoryDescriptor, 249 BytesRead, 250 USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK 251 ); 252 } 253 254 _Must_inspect_result_ 255 __drv_maxIRQL(DISPATCH_LEVEL) 256 NTSTATUS 257 WDFAPI 258 WDFEXPORT(WdfUsbTargetPipeFormatRequestForRead)( 259 __in 260 PWDF_DRIVER_GLOBALS DriverGlobals, 261 __in 262 WDFUSBPIPE Pipe, 263 __in 264 WDFREQUEST Request, 265 __in_opt 266 WDFMEMORY ReadMemory, 267 __in_opt 268 PWDFMEMORY_OFFSET ReadOffsets 269 ) 270 { 271 DDI_ENTRY(); 272 273 DoTraceLevelMessage( 274 GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 275 "WDFUSBPIPE %p, WDFREQUEST %p, WDFMEMORY %p", 276 Pipe, Request, ReadMemory); 277 278 return FxUsbPipe::_FormatTransfer( 279 GetFxDriverGlobals(DriverGlobals), 280 Pipe, 281 Request, 282 ReadMemory, 283 ReadOffsets, 284 USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK 285 ); 286 } 287 288 _Must_inspect_result_ 289 __drv_maxIRQL(DISPATCH_LEVEL) 290 NTSTATUS 291 WDFAPI 292 WDFEXPORT(WdfUsbTargetPipeConfigContinuousReader)( 293 __in 294 PWDF_DRIVER_GLOBALS DriverGlobals, 295 __in 296 WDFUSBPIPE Pipe, 297 __in 298 PWDF_USB_CONTINUOUS_READER_CONFIG Config 299 ) 300 { 301 DDI_ENTRY(); 302 303 PFX_DRIVER_GLOBALS pFxDriverGlobals; 304 FxUsbPipe* pUsbPipe; 305 NTSTATUS status; 306 size_t total; 307 308 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 309 Pipe, 310 FX_TYPE_IO_TARGET_USB_PIPE, 311 (PVOID*) &pUsbPipe, 312 &pFxDriverGlobals); 313 314 FxPointerNotNull(pFxDriverGlobals, Config); 315 316 if (Config->Size != sizeof(WDF_USB_CONTINUOUS_READER_CONFIG)) { 317 status = STATUS_INFO_LENGTH_MISMATCH; 318 319 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 320 "Config %p incorrect size %d, expected %d %!STATUS!", 321 Config, Config->Size, sizeof(WDF_USB_CONTINUOUS_READER_CONFIG), 322 status); 323 324 return status; 325 } 326 327 if (Config->EvtUsbTargetPipeReadComplete == NULL) { 328 status = STATUS_INVALID_PARAMETER; 329 DoTraceLevelMessage( 330 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 331 "NULL EvtUsbTargetPipeReadComplete not allowed %!STATUS!", status); 332 return status; 333 } 334 335 if (Config->TransferLength == 0) { 336 status = STATUS_INVALID_PARAMETER; 337 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 338 "TransferLength of 0 not allowed %!STATUS!", status); 339 return status; 340 } 341 342 status = RtlSizeTAdd(Config->HeaderLength, 343 Config->TransferLength, 344 &total); 345 346 if (!NT_SUCCESS(status)) { 347 DoTraceLevelMessage( 348 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 349 "HeaderLength + TransferLength overflow %!STATUS!", status); 350 return status; 351 } 352 353 status = RtlSizeTAdd(total, 354 Config->TrailerLength, 355 &total); 356 357 if (!NT_SUCCESS(status)) { 358 DoTraceLevelMessage( 359 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 360 "HeaderLength + TransferLength + TrailerLength overflow %!STATUS!", 361 status); 362 return status; 363 } 364 365 // 366 // Internally WDF will assign a parent to the memory, so do not allow the driver 367 // to do so. 368 // 369 status = FxValidateObjectAttributes(pFxDriverGlobals, 370 Config->BufferAttributes, 371 FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED); 372 if (!NT_SUCCESS(status)) { 373 return status; 374 } 375 376 // 377 // Only bulk or interrrupt is allowed for a continous reader 378 // 379 if ((pUsbPipe->IsType(WdfUsbPipeTypeBulk) || 380 pUsbPipe->IsType(WdfUsbPipeTypeInterrupt)) == FALSE) { 381 status = STATUS_INVALID_DEVICE_REQUEST; 382 383 DoTraceLevelMessage( 384 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 385 "WDFUSBPIPE %p type %!WDF_USB_PIPE_TYPE!, only bulk or interrupt " 386 "pipes can be configured for continous readers, %!STATUS!", 387 Pipe, pUsbPipe->GetType(), status); 388 389 return status; 390 } 391 392 if (pUsbPipe->IsOutEndpoint()) { 393 status = STATUS_INVALID_DEVICE_REQUEST; 394 395 DoTraceLevelMessage( 396 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 397 "WDFUSBPIPE %p, wrong direction for continuous reader, %!STATUS!", 398 Pipe, status); 399 400 return status; 401 } 402 403 status = pUsbPipe->ValidateTransferLength(Config->TransferLength); 404 if (!NT_SUCCESS(status)) { 405 DoTraceLevelMessage( 406 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 407 "TransferLength %I64d not a valid transer length (not integral of max " 408 "packet size %d) %!STATUS!", Config->TransferLength, 409 pUsbPipe->GetMaxPacketSize(), status); 410 return status; 411 } 412 413 status = pUsbPipe->InitContinuousReader(Config, total); 414 415 return status; 416 } 417 418 _Must_inspect_result_ 419 __drv_maxIRQL(PASSIVE_LEVEL) 420 NTSTATUS 421 WDFAPI 422 WDFEXPORT(WdfUsbTargetPipeAbortSynchronously)( 423 __in 424 PWDF_DRIVER_GLOBALS DriverGlobals, 425 __in 426 WDFUSBPIPE Pipe, 427 __in_opt 428 WDFREQUEST Request, 429 __in_opt 430 PWDF_REQUEST_SEND_OPTIONS RequestOptions 431 ) 432 { 433 DDI_ENTRY(); 434 435 PFX_DRIVER_GLOBALS pFxDriverGlobals; 436 FxUsbPipe* pUsbPipe; 437 NTSTATUS status; 438 439 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 440 Pipe, 441 FX_TYPE_IO_TARGET_USB_PIPE, 442 (PVOID*) &pUsbPipe, 443 &pFxDriverGlobals); 444 445 FxUsbPipeRequestContext context(FxUrbTypeLegacy); 446 447 FxSyncRequest request(pFxDriverGlobals, &context, Request); 448 449 // 450 // FxSyncRequest always succeesds for KM but can fail for UM. 451 // 452 status = request.Initialize(); 453 if (!NT_SUCCESS(status)) { 454 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 455 "Failed to initialize FxSyncRequest"); 456 return status; 457 } 458 459 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 460 "Pipe %p", Pipe); 461 462 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 463 if (!NT_SUCCESS(status)) { 464 return status; 465 } 466 467 status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions); 468 if (!NT_SUCCESS(status)) { 469 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 470 "Invalid request options"); 471 return status; 472 } 473 474 status = pUsbPipe->FormatAbortRequest(request.m_TrueRequest); 475 if (NT_SUCCESS(status)) { 476 DoTraceLevelMessage( 477 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 478 "WDFUSBPIPE %p, WDFREQUEST %p being submitted", 479 Pipe, request.m_TrueRequest->GetTraceObjectHandle()); 480 481 status = pUsbPipe->SubmitSync(request.m_TrueRequest, RequestOptions); 482 } 483 484 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 485 "WDFUSBPIPE %p, %!STATUS!", Pipe, status); 486 487 return status; 488 } 489 490 _Must_inspect_result_ 491 __drv_maxIRQL(DISPATCH_LEVEL) 492 NTSTATUS 493 WDFAPI 494 WDFEXPORT(WdfUsbTargetPipeFormatRequestForAbort)( 495 __in 496 PWDF_DRIVER_GLOBALS DriverGlobals, 497 __in 498 WDFUSBPIPE Pipe, 499 __in 500 WDFREQUEST Request 501 ) 502 { 503 DDI_ENTRY(); 504 505 PFX_DRIVER_GLOBALS pFxDriverGlobals; 506 FxRequest* pRequest; 507 FxUsbPipe* pUsbPipe; 508 NTSTATUS status; 509 510 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 511 Pipe, 512 FX_TYPE_IO_TARGET_USB_PIPE, 513 (PVOID*) &pUsbPipe, 514 &pFxDriverGlobals); 515 516 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 517 "Pipe %p, Request %p", Pipe, Request); 518 519 FxObjectHandleGetPtr(pFxDriverGlobals, 520 Request, 521 FX_TYPE_REQUEST, 522 (PVOID*) &pRequest); 523 524 status = pUsbPipe->FormatAbortRequest(pRequest); 525 526 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 527 "Pipe %p, Request %p, status %!STATUS!", 528 Pipe, Request, status); 529 530 return status; 531 } 532 533 _Must_inspect_result_ 534 __drv_maxIRQL(PASSIVE_LEVEL) 535 NTSTATUS 536 WDFAPI 537 WDFEXPORT(WdfUsbTargetPipeResetSynchronously)( 538 __in 539 PWDF_DRIVER_GLOBALS DriverGlobals, 540 __in 541 WDFUSBPIPE Pipe, 542 __in_opt 543 WDFREQUEST Request, 544 __in_opt 545 PWDF_REQUEST_SEND_OPTIONS RequestOptions 546 ) 547 { 548 DDI_ENTRY(); 549 550 PFX_DRIVER_GLOBALS pFxDriverGlobals; 551 FxUsbPipe* pUsbPipe; 552 NTSTATUS status; 553 554 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 555 Pipe, 556 FX_TYPE_IO_TARGET_USB_PIPE, 557 (PVOID*) &pUsbPipe, 558 &pFxDriverGlobals); 559 560 FxUsbPipeRequestContext context(FxUrbTypeLegacy); 561 562 FxSyncRequest request(pFxDriverGlobals, &context, Request); 563 564 // 565 // FxSyncRequest always succeesds for KM but can fail for UM. 566 // 567 status = request.Initialize(); 568 if (!NT_SUCCESS(status)) { 569 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 570 "Failed to initialize FxSyncRequest"); 571 return status; 572 } 573 574 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 575 "WDFUSBPIPE %p reset", Pipe); 576 577 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 578 if (!NT_SUCCESS(status)) { 579 return status; 580 } 581 582 status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions); 583 if (!NT_SUCCESS(status)) { 584 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 585 "Invalid request options"); 586 return status; 587 } 588 589 status = pUsbPipe->FormatResetRequest(request.m_TrueRequest); 590 591 if (NT_SUCCESS(status)) { 592 DoTraceLevelMessage( 593 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 594 "WDFUSBPIPE %p, WDFREQUEST %p being submitted", 595 Pipe, request.m_TrueRequest->GetTraceObjectHandle()); 596 597 pUsbPipe->CancelSentIo(); 598 599 // 600 // Even if the previous state of the target was stopped let this IO go through by 601 // ignoring target state. 602 // 603 status = pUsbPipe->SubmitSyncRequestIgnoreTargetState(request.m_TrueRequest, RequestOptions); 604 } 605 606 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 607 "WDFUSBPIPE %p reset, %!STATUS!", Pipe, status); 608 609 return status; 610 } 611 612 _Must_inspect_result_ 613 __drv_maxIRQL(DISPATCH_LEVEL) 614 NTSTATUS 615 WDFAPI 616 WDFEXPORT(WdfUsbTargetPipeFormatRequestForReset)( 617 __in 618 PWDF_DRIVER_GLOBALS DriverGlobals, 619 __in 620 WDFUSBPIPE Pipe, 621 __in 622 WDFREQUEST Request 623 ) 624 { 625 DDI_ENTRY(); 626 627 PFX_DRIVER_GLOBALS pFxDriverGlobals; 628 FxRequest* pRequest; 629 FxUsbPipe* pUsbPipe; 630 NTSTATUS status; 631 632 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 633 Pipe, 634 FX_TYPE_IO_TARGET_USB_PIPE, 635 (PVOID*) &pUsbPipe, 636 &pFxDriverGlobals); 637 638 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 639 "Pipe %p, Request %p", Pipe, Request); 640 641 FxObjectHandleGetPtr(pFxDriverGlobals, 642 Request, 643 FX_TYPE_REQUEST, 644 (PVOID*) &pRequest); 645 646 status = pUsbPipe->FormatResetRequest(pRequest); 647 648 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 649 "Pipe %p, Request %p = 0x%x", 650 Pipe, Request, status); 651 652 return status; 653 } 654 655 _Must_inspect_result_ 656 __drv_maxIRQL(PASSIVE_LEVEL) 657 NTSTATUS 658 WDFAPI 659 WDFEXPORT(WdfUsbTargetPipeSendUrbSynchronously)( 660 __in 661 PWDF_DRIVER_GLOBALS DriverGlobals, 662 __in 663 WDFUSBPIPE Pipe, 664 __in_opt 665 WDFREQUEST Request, 666 __in_opt 667 PWDF_REQUEST_SEND_OPTIONS RequestOptions, 668 __in_xcount("union bug in SAL") 669 PURB Urb 670 ) 671 { 672 DDI_ENTRY(); 673 674 FxRequestBuffer buf; 675 PFX_DRIVER_GLOBALS pFxDriverGlobals; 676 FxUsbPipe* pUsbPipe; 677 NTSTATUS status; 678 679 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 680 Pipe, 681 FX_TYPE_IO_TARGET_USB_PIPE, 682 (PVOID*) &pUsbPipe, 683 &pFxDriverGlobals); 684 685 FxUsbUrbContext context; 686 FxSyncRequest request(pFxDriverGlobals, &context, Request); 687 688 // 689 // FxSyncRequest always succeesds for KM but can fail for UM. 690 // 691 status = request.Initialize(); 692 if (!NT_SUCCESS(status)) { 693 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 694 "Failed to initialize FxSyncRequest"); 695 return status; 696 } 697 698 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 699 "WDFUSBPIPE %p, Urb %p", Pipe, Urb); 700 701 FxPointerNotNull(pFxDriverGlobals, Urb); 702 703 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 704 if (!NT_SUCCESS(status)) { 705 return status; 706 } 707 708 status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions); 709 if (!NT_SUCCESS(status)) { 710 return status; 711 } 712 713 buf.SetBuffer(Urb, 0); 714 715 status = FxFormatUrbRequest(pFxDriverGlobals, 716 pUsbPipe, 717 request.m_TrueRequest, 718 &buf, 719 pUsbPipe->GetUrbType(), 720 pUsbPipe->GetUSBDHandle()); 721 722 if (NT_SUCCESS(status)) { 723 DoTraceLevelMessage( 724 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 725 "WDFUSBPIPE %p, WDFREQUEST %p being submitted", 726 Pipe, request.m_TrueRequest->GetTraceObjectHandle()); 727 728 status = pUsbPipe->SubmitSync(request.m_TrueRequest, RequestOptions); 729 } 730 731 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 732 "WDFUSBPIPE %p, Urb %p, %!STATUS!", 733 Pipe, Urb, status); 734 735 return status; 736 } 737 738 _Must_inspect_result_ 739 __drv_maxIRQL(DISPATCH_LEVEL) 740 NTSTATUS 741 WDFAPI 742 WDFEXPORT(WdfUsbTargetPipeFormatRequestForUrb)( 743 __in 744 PWDF_DRIVER_GLOBALS DriverGlobals, 745 __in 746 WDFUSBPIPE Pipe, 747 __in 748 WDFREQUEST Request, 749 __in 750 WDFMEMORY UrbMemory, 751 __in_opt 752 PWDFMEMORY_OFFSET UrbOffsets 753 ) 754 { 755 DDI_ENTRY(); 756 757 PFX_DRIVER_GLOBALS pFxDriverGlobals; 758 IFxMemory* pMemory; 759 FxUsbPipe* pUsbPipe; 760 FxRequest* pRequest; 761 FxRequestBuffer buf; 762 NTSTATUS status; 763 size_t bufferSize; 764 765 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 766 Pipe, 767 FX_TYPE_IO_TARGET_USB_PIPE, 768 (PVOID*) &pUsbPipe, 769 &pFxDriverGlobals); 770 771 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 772 "Pipe %p, Request %p, Memory %p", 773 Pipe, Request, UrbMemory); 774 775 FxObjectHandleGetPtr(pFxDriverGlobals, 776 UrbMemory, 777 IFX_TYPE_MEMORY, 778 (PVOID*) &pMemory); 779 780 FxObjectHandleGetPtr(pFxDriverGlobals, 781 Request, 782 FX_TYPE_REQUEST, 783 (PVOID*) &pRequest); 784 785 status = pMemory->ValidateMemoryOffsets(UrbOffsets); 786 if (!NT_SUCCESS(status)) { 787 return status; 788 } 789 790 bufferSize = pMemory->GetBufferSize(); 791 if (UrbOffsets != NULL && UrbOffsets->BufferOffset > 0) { 792 bufferSize -= UrbOffsets->BufferOffset; 793 } 794 795 if (bufferSize < sizeof(_URB_HEADER)) { 796 status = STATUS_INVALID_PARAMETER; 797 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 798 "UrbMemory %p buffer size, %I64d, smaller then " 799 "_URB_HEADER, %!STATUS!", UrbMemory, 800 pMemory->GetBufferSize(), status); 801 return status; 802 } 803 804 buf.SetMemory(pMemory, UrbOffsets); 805 806 status = FxFormatUrbRequest(pFxDriverGlobals, 807 pUsbPipe, 808 pRequest, 809 &buf, 810 pUsbPipe->GetUrbType(), 811 pUsbPipe->GetUSBDHandle()); 812 813 if (NT_SUCCESS(status)) { 814 FxUsbUrbContext* pContext; 815 pContext = (FxUsbUrbContext*) pRequest->GetContext(); 816 817 pContext->SetUsbType(WdfUsbRequestTypePipeUrb); 818 pContext->m_UsbParameters.Parameters.PipeUrb.Buffer = UrbMemory; 819 } 820 821 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET, 822 "Pipe %p, Request %p, Memory %p, status %!STATUS!", 823 Pipe, Request, UrbMemory, status); 824 825 return status; 826 } 827 828 __drv_maxIRQL(DISPATCH_LEVEL) 829 USBD_PIPE_HANDLE 830 WDFAPI 831 WDFEXPORT(WdfUsbTargetPipeWdmGetPipeHandle)( 832 __in 833 PWDF_DRIVER_GLOBALS DriverGlobals, 834 __in 835 WDFUSBPIPE UsbPipe 836 ) 837 /*++ 838 839 Routine Description: 840 Returns the underlying WDM USBD pipe handle 841 842 Arguments: 843 UsbPipe - the WDF pipe whose WDM handle will be returned 844 845 Return Value: 846 valid handle value or NULL on error 847 848 --*/ 849 { 850 DDI_ENTRY(); 851 852 FxUsbPipe* pUsbPipe; 853 854 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 855 UsbPipe, 856 FX_TYPE_IO_TARGET_USB_PIPE, 857 (PVOID*) &pUsbPipe); 858 859 return pUsbPipe->WdmGetPipeHandle(); 860 } 861 862 } // extern "C" 863