ReactOS 0.4.17-dev-1281-g065abb3
driver.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS USB Host Controller Extension
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Driver entry, the control device and driver wide settings
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "ucx01000.h"
9
10#define NDEBUG
11#include <debug.h>
12
13#define UCX_CONTROL_DEVICE_ATTEMPTS 100
14
15extern "C" DRIVER_INITIALIZE DriverEntry;
16static EVT_WDF_DRIVER_UNLOAD UcxEvtDriverUnload;
17
18/* SDDL_DEVOBJ_KERNEL_ONLY: an empty DACL, so no user mode caller can open it. wdmsec.h is not available here */
19DECLARE_CONST_UNICODE_STRING(UcxKernelOnlySddl, L"D:P");
20
21/* The loader needs a named device; another instance may own the first name */
23static
24CODE_SEG("INIT")
27UcxCreateControlDevice(
28 _In_ WDFDRIVER Driver)
29{
31 WDFDEVICE Device;
34
35 PAGED_CODE();
36
37 DeviceInit = WdfControlDeviceInitAllocate(Driver, &UcxKernelOnlySddl);
38 if (DeviceInit == NULL)
40
41 RtlInitEmptyUnicodeString(&UcxDriver.ControlDeviceName,
42 UcxDriver.ControlDeviceNameBuffer,
43 sizeof(UcxDriver.ControlDeviceNameBuffer));
44
46 {
47 Status = RtlUnicodeStringPrintf(&UcxDriver.ControlDeviceName, L"\\Device\\UCX%lu", Index);
48 if (!NT_SUCCESS(Status))
49 break;
50
51 Status = WdfDeviceInitAssignName(DeviceInit, &UcxDriver.ControlDeviceName);
52 if (!NT_SUCCESS(Status))
53 break;
54
55 Status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &Device);
56 }
57
58 /* A successful create took the init block over */
59 if (!NT_SUCCESS(Status))
60 {
61 if (DeviceInit != NULL)
62 WdfDeviceInitFree(DeviceInit);
63 return Status;
64 }
65
66 WdfControlFinishInitializing(Device);
67 UcxDriver.ControlDevice = Device;
68
69 return STATUS_SUCCESS;
70}
71
72/* Only a value of exactly 1 turns it on; anything missing leaves it off */
74static
75CODE_SEG("INIT")
76VOID
79{
80 DECLARE_CONST_UNICODE_STRING(KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\usbflags");
81 DECLARE_CONST_UNICODE_STRING(ValueName, L"Allow64KLowOrFullSpeedControlTransfers");
82 WDFKEY Key;
85
86 PAGED_CODE();
87
89 if (!NT_SUCCESS(Status))
90 {
92 DPRINT1("Cannot open usbflags 0x%lx\n", Status);
93 return;
94 }
95
96 Status = WdfRegistryQueryULong(Key, &ValueName, &Value);
97 if (NT_SUCCESS(Status))
98 UcxDriver.Allow64KLowOrFullSpeedControl = (Value == 1);
100 DPRINT1("Cannot read Allow64KLowOrFullSpeedControlTransfers 0x%lx\n", Status);
101
103}
104
105static
106VOID
107NTAPI
109 _In_ WDFDRIVER Driver)
110{
112
113 PAGED_CODE();
114
115 if (UcxDriver.ControlDevice != NULL)
116 {
117 WdfObjectDelete(UcxDriver.ControlDevice);
118 UcxDriver.ControlDevice = NULL;
119 }
120}
121
122extern "C"
123CODE_SEG("INIT")
125NTAPI
129{
130 DECLARE_CONST_UNICODE_STRING(TryQueueName, L"IoTryQueueWorkItem");
134
136 UcxDriver.RandomSeed = Ticks.LowPart;
137
139 KeInitializeSpinLock(&UcxDriver.ControllerListLock);
140 UcxDriver.ControllerCount = 0;
141
144 Config.EvtDriverUnload = UcxEvtDriverUnload;
145 Config.DriverPoolTag = UCX_POOL_TAG;
146
149 {
150 DPRINT1("WdfDriverCreate failed 0x%lx\n", Status);
151 return Status;
152 }
153
154 Status = UcxCreateControlDevice(UcxDriver.Driver);
155 if (!NT_SUCCESS(Status))
156 {
157 DPRINT1("Cannot create the control device 0x%lx\n", Status);
158 return Status;
159 }
160
162 if (!NT_SUCCESS(Status))
163 {
164 DPRINT1("WdfRegisterClassLibrary failed 0x%lx\n", Status);
165 WdfObjectDelete(UcxDriver.ControlDevice);
166 UcxDriver.ControlDevice = NULL;
167 return Status;
168 }
169
170 UcxDriver.IoTryQueueWorkItem =
172
174
175 DPRINT("UCX loaded, control device %wZ\n", &UcxDriver.ControlDeviceName);
177}
#define PAGED_CODE()
#define CODE_SEG(...)
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
RtlInitEmptyUnicodeString(SymbolicLinkName, NULL, 0)
WDF_CLASS_LIBRARY_INFO UcxClassLibraryInfo
Definition: classlib.cpp:15
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
WDF_DRIVER_CONFIG Config
Definition: driver.cpp:131
static EVT_WDF_DRIVER_UNLOAD UcxEvtDriverUnload
Definition: driver.cpp:16
#define UCX_CONTROL_DEVICE_ATTEMPTS
Definition: driver.cpp:13
InitializeListHead & UcxDriver
Definition: driver.cpp:138
DRIVER_INITIALIZE DriverEntry
Definition: driver.cpp:15
NTSTATUS Status
Definition: driver.cpp:133
return STATUS_SUCCESS
Definition: driver.cpp:176
LARGE_INTEGER Ticks
Definition: driver.cpp:132
UcxReadUsbFlags()
#define L(x)
Definition: resources.c:13
#define _IRQL_requires_(irql)
Definition: driverspecs.h:229
return WdfRegistryOpenKey(NULL, &KeyName, Access, WDF_NO_OBJECT_ATTRIBUTES, Key)
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
WdfRegistryClose(HardwareKey)
Status
Definition: gdiplustypes.h:24
return RtlUnicodeStringPrintf(Name, L"uxd_port_%03u", PortNumber)
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
#define _In_
Definition: no_sal2.h:158
#define KEY_READ
Definition: nt_native.h:1026
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define KeQueryTickCount(CurrentCount)
Definition: ke.h:43
#define DPRINT
Definition: sndvol32.h:73
PVOID NTAPI MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)
Definition: sysldr.c:3672
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG
Definition: typedefs.h:59
WDF_EXTERN_C_START typedef _Inout_ PWDFDEVICE_INIT DeviceInit
Definition: ucxclass.h:37
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG Config
BOOLEAN(NTAPI * PFN_UCX_IO_TRY_QUEUE_WORKITEM)(_Inout_ PIO_WORKITEM IoWorkItem, _In_ PIO_WORKITEM_ROUTINE_EX WorkerRoutine, _In_ WORK_QUEUE_TYPE QueueType, _In_opt_ PVOID Context)
Definition: ucxutil.h:134
#define UCX_POOL_TAG
Definition: ucxutil.h:11
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
ULONG LowPart
Definition: typedefs.h:106
WdfObjectDelete(String)
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PWDFDEVICE_INIT DeviceInit
Definition: wdfcontrol.h:113
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
@ WdfDriverInitNonPnpDriver
Definition: wdfdriver.h:51
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
FORCEINLINE VOID WDF_DRIVER_CONFIG_INIT(_Out_ PWDF_DRIVER_CONFIG Config, _In_opt_ PFN_WDF_DRIVER_DEVICE_ADD EvtDriverDeviceAdd)
Definition: wdfdriver.h:148
NTSTATUS NTAPI WdfRegisterClassLibrary(_In_ PWDF_CLASS_LIBRARY_INFO ClassLibInfo, _In_ PUNICODE_STRING SourceString, _In_ PUNICODE_STRING ObjectName)
Register class extension library (e.g., UCX)
Definition: wdfldr.c:696
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define WDF_NO_EVENT_CALLBACK
Definition: wdftypes.h:106
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105