ReactOS 0.4.17-dev-1281-g065abb3
urbroute.cpp File Reference
#include "ucx01000.h"
#include <pseh/pseh2.h>
#include <debug.h>
Include dependency graph for urbroute.cpp:

Go to the source code of this file.

Classes

struct  UcxUrbFunction
 

Macros

#define NDEBUG
 
#define UCX_URB_TRANSFER   0x01
 
#define UCX_URB_DEFAULT_PIPE   0x02
 
#define UCX_URB_NO_DATA   0x04
 
#define UCX_URB_PIPE_REQUEST   0x08
 
#define UCX_DIR_OUT   0
 
#define UCX_DIR_IN   1
 
#define UCX_DIR_CLIENT   2
 
#define UCX_RT_STANDARD   0
 
#define UCX_RT_CLASS   1
 
#define UCX_RT_VENDOR   2
 
#define UCX_TO_DEVICE   0
 
#define UCX_TO_INTERFACE   1
 
#define UCX_TO_ENDPOINT   2
 
#define UCX_TO_OTHER   3
 
#define UCX_PIPE_REQUEST_SIZE   sizeof(struct _URB_PIPE_REQUEST)
 
#define UCX_DESCRIPTOR_SIZE   sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)
 
#define UCX_FEATURE_SIZE   sizeof(struct _URB_CONTROL_FEATURE_REQUEST)
 
#define UCX_STATUS_SIZE   sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST)
 
#define UCX_VENDOR_SIZE   sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)
 
#define UCX_STD_TRANSFER   (UCX_URB_TRANSFER | UCX_URB_DEFAULT_PIPE)
 
#define UCX_STD_NO_DATA   (UCX_URB_TRANSFER | UCX_URB_DEFAULT_PIPE | UCX_URB_NO_DATA)
 
#define UCX_UNSUPPORTED(Length)   { UcxUrbHandler::NotSupported, (USHORT)(Length), 0, 0, 0, 0, 0 }
 
#define UCX_INVALID   { UcxUrbHandler::InvalidFunction, 0, 0, 0, 0, 0, 0 }
 
#define UCX_DESCRIPTOR(Dir, To, Req)   { UcxUrbHandler::GetSetDescriptor, UCX_DESCRIPTOR_SIZE, UCX_STD_TRANSFER, Dir, UCX_RT_STANDARD, To, Req }
 
#define UCX_FEATURE(To, Req)   { UcxUrbHandler::SetClearFeature, UCX_FEATURE_SIZE, UCX_STD_NO_DATA, UCX_DIR_OUT, UCX_RT_STANDARD, To, Req }
 
#define UCX_STATUS(To)   { UcxUrbHandler::GetStatus, UCX_STATUS_SIZE, UCX_STD_TRANSFER, UCX_DIR_IN, UCX_RT_STANDARD, To, USB_REQUEST_GET_STATUS }
 
#define UCX_VENDOR_CLASS(Type, To)   { UcxUrbHandler::VendorClass, UCX_VENDOR_SIZE, UCX_STD_TRANSFER, UCX_DIR_CLIENT, Type, To, 0 }
 

Enumerations

enum class  UcxUrbHandler : UCHAR {
  NotSupported , InvalidFunction , AbortPipe , GetCurrentFrame ,
  ControlTransfer , BulkOrInterrupt , Isoch , GetSetDescriptor ,
  SetClearFeature , GetStatus , VendorClass , GetConfiguration ,
  GetInterface , MsFeatureDescriptor
}
 

Functions

NTSTATUS NTAPI UcxUsbdStatusToNtStatus (_In_ USBD_STATUS UsbdStatus)
 
USBD_STATUS NTAPI UcxNtStatusToUsbdStatus (_In_ NTSTATUS Status)
 
VOID NTAPI UcxLockTransferBuffer (_Inout_ PURB Urb)
 
VOID NTAPI UcxUnlockTransferBuffer (_Inout_ PURB Urb)
 
 C_ASSERT (ARRAYSIZE(UcxUrbFunctions)==URB_FUNCTION_RESERVE_0X0034+1)
 
static VOID NTAPI UcxSetCompletionOnNext (_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PIO_COMPLETION_ROUTINE Completion, _In_ PVOID Context)
 
NTSTATUS NTAPI UcxForwardIrpToQueue (_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PIO_COMPLETION_ROUTINE Completion, _In_ PVOID Context, _In_ WDFQUEUE Queue)
 
NTSTATUS NTAPI UcxForwardIrpWithRequest (_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PIO_COMPLETION_ROUTINE Completion, _In_ PVOID Context, _In_ WDFQUEUE Queue, _In_ WDFREQUEST Request)
 
BOOLEAN NTAPI UcxValidatePipeHandle (_In_ UcxUsbDevice *Device, _In_ USBD_PIPE_HANDLE Handle)
 
static BOOLEAN NTAPI UcxChainedMdlMisaligned (_In_ PMDL Mdl, _In_ ULONG Length)
 
static PUCHAR NTAPI UcxSetupPacket (_In_ PURB Urb)
 
static UCHAR NTAPI UcxRequestType (_In_ UCHAR Direction, _In_ UCHAR Type, _In_ UCHAR Recipient)
 
static VOID NTAPI UcxSetWord (_Out_writes_bytes_(2) PUCHAR Where, _In_ USHORT Value)
 
static USHORT NTAPI UcxGetWord (_In_reads_bytes_(2) const UCHAR *Where)
 
static NTSTATUS NTAPI UcxForwardDefaultPipeRequest (_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PURB Urb, _In_ WDFQUEUE Queue)
 
static NTSTATUS NTAPI UcxHandleStandardRequest (_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PURB Urb, _In_ WDFQUEUE Queue, _In_ const UcxUrbFunction *Function)
 
static NTSTATUS NTAPI UcxHandleIsoch (_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PURB Urb, _In_ WDFQUEUE Queue, _In_ UcxPipe *Pipe)
 
static NTSTATUS NTAPI UcxHandleGetCurrentFrame (_In_ PIRP Irp, _In_ PURB Urb, _In_ UcxUsbDevice *Device)
 
static USBD_STATUS NTAPI UcxCheckTransferAgainstPipe (_In_ PURB Urb, _In_ const UcxPipe *Pipe)
 
