ReactOS 0.4.17-dev-1321-g5c122a9
usbdex.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS USB Driver Library
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: USBD handle, capability query and URB allocation for client drivers
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "usbdex.h"
9
10#define USBDEX_HANDLE_SIGNATURE 'DBSU'
11
12/* Handle modes; the UCX value is the client interface version it negotiated */
13#define USBDEX_MODE_UCX USBD_INTERFACE_VERSION_602
14#define USBDEX_MODE_LEGACY USBD_INTERFACE_VERSION_600
15#define USBDEX_MODE_NONE 0xFFFFFFFF
16
17/* POOL_TYPE value for no-execute nonpaged pool on NT 6.2 and later */
18#define USBDEX_NONPAGED_POOL_NX ((POOL_TYPE)0x200)
19
20#define USBDEX_PIPE_MAX_TRANSFER_DEFAULT 0xFFFFFFFF
21#define USBDEX_SELECT_INTERFACE_MAX_PIPES 32
22#define USBDEX_COMPOSITE_VERSION 0x0100
23
24typedef
27 _In_ ULONG RelativeTo,
32
33/* What a USBD_HANDLE points to; private to each client binary */
35{
44
47
48static IO_COMPLETION_ROUTINE UsbdexSyncCompletion;
49static RTL_QUERY_REGISTRY_ROUTINE UsbdexVerifierValueCallback;
50
54 _In_opt_ USBD_HANDLE USBDHandle)
55{
57}
58
63{
64 return Handle->Mode != USBDEX_MODE_NONE && Handle->Mode >= USBDEX_MODE_UCX;
65}
66
67static
68VOID
70{
72
74 return;
75
77
79 OsVersion.dwOSVersionInfoSize = sizeof(OsVersion);
81 {
82 if (OsVersion.dwMajorVersion > 6 ||
83 (OsVersion.dwMajorVersion == 6 && OsVersion.dwMinorVersion >= 2))
84 {
86 }
87 }
88
90}
91
92static
98 _In_reads_opt_(_Inexpressible_("varies")) PVOID Context)
99{
102
105}
106
107/* Sends a prepared IRP, waits for it, frees it and returns its final status */
108static
111 _In_ PDEVICE_OBJECT ClientDevice,
114{
115 KEVENT Done;
117
119
121 if (!NT_SUCCESS(Status))
123
125 if (Status == STATUS_PENDING)
126 {
128 Status = Irp->IoStatus.Status;
129 }
130
131 IoFreeIrp(Irp);
132 return Status;
133}
134
135static
138 _In_ PDEVICE_OBJECT ClientDevice,
140 _In_ const GUID *InterfaceType,
142{
144 PIRP Irp;
145
146 Irp = IoAllocateIrp(Target->StackSize, FALSE);
147 if (!Irp)
149
150 /* PnP IRPs must start out as not supported */
151 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
152
154 Stack->MajorFunction = IRP_MJ_PNP;
155 Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
156 Stack->Parameters.QueryInterface.InterfaceType = InterfaceType;
157 Stack->Parameters.QueryInterface.Size = Interface->Size;
158 Stack->Parameters.QueryInterface.Version = Interface->Version;
159 Stack->Parameters.QueryInterface.Interface = Interface;
160 Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
161
162 return UsbdexCallAndWait(ClientDevice, Target, Irp);
163}
164
165static
168 _In_ PDEVICE_OBJECT ClientDevice,
172{
174 PIRP Irp;
175
176 Irp = IoAllocateIrp(Target->StackSize, FALSE);
177 if (!Irp)
179
180 Irp->AssociatedIrp.SystemBuffer = OutputBuffer;
181
183 Stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
184 Stack->MinorFunction = 0;
185 Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_UCXHUB_QUERY_USB_CAPABILITY;
186 Stack->Parameters.Others.Argument1 = Request;
187
188 return UsbdexCallAndWait(ClientDevice, Target, Irp);
189}
190
191static
193NTAPI
201{
204
205 if (ValueType != REG_DWORD)
207
208 if (ValueLength != sizeof(ULONG))
210
211 /* A missing value comes back as the default, which already is the destination */
212 if (ValueData != EntryContext)
214
215 return STATUS_SUCCESS;
216}
217
219static
220PWSTR
224{
225 static const WCHAR DriverPrefix[] = L"\\Driver\\";
226 static const WCHAR ParametersSuffix[] = L"\\Parameters";
227 const SIZE_T PrefixBytes = sizeof(DriverPrefix) - sizeof(WCHAR);
228 PUNICODE_STRING DriverName = &DriverObject->DriverName;
229 SIZE_T ServiceBytes;
230 SIZE_T PathBytes;
231 PWSTR Path;
232
233 if (DriverName->Length <= PrefixBytes)
234 return NULL;
235
236 if (!RtlEqualMemory(DriverName->Buffer, DriverPrefix, PrefixBytes))
237 return NULL;
238
239 ServiceBytes = DriverName->Length - PrefixBytes;
240 PathBytes = ServiceBytes + sizeof(ParametersSuffix);
241
243 if (!Path)
244 return NULL;
245
246 RtlCopyMemory(Path, (PUCHAR)DriverName->Buffer + PrefixBytes, ServiceBytes);
247 RtlCopyMemory((PUCHAR)Path + ServiceBytes, ParametersSuffix, sizeof(ParametersSuffix));
248 return Path;
249}
250
251/* Loads the UsbVerifier* overrides from the client's Parameters key into its interface */
252static
253VOID
256 _In_z_ PCWSTR ParametersPath,
259{
260 PCWSTR ValueNames[] =
261 {
262 L"UsbVerifierEnabled",
263 L"UsbVerifierFailRegistration",
264 L"UsbVerifierFailChainedMdlSupport",
265 L"UsbVerifierFailStaticStreamSupport",
266 L"UsbVerifierStaticStreamCountOverride",
267 L"UsbVerifierFailEnableStaticStreams",
268 };
269 PULONG Fields[] =
270 {
271 &Client->VerifierEnabled,
272 &Client->VerifierFailRegistration,
273 &Client->VerifierFailChainedMdlSupport,
274 &Client->VerifierFailStaticStreamSupport,
275 &Client->VerifierStaticStreamCountOverride,
276 &Client->VerifierFailEnableStaticStreams,
277 };
279 PFN_USBDEX_QUERY_REGISTRY QueryValues;
281 SIZE_T TableBytes;
282 ULONG Index;
283
284 C_ASSERT(RTL_NUMBER_OF(ValueNames) == RTL_NUMBER_OF(Fields));
285
286 Client->VerifierEnabled = MmIsDriverVerifying(DriverObject) ? 1 : 0;
287
288 /* One extra zeroed entry terminates the table */
289 TableBytes = (RTL_NUMBER_OF(ValueNames) + 1) * sizeof(*Table);
291 if (!Table)
292 return;
293
294 for (Index = 0; Index < RTL_NUMBER_OF(ValueNames); Index++)
295 {
297 Table[Index].Flags = 0;
298 Table[Index].Name = (PWSTR)ValueNames[Index];
299 Table[Index].EntryContext = Fields[Index];
300 Table[Index].DefaultType = REG_DWORD;
301 Table[Index].DefaultData = Fields[Index];
302 Table[Index].DefaultLength = sizeof(ULONG);
303 }
304
305 RtlInitUnicodeString(&RoutineName, L"RtlQueryRegistryValuesEx");
307 if (!QueryValues)
308 QueryValues = RtlQueryRegistryValues;
309
310 (VOID)QueryValues(RTL_REGISTRY_SERVICES, ParametersPath, Table, NULL, NULL);
311
313}
314
315/* Asks a USB 2 era bus driver for its USBDI interface; returns the resulting handle mode */
316static
317ULONG
320{
321 USB_BUS_INTERFACE_USBDI_V1 BusInterface;
323
324 RtlZeroMemory(&BusInterface, sizeof(BusInterface));
325 BusInterface.Size = sizeof(BusInterface);
326 BusInterface.Version = USB_BUSIF_USBDI_VERSION_1;
327
328 Status = UsbdexQueryInterface(Handle->Client.DeviceObject,
329 Handle->TargetDeviceObject,
330 &USB_BUS_INTERFACE_USBDI_GUID,
331 (PINTERFACE)&BusInterface);
332 if (!NT_SUCCESS(Status))
333 return USBDEX_MODE_NONE;
334
335 if (BusInterface.IsDeviceHighSpeed)
336 Handle->HighSpeed = BusInterface.IsDeviceHighSpeed(BusInterface.BusContext);
337
338 /* The bus driver referenced the interface while answering; this is the only use of it */
339 if (BusInterface.InterfaceDereference)
340 BusInterface.InterfaceDereference(BusInterface.BusContext);
341
342 return USBDEX_MODE_LEGACY;
343}
344
345static
349{
350 if (Handle->CloseRequested || Handle->ReferenceCount < 1)
352
353 InterlockedIncrement(&Handle->ReferenceCount);
354 return STATUS_SUCCESS;
355}
356
357static
358VOID
361{
362 if (InterlockedDecrement(&Handle->ReferenceCount) > 0)
363 return;
364
365 /* Only a closed handle goes away; anything else is a client imbalance */
366 if (!Handle->CloseRequested)
367 return;
368
369 if (Handle->Client.Unregister)
370 Handle->Client.Unregister(Handle->Client.Handle);
371
372 ExFreePoolWithTag(Handle, Handle->Client.PoolTag);
373}
374
375/* Common front half of every URB allocator; takes the reference the URB will own */
376static
380 _In_ BOOLEAN ArgumentsValid,
382{
383 if (!Handle || !ArgumentsValid)
384 {
385 if (Urb)
386 *Urb = NULL;
388 }
389
390 if (!Urb)
392
393 *Urb = NULL;
394
397
398 return STATUS_SUCCESS;
399}
400
401/* Common back half; a failed allocation gives its reference back */
402static
408{
409 if (!NT_SUCCESS(Status))
410 {
411 *Urb = NULL;
413 }
414
415 return Status;
416}
417
418static
419PURB
423{
424 return ExAllocatePoolZero(UsbdexPoolType, Size, Handle->Client.PoolTag);
425}
426
427/* Fills one interface block the way the bus driver expects to receive it */
428static
429VOID
433 _In_ UCHAR PipeCount)
434{
436 ULONG Index;
437
438 Information->Length = (USHORT)GET_USBD_INTERFACE_SIZE(PipeCount);
439 Information->InterfaceNumber = Descriptor->bInterfaceNumber;
440 Information->AlternateSetting = Descriptor->bAlternateSetting;
441 Information->NumberOfPipes = PipeCount;
442
443 Pipe = Information->Pipes;
444 for (Index = 0; Index < PipeCount; Index++)
445 {
446 Pipe[Index].MaximumTransferSize = USBDEX_PIPE_MAX_TRANSFER_DEFAULT;
447 Pipe[Index].PipeFlags = 0;
448 }
449}
450
451static
457 _Out_ PURB *Urb)
458{
461 PUCHAR End;
462 PURB NewUrb;
465 UCHAR PipeCount;
466
467 /* The URB Length field is 16 bits, so the whole request has to fit */
469 for (Entry = InterfaceList; Entry->InterfaceDescriptor; Entry++)
470 {
471 TotalSize += (ULONG)GET_USBD_INTERFACE_SIZE(Entry->InterfaceDescriptor->bNumEndpoints);
472 if (TotalSize > MAXUSHORT)
474 }
475
477 if (!NewUrb)
479
480 Cursor = (PUCHAR)&NewUrb->UrbSelectConfiguration.Interface;
481 End = (PUCHAR)NewUrb + TotalSize;
482
483 /* The descriptors may change under us, so every block is checked against the buffer again */
484 for (Entry = InterfaceList; Entry->InterfaceDescriptor; Entry++)
485 {
486 PipeCount = Entry->InterfaceDescriptor->bNumEndpoints;
488 if (BlockSize > (ULONG)(End - Cursor))
489 {
490 ExFreePoolWithTag(NewUrb, Handle->Client.PoolTag);
492 }
493
495 Entry->InterfaceDescriptor,
496 PipeCount);
498 Cursor += BlockSize;
499 }
500
501 NewUrb->UrbSelectConfiguration.Hdr.Length = (USHORT)TotalSize;
503 NewUrb->UrbSelectConfiguration.ConfigurationDescriptor = ConfigurationDescriptor;
504
505 *Urb = NewUrb;
506 return STATUS_SUCCESS;
507}
508
509static
515 _Out_ PURB *Urb)
516{
518 PURB NewUrb;
520 UCHAR PipeCount;
521
522 Descriptor = InterfaceListEntry->InterfaceDescriptor;
523 if (!Descriptor)
525
526 PipeCount = Descriptor->bNumEndpoints;
527 if (PipeCount > USBDEX_SELECT_INTERFACE_MAX_PIPES)
529
531 (ULONG)GET_USBD_INTERFACE_SIZE(PipeCount);
532
534 if (!NewUrb)
536
537 UsbdexInitInterfaceInformation(&NewUrb->UrbSelectInterface.Interface, Descriptor, PipeCount);
538 InterfaceListEntry->Interface = &NewUrb->UrbSelectInterface.Interface;
539
540 NewUrb->UrbSelectInterface.Hdr.Length = (USHORT)TotalSize;
542 NewUrb->UrbSelectInterface.ConfigurationHandle = ConfigurationHandle;
543
544 *Urb = NewUrb;
545 return STATUS_SUCCESS;
546}
547
548/* Capability answers for a stack that predates the capability IOCTL */
549static
553 _In_ const GUID *CapabilityType,
555{
556 if (IsEqualGUID(CapabilityType, &GUID_USB_CAPABILITY_DEVICE_CONNECTION_HIGH_SPEED_COMPATIBLE))
557 {
558 if (OutputBuffer)
560
561 return Handle->HighSpeed ? STATUS_SUCCESS : STATUS_NOT_SUPPORTED;
562 }
563
564 if (IsEqualGUID(CapabilityType, &GUID_USB_CAPABILITY_SELECTIVE_SUSPEND))
566
568}
569
573NTAPI
579 _Out_ USBD_HANDLE *USBDHandle)
580{
582 PWSTR ParametersPath;
584
586 {
587 if (USBDHandle)
588 *USBDHandle = NULL;
590 }
591
593
594 if (!DeviceObject ||
597 PoolTag == 0)
598 {
599 if (USBDHandle)
600 *USBDHandle = NULL;
602 }
603
604 if (!USBDHandle)
606
607 ParametersPath = UsbdexBuildParametersPath(DeviceObject->DriverObject, PoolTag);
608
610 if (!Handle)
611 {
612 if (ParametersPath)
613 ExFreePoolWithTag(ParametersPath, PoolTag);
614 *USBDHandle = NULL;
616 }
617
618 if (ParametersPath)
619 UsbdexReadVerifierSettings(DeviceObject->DriverObject, ParametersPath, PoolTag, &Handle->Client);
620
621 Handle->Signature = USBDEX_HANDLE_SIGNATURE;
622 Handle->Client.Header.Size = sizeof(Handle->Client);
623 Handle->Client.Header.Version = USBD_CLIENT_INTERFACE_VERSION;
624 Handle->Client.ClientContractVersion = USBDClientContractVersion;
625 Handle->Client.DeviceObject = DeviceObject;
626 Handle->Client.PoolTag = PoolTag;
627 Handle->Client.ClientContext = Handle;
628 Handle->TargetDeviceObject = TargetDeviceObject;
629 Handle->Mode = USBDEX_MODE_UCX;
630 Handle->ReferenceCount = 1;
631
634 &GUID_USBD_CLIENT_INTERFACE,
635 (PINTERFACE)&Handle->Client);
636 if (!NT_SUCCESS(Status))
637 {
638 /* Nothing the lower stack may have left in the answer part is usable */
639 Handle->Client.Handle = NULL;
640 Handle->Client.Unregister = NULL;
641 Handle->Client.AllocUrb = NULL;
642 Handle->Client.AllocIsochUrb = NULL;
643 Handle->Client.AllocSelectConfigUrb = NULL;
644 Handle->Client.AllocSelectInterfaceUrb = NULL;
645 Handle->Client.ReleaseUrb = NULL;
646
647 /* Not a UCX stack; the handle still works, with pool URBs */
649 }
650
651 if (ParametersPath)
652 ExFreePoolWithTag(ParametersPath, PoolTag);
653
654 *USBDHandle = (USBD_HANDLE)Handle;
655 return STATUS_SUCCESS;
656}
657
659VOID
660NTAPI
662 _In_ USBD_HANDLE USBDHandle)
663{
665
666 if (!Handle)
667 return;
668
669 /* Outstanding URBs keep the handle alive until their USBD_UrbFree */
670 Handle->CloseRequested = TRUE;
672}
673
677NTAPI
679 _In_ USBD_HANDLE USBDHandle,
680 _In_ const GUID *CapabilityType,
689{
693
694 if (ResultLength)
695 *ResultLength = 0;
696
699
700 if (!Handle || !CapabilityType)
702
703 /* A buffer and its length come together or not at all */
704 if ((OutputBufferLength != 0) != (OutputBuffer != NULL))
706
707 if (Handle->Mode == USBDEX_MODE_NONE)
709
710 if (Handle->Mode == USBDEX_MODE_LEGACY)
712
713 RtlZeroMemory(&Request, sizeof(Request));
715 Request.Size = sizeof(Request);
716 Request.UsbdHandle = Handle->Client.Handle;
717 Request.CapabilityType = *CapabilityType;
718 Request.OutputBufferLength = OutputBufferLength;
719
720 Status = UsbdexSendCapabilityRequest(Handle->Client.DeviceObject,
721 Handle->TargetDeviceObject,
722 &Request,
725 *ResultLength = Request.ResultLength;
726
727 return Status;
728}
729
733NTAPI
735 _In_ USBD_HANDLE USBDHandle,
737{
740
742 if (!NT_SUCCESS(Status))
743 return Status;
744
745 if (Handle->Client.AllocUrb)
746 {
747 Status = Handle->Client.AllocUrb(Handle->Client.Handle, Urb);
748 }
749 else
750 {
751 *Urb = UsbdexAllocatePoolUrb(Handle, sizeof(URB));
753 }
754
756}
757
761NTAPI
763 _In_ USBD_HANDLE USBDHandle,
768 PURB *Urb)
769{
771 const ULONG MaxPackets = (MAXULONG - sizeof(URB)) / sizeof(USBD_ISO_PACKET_DESCRIPTOR);
773
775 if (!NT_SUCCESS(Status))
776 return Status;
777
778 if (Handle->Client.AllocIsochUrb)
779 {
780 Status = Handle->Client.AllocIsochUrb(Handle->Client.Handle, NumberOfIsochPackets, Urb);
781 }
782 else if (NumberOfIsochPackets > MaxPackets)
783 {
785 }
786 else
787 {
788 /* Same size as the UCX isoch URB region: a whole URB plus one descriptor per packet */
790 sizeof(URB) +
793 }
794
796}
797
801NTAPI
802USBD_SelectConfigUrbAllocateAndBuild(
803 _In_ USBD_HANDLE USBDHandle,
807{
810
812 if (!NT_SUCCESS(Status))
813 return Status;
814
815 if (Handle->Client.AllocSelectConfigUrb)
816 {
817 Status = Handle->Client.AllocSelectConfigUrb(Handle->Client.Handle,
820 Urb);
821 }
822 else
823 {
825 }
826
828}
829
833NTAPI
834USBD_SelectInterfaceUrbAllocateAndBuild(
835 _In_ USBD_HANDLE USBDHandle,
839{
842
845 Urb);
846 if (!NT_SUCCESS(Status))
847 return Status;
848
849 if (Handle->Client.AllocSelectInterfaceUrb)
850 {
851 Status = Handle->Client.AllocSelectInterfaceUrb(Handle->Client.Handle,
854 Urb);
855 }
856 else
857 {
859 }
860
862}
863
865VOID
866NTAPI
868 _In_ USBD_HANDLE USBDHandle,
869 _In_ PURB Urb)
870{
872
873 if (!Urb || !Handle)
874 return;
875
876 if (Handle->Client.ReleaseUrb)
877 Handle->Client.ReleaseUrb(Urb);
878 else
879 ExFreePoolWithTag(Urb, Handle->Client.PoolTag);
880
882}
883
885VOID
886NTAPI
888 _In_ USBD_HANDLE USBDHandle,
890 _In_ PURB Urb)
891{
893
895
896 /* UCX tells an XRB from a plain URB by finding the URB in FileObject too */
899}
900
903NTAPI
904USBD_IsInterfaceVersionSupported(
905 _In_ USBD_HANDLE USBDHandle,
907{
909}
910
912VOID
913NTAPI
914USBD_BuildRegisterCompositeDevice(
915 _In_ USBD_HANDLE USBDHandle,
919{
921
924 RegisterCompositeDevice->Size = sizeof(*RegisterCompositeDevice);
925 RegisterCompositeDevice->Reserved = (USBDI_HANDLE)Handle->Client.Handle;
926 RegisterCompositeDevice->CapabilityFlags = CapabilityFlags;
927 RegisterCompositeDevice->FunctionCount = FunctionCount;
928}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define VOID
Definition: acefi.h:82
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
D3D12_VIDEO_MOTION_ESTIMATOR_SEARCH_BLOCK_SIZE BlockSize
Definition: d3d12video.idl:529
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
PUCHAR End
Definition: desccheck.cpp:2229
PUCHAR Cursor
Definition: desccheck.cpp:2228
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
KEVENT Done
Definition: devreq.cpp:1162
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:182
#define NTSTATUS
Definition: precomp.h:19
#define L(x)
Definition: resources.c:13
#define __drv_freesMem(kind)
Definition: driverspecs.h:272
#define _IRQL_requires_max_(irql)
Definition: driverspecs.h:230
#define _IRQL_requires_(irql)
Definition: driverspecs.h:229
LOGICAL NTAPI MmIsDriverVerifying(IN PDRIVER_OBJECT DriverObject)
Definition: drvmgmt.c:212
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define NonPagedPool
Definition: env_spec_w32.h:307
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1675
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:24
ASMGENDATA Table[]
Definition: genincdata.c:61
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
UNICODE_STRING Path
#define UCXHUB_QUERY_CAPABILITY_VERSION
Definition: hubucx.h:156
#define IOCTL_UCXHUB_QUERY_USB_CAPABILITY
Definition: hubucx.h:65
Request TotalSize
Definition: hubwmi.cpp:555
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define C_ASSERT(e)
Definition: intsafe.h:73
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 RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
_In_ PIRP Irp
Definition: kse.h:79
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:47
static ULONG OsVersion
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
_Must_inspect_result_ _Out_ PNDIS_STATUS _Out_ PNDIS_HANDLE ConfigurationHandle
Definition: ndis.h:3947
#define KernelMode
Definition: asm.h:38
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4230
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4231
#define _Outptr_result_bytebuffer_(s)
Definition: no_sal2.h:288
#define _Out_opt_
Definition: no_sal2.h:214
#define _Inout_
Definition: no_sal2.h:162
#define _Deref_out_range_(l, h)
Definition: no_sal2.h:376
#define _In_z_
Definition: no_sal2.h:164
#define _Outptr_
Definition: no_sal2.h:262
#define _Pre_null_
Definition: no_sal2.h:512
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define _Out_
Definition: no_sal2.h:160
#define _In_reads_opt_(s)
Definition: no_sal2.h:222
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Out_writes_bytes_to_opt_(s, c)
Definition: no_sal2.h:240
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define _When_(c, a)
Definition: no_sal2.h:38
#define _In_reads_bytes_opt_(s)
Definition: no_sal2.h:224
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RTL_REGISTRY_SERVICES
Definition: nt_native.h:162
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
@ NotificationEvent
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:647
#define IoCallDriver
Definition: irp.c:1257
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1698
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:559
#define STATUS_INVALID_LEVEL
Definition: ntstatus.h:658
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REG_DWORD
Definition: sdbapi.c:615
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
char Name[55]
Definition: genincdata.c:33
Definition: client.c:31
PFILE_OBJECT FileObject
Definition: iotypes.h:3184
struct _IO_STACK_LOCATION::@5136::@5175 Others
union _IO_STACK_LOCATION::@1823 Parameters
Definition: usb.h:565
struct _URB_SELECT_CONFIGURATION UrbSelectConfiguration
Definition: usb.h:569
struct _URB_SELECT_INTERFACE UrbSelectInterface
Definition: usb.h:568
PDEVICE_OBJECT TargetDeviceObject
Definition: usbdex.c:38
volatile LONG ReferenceCount
Definition: usbdex.c:40
BOOLEAN HighSpeed
Definition: usbdex.c:41
BOOLEAN CloseRequested
Definition: usbdex.c:42
USBD_CLIENT_INTERFACE Client
Definition: usbdex.c:37
Definition: usbdlib.h:7
PINTERFACE_DEREFERENCE InterfaceDereference
Definition: usbbusif.h:98
PUSB_BUSIFFN_IS_DEVICE_HIGH_SPEED IsDeviceHighSpeed
Definition: usbbusif.h:103
PVOID NTAPI MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)
Definition: sysldr.c:3672
#define STATUS_PENDING
Definition: telnetd.h:14
uint16_t * PWSTR
Definition: typedefs.h:56
#define MAXULONG
Definition: typedefs.h:251
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
INT POOL_TYPE
Definition: typedefs.h:78
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_In_ PGUID _In_ ULONG _Out_ PULONG ResultLength
Definition: ucxcontroller.h:83
_In_ PGUID CapabilityType
Definition: ucxcontroller.h:80
_In_ PGUID _In_ ULONG OutputBufferLength
Definition: ucxcontroller.h:81
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST Request
_In_ UCXUSBDEVICE _In_ ULONG Interface
Definition: ucxusbdevice.h:428
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _USBD_INTERFACE_INFORMATION * PUSBD_INTERFACE_INFORMATION
#define URB_FUNCTION_SELECT_INTERFACE
Definition: usb.h:87
struct _USBD_ISO_PACKET_DESCRIPTOR USBD_ISO_PACKET_DESCRIPTOR
#define URB_FUNCTION_SELECT_CONFIGURATION
Definition: usb.h:86
struct _URB URB
#define USB_BUSIF_USBDI_VERSION_1
Definition: usbbusif.h:74
#define USBD_CLIENT_INTERFACE_VERSION
Definition: usbdclient.h:18
static PURB UsbdexAllocatePoolUrb(_In_ PUSBDEX_HANDLE_OBJECT Handle, _In_ SIZE_T Size)
Definition: usbdex.c:420
struct _USBDEX_HANDLE_OBJECT USBDEX_HANDLE_OBJECT
static BOOLEAN UsbdexPoolTypeKnown
Definition: usbdex.c:46
static VOID UsbdexDereferenceHandle(_Inout_ PUSBDEX_HANDLE_OBJECT Handle)
Definition: usbdex.c:359
static VOID UsbdexDetectPoolType(VOID)
Definition: usbdex.c:69
static RTL_QUERY_REGISTRY_ROUTINE UsbdexVerifierValueCallback
Definition: usbdex.c:49
NTSTATUS(NTAPI * PFN_USBDEX_QUERY_REGISTRY)(_In_ ULONG RelativeTo, _In_ PCWSTR Path, _Inout_ PRTL_QUERY_REGISTRY_TABLE QueryTable, _In_opt_ PVOID Context, _In_opt_ PVOID Environment)
Definition: usbdex.c:26
static VOID UsbdexInitInterfaceInformation(_Out_ PUSBD_INTERFACE_INFORMATION Information, _In_ PUSB_INTERFACE_DESCRIPTOR Descriptor, _In_ UCHAR PipeCount)
Definition: usbdex.c:430
static NTSTATUS UsbdexBuildSelectInterfaceUrb(_In_ PUSBDEX_HANDLE_OBJECT Handle, _In_ USBD_CONFIGURATION_HANDLE ConfigurationHandle, _Inout_ PUSBD_INTERFACE_LIST_ENTRY InterfaceListEntry, _Out_ PURB *Urb)
Definition: usbdex.c:511
#define USBDEX_COMPOSITE_VERSION
Definition: usbdex.c:22
static NTSTATUS UsbdexFinishAllocation(_Inout_ PUSBDEX_HANDLE_OBJECT Handle, _In_ NTSTATUS Status, _Inout_ PURB *Urb)
Definition: usbdex.c:404
#define USBDEX_MODE_LEGACY
Definition: usbdex.c:14
#define USBDEX_PIPE_MAX_TRANSFER_DEFAULT
Definition: usbdex.c:20
#define USBDEX_SELECT_INTERFACE_MAX_PIPES
Definition: usbdex.c:21
static ULONG UsbdexProbeLegacyStack(_Inout_ PUSBDEX_HANDLE_OBJECT Handle)
Definition: usbdex.c:318
static VOID UsbdexReadVerifierSettings(_In_ PDRIVER_OBJECT DriverObject, _In_z_ PCWSTR ParametersPath, _In_ ULONG PoolTag, _Inout_ PUSBD_CLIENT_INTERFACE Client)
Definition: usbdex.c:254
static NTSTATUS UsbdexSendCapabilityRequest(_In_ PDEVICE_OBJECT ClientDevice, _In_ PDEVICE_OBJECT Target, _Inout_ PUCXHUB_QUERY_CAPABILITY Request, _Out_opt_ PVOID OutputBuffer)
Definition: usbdex.c:167
static NTSTATUS UsbdexQueryInterface(_In_ PDEVICE_OBJECT ClientDevice, _In_ PDEVICE_OBJECT Target, _In_ const GUID *InterfaceType, _Inout_ PINTERFACE Interface)
Definition: usbdex.c:137
static IO_COMPLETION_ROUTINE UsbdexSyncCompletion
Definition: usbdex.c:48
FORCEINLINE BOOLEAN UsbdexIsUcxMode(_In_ PUSBDEX_HANDLE_OBJECT Handle)
Definition: usbdex.c:61
struct _USBDEX_HANDLE_OBJECT * PUSBDEX_HANDLE_OBJECT
#define USBDEX_MODE_UCX
Definition: usbdex.c:13
static NTSTATUS UsbdexBuildSelectConfigUrb(_In_ PUSBDEX_HANDLE_OBJECT Handle, _In_opt_ PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, _Inout_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList, _Out_ PURB *Urb)
Definition: usbdex.c:453
static NTSTATUS UsbdexStartAllocation(_In_opt_ PUSBDEX_HANDLE_OBJECT Handle, _In_ BOOLEAN ArgumentsValid, _Out_opt_ PURB *Urb)
Definition: usbdex.c:378
#define USBDEX_HANDLE_SIGNATURE
Definition: usbdex.c:10
static NTSTATUS UsbdexReferenceHandle(_Inout_ PUSBDEX_HANDLE_OBJECT Handle)
Definition: usbdex.c:347
#define USBDEX_NONPAGED_POOL_NX
Definition: usbdex.c:18
static NTSTATUS UsbdexLegacyCapability(_In_ PUSBDEX_HANDLE_OBJECT Handle, _In_ const GUID *CapabilityType, _In_opt_ PUCHAR OutputBuffer)
Definition: usbdex.c:551
#define USBDEX_MODE_NONE
Definition: usbdex.c:15
static PWSTR UsbdexBuildParametersPath(_In_ PDRIVER_OBJECT DriverObject, _In_ ULONG PoolTag)
Definition: usbdex.c:221
static NTSTATUS UsbdexCallAndWait(_In_ PDEVICE_OBJECT ClientDevice, _In_ PDEVICE_OBJECT Target, _In_ __drv_freesMem(Mem) PIRP Irp)
Definition: usbdex.c:110
static POOL_TYPE UsbdexPoolType
Definition: usbdex.c:45
FORCEINLINE PUSBDEX_HANDLE_OBJECT UsbdexHandleObject(_In_opt_ USBD_HANDLE USBDHandle)
Definition: usbdex.c:53
_In_opt_ PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
Definition: usbdlib.h:331
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ ULONG _In_ ULONG _Out_ USBD_HANDLE * USBDHandle
Definition: usbdlib.h:281
#define GET_USBD_INTERFACE_SIZE(numEndpoints)
Definition: usbdlib.h:148
_In_ COMPOSITE_DEVICE_CAPABILITIES _In_ ULONG FunctionCount
Definition: usbdlib.h:373
_In_ ULONG USBDInterfaceVersion
Definition: usbdlib.h:365
_In_ COMPOSITE_DEVICE_CAPABILITIES CapabilityFlags
Definition: usbdlib.h:372
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ ULONG USBDClientContractVersion
Definition: usbdlib.h:279
#define USBD_CLIENT_CONTRACT_VERSION_602
Definition: usbdlib.h:100
_In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList
Definition: usbdlib.h:208
_In_ USBD_CONFIGURATION_HANDLE _Inout_ PUSBD_INTERFACE_LIST_ENTRY InterfaceListEntry
Definition: usbdlib.h:342
_In_ COMPOSITE_DEVICE_CAPABILITIES _In_ ULONG _Out_ PREGISTER_COMPOSITE_DEVICE RegisterCompositeDevice
Definition: usbdlib.h:374
_In_ PIO_STACK_LOCATION IoStackLocation
Definition: usbdlib.h:357
_In_opt_ PUSB_CONFIGURATION_DESCRIPTOR _Inout_ PUSBD_INTERFACE_LIST_ENTRY _Outptr_ PURB * Urb
Definition: usbdlib.h:333
NTSTATUS USBD_QueryUsbCapability(_In_ USBD_HANDLE USBDHandle, _In_ const GUID *CapabilityType, _In_ ULONG OutputBufferLength, _When_(OutputBufferLength==0, _Pre_null_) _When_(OutputBufferLength !=0 &&ResultLength==NULL, _Out_writes_bytes_(OutputBufferLength)) _When_(OutputBufferLength !=0 &&ResultLength !=NULL, _Out_writes_bytes_to_opt_(OutputBufferLength, *ResultLength)) PUCHAR OutputBuffer, _Out_opt_ _When_(ResultLength !=NULL, _Deref_out_range_(<=, OutputBufferLength)) PULONG ResultLength)
Definition: usbstubum.cpp:111
NTSTATUS USBD_UrbAllocate(_In_ USBD_HANDLE USBDHandle, _Outptr_result_bytebuffer_(sizeof(URB)) PURB *Urb)
Definition: usbstubum.cpp:46
NTSTATUS USBD_IsochUrbAllocate(_In_ USBD_HANDLE USBDHandle, _In_ ULONG NumberOfIsochPacket, _Outptr_result_bytebuffer_(sizeof(struct _URB_ISOCH_TRANSFER)+(NumberOfIsochPackets *sizeof(USBD_ISO_PACKET_DESCRIPTOR)) - sizeof(USBD_ISO_PACKET_DESCRIPTOR)) PURB *Urb)
Definition: usbstubum.cpp:60
NTSTATUS USBD_CreateHandle(_In_ PDEVICE_OBJECT DeviceObject, _In_ PDEVICE_OBJECT TargetDeviceObject, _In_ ULONG USBDClientContractVersion, _In_ ULONG PoolTag, _Out_ USBD_HANDLE *USBDHandle)
Definition: usbstubum.cpp:90
VOID USBD_CloseHandle(_In_ USBD_HANDLE USBDHandle)
Definition: usbstubum.cpp:80
VOID USBD_AssignUrbToIoStackLocation(_In_ USBD_HANDLE USBDHandle, _In_ PIO_STACK_LOCATION IoStackLocation, _In_ PURB Urb)
Definition: usbstubum.cpp:136
VOID USBD_UrbFree(_In_ USBD_HANDLE USBDHandle, _In_ PURB Urb)
Definition: usbstubum.cpp:33
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID InterfaceType
Definition: wdffdo.h:463
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG PoolTag
Definition: wdfmemory.h:164
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
#define FORCEINLINE
Definition: wdftypes.h:67
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ ULONG NumberOfIsochPackets
Definition: wdfusb.h:1703
_In_ WDFUSBPIPE Pipe
Definition: wdfusb.h:1741
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2721
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_QUERY_INTERFACE
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
@ Executive
Definition: ketypes.h:467
RtlInitUnicodeString & RoutineName
Definition: xhcientry.cpp:59