static USBD_STATUS NTAPI UcxPrepareTransfer (_In_ PURB Urb, _In_ UcxUsbDevice *Device, _In_ const UcxUrbFunction *Function, _Outptr_ UcxPipe **TargetPipe)
 
NTSTATUS NTAPI UcxProcessLegacyUrb (_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PURB Urb)
 
static NTSTATUS NTAPI UcxLegacyTransferCompletion (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Context)
 

Variables

static const UcxUrbFunction UcxUrbFunctions []
 
static IO_COMPLETION_ROUTINE UcxLegacyTransferCompletion
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 11 of file urbroute.cpp.

◆ UCX_DESCRIPTOR

#define UCX_DESCRIPTOR (   Dir,
  To,
  Req 
)    { UcxUrbHandler::GetSetDescriptor, UCX_DESCRIPTOR_SIZE, UCX_STD_TRANSFER, Dir, UCX_RT_STANDARD, To, Req }

Definition at line 206 of file urbroute.cpp.

◆ UCX_DESCRIPTOR_SIZE

Definition at line 196 of file urbroute.cpp.

◆ UCX_DIR_CLIENT

#define UCX_DIR_CLIENT   2

Definition at line 173 of file urbroute.cpp.

◆ UCX_DIR_IN

#define UCX_DIR_IN   1

Definition at line 172 of file urbroute.cpp.

◆ UCX_DIR_OUT

#define UCX_DIR_OUT   0

Definition at line 171 of file urbroute.cpp.

◆ UCX_FEATURE

#define UCX_FEATURE (   To,
  Req 
)    { UcxUrbHandler::SetClearFeature, UCX_FEATURE_SIZE, UCX_STD_NO_DATA, UCX_DIR_OUT, UCX_RT_STANDARD, To, Req }

Definition at line 207 of file urbroute.cpp.

◆ UCX_FEATURE_SIZE

Definition at line 197 of file urbroute.cpp.

◆ UCX_INVALID

#define UCX_INVALID   { UcxUrbHandler::InvalidFunction, 0, 0, 0, 0, 0, 0 }

Definition at line 205 of file urbroute.cpp.

◆ UCX_PIPE_REQUEST_SIZE

#define UCX_PIPE_REQUEST_SIZE   sizeof(struct _URB_PIPE_REQUEST)

Definition at line 195 of file urbroute.cpp.

◆ UCX_RT_CLASS

#define UCX_RT_CLASS   1

Definition at line 187 of file urbroute.cpp.

◆ UCX_RT_STANDARD

#define UCX_RT_STANDARD   0

Definition at line 186 of file urbroute.cpp.

◆ UCX_RT_VENDOR

#define UCX_RT_VENDOR   2

Definition at line 188 of file urbroute.cpp.

◆ UCX_STATUS

◆ UCX_STATUS_SIZE

Definition at line 198 of file urbroute.cpp.

◆ UCX_STD_NO_DATA

Definition at line 202 of file urbroute.cpp.

◆ UCX_STD_TRANSFER

#define UCX_STD_TRANSFER   (UCX_URB_TRANSFER | UCX_URB_DEFAULT_PIPE)

Definition at line 201 of file urbroute.cpp.

◆ UCX_TO_DEVICE

#define UCX_TO_DEVICE   0

Definition at line 190 of file urbroute.cpp.

◆ UCX_TO_ENDPOINT

#define UCX_TO_ENDPOINT   2

Definition at line 192 of file urbroute.cpp.

◆ UCX_TO_INTERFACE

#define UCX_TO_INTERFACE   1

Definition at line 191 of file urbroute.cpp.

◆ UCX_TO_OTHER

#define UCX_TO_OTHER   3

Definition at line 193 of file urbroute.cpp.

◆ UCX_UNSUPPORTED

#define UCX_UNSUPPORTED (   Length)    { UcxUrbHandler::NotSupported, (USHORT)(Length), 0, 0, 0, 0, 0 }

Definition at line 204 of file urbroute.cpp.

◆ UCX_URB_DEFAULT_PIPE

#define UCX_URB_DEFAULT_PIPE   0x02

Definition at line 166 of file urbroute.cpp.

◆ UCX_URB_NO_DATA

#define UCX_URB_NO_DATA   0x04

Definition at line 167 of file urbroute.cpp.

◆ UCX_URB_PIPE_REQUEST

#define UCX_URB_PIPE_REQUEST   0x08

Definition at line 168 of file urbroute.cpp.

◆ UCX_URB_TRANSFER

#define UCX_URB_TRANSFER   0x01

Definition at line 165 of file urbroute.cpp.

◆ UCX_VENDOR_CLASS

#define UCX_VENDOR_CLASS (   Type,
  To 
)    { UcxUrbHandler::VendorClass, UCX_VENDOR_SIZE, UCX_STD_TRANSFER, UCX_DIR_CLIENT, Type, To, 0 }

Definition at line 209 of file urbroute.cpp.

◆ UCX_VENDOR_SIZE

Definition at line 199 of file urbroute.cpp.

Enumeration Type Documentation

◆ UcxUrbHandler

Enumerator
NotSupported 
InvalidFunction 
AbortPipe 
GetCurrentFrame 
ControlTransfer 
BulkOrInterrupt 
Isoch 
GetSetDescriptor 
SetClearFeature 
GetStatus 
VendorClass 
GetConfiguration 
GetInterface 
MsFeatureDescriptor 

Definition at line 146 of file urbroute.cpp.

Function Documentation

◆ C_ASSERT()

C_ASSERT ( ARRAYSIZE(UcxUrbFunctions)  = =URB_FUNCTION_RESERVE_0X0034+1)

◆ UcxChainedMdlMisaligned()

static BOOLEAN NTAPI UcxChainedMdlMisaligned ( _In_ PMDL  Mdl,
_In_ ULONG  Length 
)
static

A single MDL is always accepted, even if shorter than the transfer.

Definition at line 399 of file urbroute.cpp.

402{
403 ULONG Remaining;
404
405 if (Mdl->Next == NULL || Length <= MmGetMdlByteCount(Mdl))
406 return FALSE;
407
409 return TRUE;
410
411 Remaining = Length - MmGetMdlByteCount(Mdl);
412
413 for (Mdl = Mdl->Next; Mdl != NULL; Mdl = Mdl->Next)
414 {
415 if (MmGetMdlByteOffset(Mdl) != 0)
416 return TRUE;
417
418 if (Remaining <= MmGetMdlByteCount(Mdl))
419 return FALSE;
420
421 if (MmGetMdlByteCount(Mdl) % PAGE_SIZE != 0)
422 return TRUE;
423
424 Remaining -= MmGetMdlByteCount(Mdl);
425 }
426
427 return TRUE;
428}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
#define MmGetMdlByteOffset(_Mdl)
#define MmGetMdlByteCount(_Mdl)

Referenced by UcxPrepareTransfer().

◆ UcxCheckTransferAgainstPipe()

static USBD_STATUS NTAPI UcxCheckTransferAgainstPipe ( _In_ PURB  Urb,
_In_ const UcxPipe *  Pipe 
)
static

The transfer specific checks; the last recorded error wins.

Definition at line 642 of file urbroute.cpp.

645{
646 ULONG Length = Urb->UrbControlTransfer.TransferBufferLength;
647 BOOLEAN AllowLarge = (Urb->UrbHeader.UsbdFlags & UCXHUB_URB_FLAG_ALLOW_LARGE_TRANSFER) != 0;
649
650 switch (Urb->UrbHeader.Function)
651 {
653 case URB_FUNCTION_CONTROL_TRANSFER_EX:
654 if (Pipe->TransferType != UcxTransferType::Control)
656 if ((Length > Pipe->MaximumTransferSize && !AllowLarge) || Length > UCX_MAX_CONTROL_TRANSFER)
658 break;
659
661 if (Pipe->TransferType != UcxTransferType::Bulk && Pipe->TransferType != UcxTransferType::Interrupt)
663 if (Length > Pipe->MaximumTransferSize)
665 break;
666
668 if (Pipe->TransferType != UcxTransferType::Isochronous)
670 break;
671 }
672
673 return Error;
674}
unsigned char BOOLEAN
Definition: actypes.h:127
BOOL Error
Definition: chkdsk.c:66
#define UCXHUB_URB_FLAG_ALLOW_LARGE_TRANSFER
Definition: hubucx.h:101
#define UCX_MAX_CONTROL_TRANSFER
Definition: urbroute.h:17
#define USBD_STATUS_INVALID_PIPE_HANDLE
Definition: usb.h:205
#define USBD_STATUS_SUCCESS
Definition: usb.h:177
#define URB_FUNCTION_CONTROL_TRANSFER
Definition: usb.h:94
#define USBD_STATUS_INVALID_PARAMETER
Definition: usb.h:203
#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
Definition: usb.h:95
LONG USBD_STATUS
Definition: usb.h:172
#define URB_FUNCTION_ISOCH_TRANSFER
Definition: usb.h:96
_In_opt_ PUSB_CONFIGURATION_DESCRIPTOR _Inout_ PUSBD_INTERFACE_LIST_ENTRY _Outptr_ PURB * Urb
Definition: usbdlib.h:333
_In_ WDFUSBPIPE Pipe
Definition: wdfusb.h:1741

Referenced by UcxPrepareTransfer().

◆ UcxForwardDefaultPipeRequest()

static NTSTATUS NTAPI UcxForwardDefaultPipeRequest ( _In_ WDFDEVICE  RootHubPdo,
_In_ PIRP  Irp,
_In_ PURB  Urb,
_In_ WDFQUEUE  Queue 
)
static

Definition at line 476 of file urbroute.cpp.

481{
482 if (Urb->UrbControlTransfer.TransferFlags & USBD_DEFAULT_PIPE_TRANSFER)
483 Urb->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
484
487}
_In_ PIRP Irp
Definition: kse.h:79
NTSTATUS NTAPI UcxForwardIrpToQueue(_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PIO_COMPLETION_ROUTINE Completion, _In_ PVOID Context, _In_ WDFQUEUE Queue)
Definition: urbroute.cpp:308
static IO_COMPLETION_ROUTINE UcxLegacyTransferCompletion
Definition: urbroute.cpp:272
VOID NTAPI UcxLockTransferBuffer(_Inout_ PURB Urb)
Definition: urbroute.cpp:82
#define USBD_DEFAULT_PIPE_TRANSFER
Definition: usb.h:163
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2231

Referenced by UcxHandleStandardRequest().

◆ UcxForwardIrpToQueue()

NTSTATUS NTAPI UcxForwardIrpToQueue ( _In_ WDFDEVICE  RootHubPdo,
_In_ PIRP  Irp,
_In_ PIO_COMPLETION_ROUTINE  Completion,
_In_ PVOID  Context,
_In_ WDFQUEUE  Queue 
)

Definition at line 308 of file urbroute.cpp.

314{
315 UcxSetCompletionOnNext(RootHubPdo, Irp, Completion, Context);
316
317 WdfDeviceWdmDispatchIrpToIoQueue(RootHubPdo, Irp, Queue, WDF_DISPATCH_IRP_TO_IO_QUEUE_PREPROCESSED_IRP);
318 return STATUS_PENDING;
319}
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define STATUS_PENDING
Definition: telnetd.h:14
static VOID NTAPI UcxSetCompletionOnNext(_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PIO_COMPLETION_ROUTINE Completion, _In_ PVOID Context)
Definition: urbroute.cpp:280
@ WDF_DISPATCH_IRP_TO_IO_QUEUE_PREPROCESSED_IRP
Definition: wdfdevice.h:437

Referenced by UcxForwardDefaultPipeRequest(), UcxForwardStreamsUrb(), UcxHandleIsoch(), UcxProcessLegacyUrb(), and UcxXrbSubmitTransfer().

◆ UcxForwardIrpWithRequest()

NTSTATUS NTAPI UcxForwardIrpWithRequest ( _In_ WDFDEVICE  RootHubPdo,
_In_ PIRP  Irp,
_In_ PIO_COMPLETION_ROUTINE  Completion,
_In_ PVOID  Context,
_In_ WDFQUEUE  Queue,
_In_ WDFREQUEST  Request 
)

Definition at line 323 of file urbroute.cpp.

330{
333
334 UcxSetCompletionOnNext(RootHubPdo, Irp, Completion, Context);
336
338 Status = WdfRequestForwardToParentDeviceIoQueue(Request, Queue, &Options);
339 if (!NT_SUCCESS(Status))
340 {
341 /* A purging queue means a controller reset or a concurrent pipe reset */
342 if (Status == STATUS_WDF_BUSY)
344
345 DPRINT1("Forwarding request %p (IRP %p) to queue %p failed 0x%lx\n", Request, Irp, Queue, Status);
346 WdfRequestComplete(Request, Status);
347 }
348
349 return STATUS_PENDING;
350}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST Request
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3540
FORCEINLINE VOID WDF_REQUEST_FORWARD_OPTIONS_INIT(_Out_ PWDF_REQUEST_FORWARD_OPTIONS ForwardOptions)
Definition: wdfrequest.h:453
#define STATUS_WDF_BUSY
Definition: wdfstatus.h:126
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2706

Referenced by UcxXrbSubmitTransfer().

◆ UcxGetWord()

static USHORT NTAPI UcxGetWord ( _In_reads_bytes_(2) const UCHAR *  Where)
static

Definition at line 466 of file urbroute.cpp.

468{
469 return (USHORT)(Where[0] | (Where[1] << 8));
470}
unsigned short USHORT
Definition: pedump.c:61

Referenced by UcxHandleStandardRequest().

◆ UcxHandleGetCurrentFrame()

static NTSTATUS NTAPI UcxHandleGetCurrentFrame ( _In_ PIRP  Irp,
_In_ PURB  Urb,
_In_ UcxUsbDevice *  Device 
)
static

Definition at line 619 of file urbroute.cpp.

623{
624 ULONG Frame = 0;
626
627 Status = Device->m_Controller->GetCurrentFrameNumber(&Frame);
628 if (!NT_SUCCESS(Status))
629 {
630 DPRINT1("Getting the current frame for URB %p failed 0x%lx\n", Urb, Status);
631 Frame = 0;
632 }
633
634 Urb->UrbGetCurrentFrameNumber.FrameNumber = Frame;
636}
NTSTATUS NTAPI UcxCompleteUrb(_In_ PIRP Irp, _In_ PURB Urb, _In_ NTSTATUS Status, _In_ USBD_STATUS UsbdStatus)
Definition: clientxrb.cpp:23
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
USBD_STATUS NTAPI UcxNtStatusToUsbdStatus(_In_ NTSTATUS Status)
Definition: urbroute.cpp:53

Referenced by UcxProcessLegacyUrb().

◆ UcxHandleIsoch()

static NTSTATUS NTAPI UcxHandleIsoch ( _In_ WDFDEVICE  RootHubPdo,
_In_ PIRP  Irp,
_In_ PURB  Urb,
_In_ WDFQUEUE  Queue,
_In_ UcxPipe *  Pipe 
)
static

Definition at line 574 of file urbroute.cpp.

580{
581 struct _URB_ISOCH_TRANSFER* Isoch = &Urb->UrbIsochronousTransfer;
582 ULONG Packets = Isoch->NumberOfPackets;
583
584 if (Isoch->TransferBufferLength == 0 && Isoch->TransferBufferMDL == NULL && Isoch->TransferBuffer == NULL)
585 {
586 DPRINT1("Isoch URB %p has no buffer\n", Urb);
588 }
589
590 if (Pipe->IsochPeriodMicroframes > 8)
591 {
592 DPRINT1("Isoch URB %p on pipe %p has period %lu microframes\n", Urb, Pipe, Pipe->IsochPeriodMicroframes);
593 Isoch->StartFrame = 0;
595 }
596
597 /* Only the frame alignment failure resets StartFrame */
598 if (Packets != 0 && (Packets * Pipe->IsochPeriodMicroframes) % 8 != 0)
599 {
600 DPRINT1("Isoch URB %p: %lu packets do not fill whole frames\n", Urb, Packets);
601 Isoch->StartFrame = 0;
603 }
604
605 if (Packets == 0 || Packets > Pipe->IsochPacketLimit)
606 {
607 DPRINT1("Isoch URB %p has bad packet count %lu, max %lu\n", Urb, Packets, Pipe->IsochPacketLimit);
609 }
610
614}
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
FORCEINLINE VOID NTAPI UcxSetTransferDirection(_Inout_ PURB Urb, _In_ const UcxPipe *Pipe)
Definition: urbroute.h:48

Referenced by UcxProcessLegacyUrb().

◆ UcxHandleStandardRequest()

static NTSTATUS NTAPI UcxHandleStandardRequest ( _In_ WDFDEVICE  RootHubPdo,
_In_ PIRP  Irp,
_In_ PURB  Urb,
_In_ WDFQUEUE  Queue,
_In_ const UcxUrbFunction *  Function 
)
static

Definition at line 492 of file urbroute.cpp.

498{
500 PULONG Flags = &Urb->UrbControlTransfer.TransferFlags;
502
504
505 switch (Function->Handler)
506 {
508 Setup[0] = UcxRequestType(Function->Direction, Function->Type, Function->Recipient);
509 Setup[1] = Function->Request;
510 break;
511
513 Urb->UrbControlTransfer.TransferBufferLength = 0;
514 Setup[0] = UcxRequestType(Function->Direction, Function->Type, Function->Recipient);
515 Setup[1] = Function->Request;
516 break;
517
520 Setup[0] = UcxRequestType(Function->Direction, Function->Type, Function->Recipient);
521 Setup[1] = Function->Request;
522 UcxSetWord(&Setup[2], 0);
523 break;
524
526 Setup[0] = UcxRequestType(Function->Direction, Function->Type, Function->Recipient);
527 Setup[1] = Function->Request;
528 UcxSetWord(&Setup[2], 0);
529 UcxSetWord(&Setup[4], 0);
530 break;
531
532 /* The client's direction bit and reserved request type bits are kept */
535 Function->Type,
536 Function->Recipient) |
537 (Setup[0] & 0x1C));
538 break;
539
540 /* The recipient comes from the client, the request code from the hub */
542 Setup[0] = (UCHAR)(UcxRequestType(UCX_DIR_IN, UCX_RT_VENDOR, 0) | (Setup[0] & 0x1F));
543 break;
544
545 default:
547 break;
548 }
549
550 if (Function->Handler != UcxUrbHandler::VendorClass)
551 {
552 if (Function->Direction == UCX_DIR_IN)
554 else
555 *Flags &= ~USBD_TRANSFER_DIRECTION_IN;
556 }
557
558 Length = (USHORT)Urb->UrbControlTransfer.TransferBufferLength;
559 UcxSetWord(&Setup[6], Length);
560
561 /* The setup bytes stay written even when this fails */
562 if (Function->Handler == UcxUrbHandler::GetStatus && UcxGetWord(&Setup[6]) != sizeof(USHORT))
563 {
564 DPRINT1("GET_STATUS URB %p has wLength %u, expected 2\n", Urb, UcxGetWord(&Setup[6]));
566 }
567
568 return UcxForwardDefaultPipeRequest(RootHubPdo, Irp, Urb, Queue);
569}
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE ACPI_HANDLE ACPI_HANDLE *OutHandle ACPI_HANDLE *OutHandle void *Context void *Context ACPI_EVENT_HANDLER Handler UINT32 UINT32 ACPI_GPE_HANDLER void *Context UINT32 ACPI_NOTIFY_HANDLER void *Context ACPI_ADR_SPACE_TYPE ACPI_ADR_SPACE_HANDLER ACPI_ADR_SPACE_SETUP Setup
Definition: acpixf.h:834
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: typedefs.h:53
unsigned char * PUCHAR
Definition: typedefs.h:53
#define UCX_RT_VENDOR
Definition: urbroute.cpp:188
static NTSTATUS NTAPI UcxForwardDefaultPipeRequest(_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PURB Urb, _In_ WDFQUEUE Queue)
Definition: urbroute.cpp:476
#define UCX_DIR_IN
Definition: urbroute.cpp:172
static VOID NTAPI UcxSetWord(_Out_writes_bytes_(2) PUCHAR Where, _In_ USHORT Value)
Definition: urbroute.cpp:455
static USHORT NTAPI UcxGetWord(_In_reads_bytes_(2) const UCHAR *Where)
Definition: urbroute.cpp:466
static UCHAR NTAPI UcxRequestType(_In_ UCHAR Direction, _In_ UCHAR Type, _In_ UCHAR Recipient)
Definition: urbroute.cpp:444
static PUCHAR NTAPI UcxSetupPacket(_In_ PURB Urb)
Definition: urbroute.cpp:435
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:167
#define USBD_SHORT_TRANSFER_OK
Definition: usb.h:161
#define NT_ASSERT
Definition: rtlfuncs.h:3334

Referenced by UcxProcessLegacyUrb().

◆ UcxLegacyTransferCompletion()

static NTSTATUS NTAPI UcxLegacyTransferCompletion ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_reads_opt_(_Inexpressible_("varies")) PVOID  Context 
)
static

Definition at line 871 of file urbroute.cpp.

875{
876 PURB Urb = (PURB)Context;
877 UcxUsbDevice* Device = UcxUsbDevice::FromHandle((UCXUSBDEVICE)Urb->UrbHeader.UsbdDeviceHandle);
878 USBD_STATUS UsbdStatus = Urb->UrbHeader.Status;
879 NTSTATUS Status = Irp->IoStatus.Status;
880 ULONG Index;
881
883
884 /* The byte count lives in the URB only */
885 Irp->IoStatus.Information = 0;
886
888 {
889 /* The HCD never saw it: purged, canceled while queued or refused */
890 DPRINT("URB %p function 0x%x canceled before reaching the HCD\n", Urb, Urb->UrbHeader.Function);
891 Urb->UrbHeader.Status = USBD_STATUS_CANCELED;
892 Irp->IoStatus.Status = STATUS_CANCELLED;
893 Urb->UrbControlTransfer.TransferBufferLength = 0;
894
895 if (Urb->UrbHeader.Function == URB_FUNCTION_ISOCH_TRANSFER)
896 {
897 for (Index = 0; Index < Urb->UrbIsochronousTransfer.NumberOfPackets; Index++)
898 Urb->UrbIsochronousTransfer.IsoPacket[Index].Status = 0xFFFFFFFF;
899 Urb->UrbIsochronousTransfer.ErrorCount = 0;
900 }
901
902 Device->m_TransferFailureCount++;
903 }
904 else if (!USBD_SUCCESS(UsbdStatus))
905 {
906 DPRINT("URB %p function 0x%x on device %p failed, USBD status 0x%lx\n",
907 Urb, Urb->UrbHeader.Function, Device, UsbdStatus);
908 Device->m_TransferFailureCount++;
909 Device->ReportNoPingResponseIfPending();
910 Irp->IoStatus.Status = UcxUsbdStatusToNtStatus(UsbdStatus);
911 }
912 else if (!NT_SUCCESS(Status))
913 {
914 DPRINT1("URB %p succeeded but its IRP %p failed 0x%lx\n", Urb, Irp, Status);
916 Urb->UrbHeader.Status = UcxNtStatusToUsbdStatus(Status);
917 }
918
919 if (Irp->PendingReturned)
921
923
924 if (UcxIsXrbIrp(Irp, Urb))
926
928}
static UcxUsbDevice * FromHandle(_In_ UCXUSBDEVICE Handle)
Definition: devobj.cpp:18
FORCEINLINE VOID NTAPI UcxXrbMarkInactive(_In_ PURB Urb)
Definition: clientxrb.h:90
FORCEINLINE BOOLEAN NTAPI UcxIsXrbIrp(_In_ PIRP Irp, _In_ PURB Urb)
Definition: clientxrb.h:79
IoMarkIrpPending(Irp)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define DPRINT
Definition: sndvol32.h:73
Definition: usb.h:565
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
NTSTATUS NTAPI UcxUsbdStatusToNtStatus(_In_ USBD_STATUS UsbdStatus)
Definition: urbroute.cpp:18
VOID NTAPI UcxUnlockTransferBuffer(_Inout_ PURB Urb)
Definition: urbroute.cpp:130
struct _URB * PURB
#define USBD_STATUS_CANCELED
Definition: usb.h:225
#define USBD_SUCCESS(Status)
Definition: usb.h:174
#define USBD_STATUS_PENDING
Definition: usb.h:179
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ NTSTATUS _In_ USBD_STATUS UsbdStatus
Definition: wdfusb.h:403
#define STATUS_CONTINUE_COMPLETION

◆ UcxLockTransferBuffer()

VOID NTAPI UcxLockTransferBuffer ( _Inout_ PURB  Urb)

Below DISPATCH_LEVEL, locks a buffer passed without an MDL so the HCD can map it.

Definition at line 82 of file urbroute.cpp.

84{
85 struct _URB_CONTROL_TRANSFER* Transfer = &Urb->UrbControlTransfer;
87 PMDL Mdl;
88
89 Urb->UrbHeader.UsbdFlags &= ~UCX_URB_FLAG_BUFFER_LOCKED;
90
91 /* At DISPATCH_LEVEL the buffer has to be resident already */
93 Transfer->TransferBufferMDL != NULL ||
94 Transfer->TransferBuffer == NULL ||
95 Transfer->TransferBufferLength == 0)
96 {
97 return;
98 }
99
101 if (Mdl == NULL)
102 {
103 DPRINT1("No MDL for the %lu byte buffer of URB %p\n", Transfer->TransferBufferLength, Urb);
104 return;
105 }
106
108
110 {
112 }
114 {
115 DPRINT1("Locking the buffer of URB %p failed 0x%lx\n", Urb, _SEH2_GetExceptionCode());
116 IoFreeMdl(Mdl);
117 Mdl = NULL;
118 }
119 _SEH2_END;
120
121 if (Mdl == NULL)
122 return;
123
124 Transfer->TransferBufferMDL = Mdl;
125 Urb->UrbHeader.UsbdFlags |= UCX_URB_FLAG_BUFFER_LOCKED;
126}
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FP_OP Operation
Definition: fpcontrol.c:150
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:928
#define KernelMode
Definition: asm.h:38
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
PMDL TransferBufferMDL
Definition: usb.h:484
ULONG TransferFlags
Definition: usb.h:481
ULONG TransferBufferLength
Definition: usb.h:482
PVOID TransferBuffer
Definition: usb.h:483
#define UCX_URB_FLAG_BUFFER_LOCKED
Definition: urbroute.h:14
enum _LOCK_OPERATION LOCK_OPERATION
@ IoReadAccess
Definition: ketypes.h:931
@ IoWriteAccess
Definition: ketypes.h:932

Referenced by UcxForwardDefaultPipeRequest(), UcxHandleIsoch(), UcxProcessLegacyUrb(), and UcxXrbSubmitTransfer().

◆ UcxNtStatusToUsbdStatus()

USBD_STATUS NTAPI UcxNtStatusToUsbdStatus ( _In_ NTSTATUS  Status)

Definition at line 53 of file urbroute.cpp.

55{
56 switch (Status)
57 {
58 case STATUS_SUCCESS:
60
63
66
69
72
73 default:
75 }
76}
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define USBD_STATUS_DEVICE_GONE
Definition: usb.h:222
#define USBD_STATUS_NOT_SUPPORTED
Definition: usb.h:213
#define USBD_STATUS_INSUFFICIENT_RESOURCES
Definition: usb.h:215

Referenced by UcxEndpoint::AbortPipe(), UcxEndpoint::GetIsochPathDelays(), UcxFailStreamsUrb(), UcxHandleGetCurrentFrame(), and UcxLegacyTransferCompletion().

◆ UcxPrepareTransfer()

static USBD_STATUS NTAPI UcxPrepareTransfer ( _In_ PURB  Urb,
_In_ UcxUsbDevice *  Device,
_In_ const UcxUrbFunction *  Function,
_Outptr_ UcxPipe **  TargetPipe 
)
static

Returns USBD_STATUS_SUCCESS with the target pipe, or the status to fail with.

Definition at line 680 of file urbroute.cpp.

685{
686 struct _URB_CONTROL_TRANSFER* Transfer = &Urb->UrbControlTransfer;
687 USHORT Code = Urb->UrbHeader.Function;
688 UcxPipe* Pipe;
690
691 *TargetPipe = NULL;
692
694
695 if (Function->Flags & UCX_URB_DEFAULT_PIPE)
696 {
697 Transfer->PipeHandle = Device->m_DefaultPipe->Handle();
699 }
700
701 if ((Transfer->TransferFlags & USBD_DEFAULT_PIPE_TRANSFER) &&
702 (Code == URB_FUNCTION_CONTROL_TRANSFER || Code == URB_FUNCTION_CONTROL_TRANSFER_EX))
703 {
704 Transfer->PipeHandle = Device->m_DefaultPipe->Handle();
705 }
706
707 /* UrbLink must be unused; the _EX form keeps its Timeout in the same slot */
708 if (Transfer->UrbLink != NULL && Code != URB_FUNCTION_CONTROL_TRANSFER_EX)
710
711 if (Function->Flags & UCX_URB_NO_DATA)
712 {
713 Transfer->TransferBuffer = NULL;
714 Transfer->TransferBufferMDL = NULL;
715 Transfer->TransferBufferLength = 0;
716 }
717
718 if (!UcxValidatePipeHandle(Device, Transfer->PipeHandle))
720
722
725
728 return Error;
729
730 /* A buffer with zero length is accepted, a length with no buffer is not */
731 if (Transfer->TransferBufferLength != 0 && Transfer->TransferBuffer == NULL && Transfer->TransferBufferMDL == NULL)
733
734 if (Transfer->TransferBufferLength == 0 && Transfer->TransferBufferMDL != NULL)
736
737 if (Pipe->TransferType == UcxTransferType::Control &&
738 ((Transfer->TransferBufferLength > Pipe->MaximumTransferSize &&
739 !(Urb->UrbHeader.UsbdFlags & UCXHUB_URB_FLAG_ALLOW_LARGE_TRANSFER)) ||
741 {
743 }
744
745 /* Only fatal under verifier; the HCD copes otherwise */
746 if (Transfer->TransferBufferMDL != NULL &&
748 Device->m_Controller->m_DriverVerifierEnabled)
749 {
750 DPRINT1("URB %p has an unaligned chained MDL %p\n", Urb, Transfer->TransferBufferMDL);
751 KeBugCheckEx(0x144, 0x807, (ULONG_PTR)Transfer->TransferBufferMDL, (ULONG_PTR)Urb, 0);
752 }
753
754 *TargetPipe = Pipe;
755 return USBD_STATUS_SUCCESS;
756}
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
Definition: pipe.h:30
static UcxPipe * FromHandle(_In_ USBD_PIPE_HANDLE Handle)
Definition: pipe.h:53
struct _URB * UrbLink
Definition: usb.h:485
USBD_PIPE_HANDLE PipeHandle
Definition: usb.h:480
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define UCX_URB_NO_DATA
Definition: urbroute.cpp:167
#define UCX_URB_DEFAULT_PIPE
Definition: urbroute.cpp:166
BOOLEAN NTAPI UcxValidatePipeHandle(_In_ UcxUsbDevice *Device, _In_ USBD_PIPE_HANDLE Handle)
Definition: urbroute.cpp:356
static BOOLEAN NTAPI UcxChainedMdlMisaligned(_In_ PMDL Mdl, _In_ ULONG Length)
Definition: urbroute.cpp:399
static USBD_STATUS NTAPI UcxCheckTransferAgainstPipe(_In_ PURB Urb, _In_ const UcxPipe *Pipe)
Definition: urbroute.cpp:642
FORCEINLINE VOID NTAPI UcxStampProcessorNumber(_Inout_ PURB Urb)
Definition: urbroute.h:32
_In_ UCHAR _In_ UCHAR _In_ ULONG Code
Definition: wdfdevice.h:1707

Referenced by UcxProcessLegacyUrb().

◆ UcxProcessLegacyUrb()

NTSTATUS NTAPI UcxProcessLegacyUrb ( _In_ WDFDEVICE  RootHubPdo,
_In_ PIRP  Irp,
_In_ PURB  Urb 
)

Validates and routes a URB the way USBPORT did. Owns the IRP afterwards.

Definition at line 760 of file urbroute.cpp.

764{
767 UcxPipe* Pipe = NULL;
769 USHORT Code;
770
771 /* Short headers are not rejected */
772 Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
773 Code = Urb->UrbHeader.Function;
774 Urb->UrbHeader.UsbdFlags &= UCX_URB_FLAGS_KEEP_HUB_BITS;
775
777 {
778 DPRINT1("URB %p has unknown function 0x%x\n", Urb, Code);
780 }
781
783
784 if (Function->Length != 0 && Function->Length != Urb->UrbHeader.Length)
785 {
786 DPRINT1("URB %p function 0x%x has length %u, expected %u\n", Urb, Code, Urb->UrbHeader.Length, Function->Length);
788 }
789
790 /* The hub fills in its UCXUSBDEVICE */
791 if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
792 {
793 DPRINT1("URB %p function 0x%x has no device handle\n", Urb, Code);
795 }
796
797 Device = UcxUsbDevice::FromHandle((UCXUSBDEVICE)Urb->UrbHeader.UsbdDeviceHandle);
798
799 if (Device->m_Disconnected)
800 {
801 DPRINT("URB %p function 0x%x for disconnected device %p\n", Urb, Code, Device);
803 }
804
805 if (Function->Flags & UCX_URB_TRANSFER)
806 {
809 {
810 DPRINT1("Transfer URB %p function 0x%x on device %p rejected, USBD status 0x%lx\n", Urb, Code, Device, Error);
812 }
813 }
814 else if (Function->Flags & UCX_URB_PIPE_REQUEST)
815 {
816 if (!UcxValidatePipeHandle(Device, Urb->UrbPipeRequest.PipeHandle))
817 {
818 DPRINT1("Pipe URB %p function 0x%x has invalid pipe %p\n", Urb, Code, Urb->UrbPipeRequest.PipeHandle);
820 }
821
822 Pipe = UcxPipe::FromHandle(Urb->UrbPipeRequest.PipeHandle);
823
824 /* Zero bandwidth pipes are not in the schedule; pipe requests on them just succeed */
827 }
828
829 /* Tells the completion routine whether the HCD ever saw it */
830 Urb->UrbHeader.Status = USBD_STATUS_PENDING;
831
832 switch (Function->Handler)
833 {
835 DPRINT1("URB %p function 0x%x is not supported\n", Urb, Code);
838
840 DPRINT1("URB %p has invalid function 0x%x\n", Urb, Code);
842
844 return Pipe->Endpoint->AbortPipe(Irp, Urb);
845
848
851 return UcxForwardIrpToQueue(RootHubPdo, Irp, UcxLegacyTransferCompletion, Urb, Pipe->Queue);
852
856 return UcxForwardIrpToQueue(RootHubPdo, Irp, UcxLegacyTransferCompletion, Urb, Pipe->Queue);
857
859 return UcxHandleIsoch(RootHubPdo, Irp, Urb, Pipe->Queue, Pipe);
860
861 default:
862 return UcxHandleStandardRequest(RootHubPdo, Irp, Urb, Pipe->Queue, Function);
863 }
864}
#define ARRAYSIZE(a)
Definition: cat.c:25
#define Code
Definition: deflate.h:80
#define UCX_URB_PIPE_REQUEST
Definition: urbroute.cpp:168
static USBD_STATUS NTAPI UcxPrepareTransfer(_In_ PURB Urb, _In_ UcxUsbDevice *Device, _In_ const UcxUrbFunction *Function, _Outptr_ UcxPipe **TargetPipe)
Definition: urbroute.cpp:680
static NTSTATUS NTAPI UcxHandleStandardRequest(_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PURB Urb, _In_ WDFQUEUE Queue, _In_ const UcxUrbFunction *Function)
Definition: urbroute.cpp:492
static NTSTATUS NTAPI UcxHandleGetCurrentFrame(_In_ PIRP Irp, _In_ PURB Urb, _In_ UcxUsbDevice *Device)
Definition: urbroute.cpp:619
static NTSTATUS NTAPI UcxHandleIsoch(_In_ WDFDEVICE RootHubPdo, _In_ PIRP Irp, _In_ PURB Urb, _In_ WDFQUEUE Queue, _In_ UcxPipe *Pipe)
Definition: urbroute.cpp:574
#define UCX_URB_TRANSFER
Definition: urbroute.cpp:165
static const UcxUrbFunction UcxUrbFunctions[]
Definition: urbroute.cpp:211
#define UCX_URB_FLAGS_KEEP_HUB_BITS
Definition: urbroute.h:11
#define USBD_STATUS_INVALID_URB_FUNCTION
Definition: usb.h:202

Referenced by UcxProcessSubmitUrb().

◆ UcxRequestType()

static UCHAR NTAPI UcxRequestType ( _In_ UCHAR  Direction,
_In_ UCHAR  Type,
_In_ UCHAR  Recipient 
)
static

Definition at line 444 of file urbroute.cpp.

448{
449 return (UCHAR)((Direction << 7) | (Type << 5) | Recipient);
450}
Type
Definition: Type.h:7
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION Direction

Referenced by UcxHandleStandardRequest().

◆ UcxSetCompletionOnNext()

static VOID NTAPI UcxSetCompletionOnNext ( _In_ WDFDEVICE  RootHubPdo,
_In_ PIRP  Irp,
_In_ PIO_COMPLETION_ROUTINE  Completion,
_In_ PVOID  Context 
)
static

Keeps the PDO's driver loaded until the routine ran when the system allows it.

Definition at line 280 of file urbroute.cpp.

285{
287
290
291 Status = IoSetCompletionRoutineEx(WdfDeviceWdmGetDeviceObject(RootHubPdo),
292 Irp,
293 Completion,
294 Context,
295 TRUE,
296 TRUE,
297 TRUE);
298 if (!NT_SUCCESS(Status))
299 {
300 DPRINT("IoSetCompletionRoutineEx failed 0x%lx for IRP %p, using the plain routine\n", Status, Irp);
302 }
303}
NTSTATUS NTAPI IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_COMPLETION_ROUTINE CompletionRoutine, IN PVOID Context, IN BOOLEAN InvokeOnSuccess, IN BOOLEAN InvokeOnError, IN BOOLEAN InvokeOnCancel)
Definition: iocomp.c:220
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413

Referenced by UcxForwardIrpToQueue(), and UcxForwardIrpWithRequest().

◆ UcxSetupPacket()

static PUCHAR NTAPI UcxSetupPacket ( _In_ PURB  Urb)
static

Definition at line 435 of file urbroute.cpp.

437{
438 return Urb->UrbControlTransfer.SetupPacket;
439}

Referenced by UcxHandleStandardRequest().

◆ UcxSetWord()

static VOID NTAPI UcxSetWord ( _Out_writes_bytes_(2) PUCHAR  Where,
_In_ USHORT  Value 
)
static

Definition at line 455 of file urbroute.cpp.

458{
459 Where[0] = (UCHAR)(Value & 0xFF);
460 Where[1] = (UCHAR)(Value >> 8);
461}
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by UcxHandleStandardRequest().

◆ UcxUnlockTransferBuffer()

VOID NTAPI UcxUnlockTransferBuffer ( _Inout_ PURB  Urb)

Definition at line 130 of file urbroute.cpp.

132{
133 struct _URB_CONTROL_TRANSFER* Transfer = &Urb->UrbControlTransfer;
134
135 if (!(Urb->UrbHeader.UsbdFlags & UCX_URB_FLAG_BUFFER_LOCKED))
136 return;
137
139 IoFreeMdl(Transfer->TransferBufferMDL);
140 Transfer->TransferBufferMDL = NULL;
141 Urb->UrbHeader.UsbdFlags &= ~UCX_URB_FLAG_BUFFER_LOCKED;
142}
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1432

Referenced by UcxLegacyTransferCompletion(), and UcxXrbTransferCompletion().

◆ UcxUsbdStatusToNtStatus()

NTSTATUS NTAPI UcxUsbdStatusToNtStatus ( _In_ USBD_STATUS  UsbdStatus)

Definition at line 18 of file urbroute.cpp.

20{
21 switch (UsbdStatus)
22 {
25 return STATUS_SUCCESS;
26
29
35
38
41
43 return STATUS_CANCELLED;
44
45 default:
47 }
48}
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define USBD_STATUS_PORT_OPERATION_PENDING
Definition: usb.h:178
#define USBD_STATUS_BAD_START_FRAME
Definition: usb.h:209

Referenced by UcxLegacyTransferCompletion(), UcxProcessLegacyUrb(), UcxXrbStreamsCompletion(), and UcxXrbTransferCompletion().

◆ UcxValidatePipeHandle()

BOOLEAN NTAPI UcxValidatePipeHandle ( _In_ UcxUsbDevice *  Device,
_In_ USBD_PIPE_HANDLE  Handle 
)

Definition at line 356 of file urbroute.cpp.

359{
363
364 if (Pipe != NULL && !Pipe->BelongsToStream)
365 {
366 if (Device->m_StalePipeIoAllowed)
367 {
368 SpinLockGuard Guard(&Device->m_TrackingLock);
369
370 for (Entry = Device->m_TrackingList.Flink; Entry != &Device->m_TrackingList; Entry = Entry->Flink)
371 {
372 if (&CONTAINING_RECORD(Entry, UcxEndpoint, m_TrackingLink)->m_Pipe == Pipe)
373 {
374 Valid = TRUE;
375 break;
376 }
377 }
378 }
379 else
380 {
381 Valid = Pipe->IsValid();
382 }
383 }
384
386 {
387 DPRINT1("Client used invalid pipe handle %p on device %p\n", Handle, Device);
390 }
391
392 return Valid;
393}
BOOLEAN NTAPI UcxAnyUsbdHandleHasVerifier(_In_ UcxUsbDevice *Device)
Definition: clientif.cpp:646
BOOLEAN Valid
Definition: desccheck.cpp:2227
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
ULONG Handle
Definition: gdb_input.c:15
BOOLEAN NTAPI KdRefreshDebuggerNotPresent(VOID)
Definition: kdapi.c:2679
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
NTSYSAPI void WINAPI DbgBreakPoint(void)

Referenced by UcxPrepareTransfer(), and UcxProcessLegacyUrb().

Variable Documentation

◆ UcxLegacyTransferCompletion

IO_COMPLETION_ROUTINE UcxLegacyTransferCompletion
static

Definition at line 272 of file urbroute.cpp.

Referenced by UcxForwardDefaultPipeRequest(), UcxHandleIsoch(), and UcxProcessLegacyUrb().

◆ UcxUrbFunctions

const UcxUrbFunction UcxUrbFunctions[]
static

Definition at line 211 of file urbroute.cpp.

Referenced by UcxProcessLegacyUrb().