2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS USB miniport driver (Cromwell type)
4 * FILE: drivers/usb/miniport/common/main.c
5 * PURPOSE: Driver entry
7 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.com)
8 * Hervé Poussineau (hpoussin@reactos.org),
10 * Some parts of code are inspired (or even just copied) from
11 * ReactOS Videoport driver (drivers/video/videoprt)
18 #include "usbcommon.h"
20 // data for embedded drivers
21 CONNECT_DATA KbdClassInformation
;
22 CONNECT_DATA MouseClassInformation
;
23 PDEVICE_OBJECT KeyboardFdo
= NULL
;
24 PDEVICE_OBJECT MouseFdo
= NULL
;
28 IN PDRIVER_OBJECT DriverObject
,
29 IN PDEVICE_OBJECT Fdo
,
30 OUT PDEVICE_OBJECT
* pPdo
)
33 PUSBMP_DEVICE_EXTENSION DeviceExtension
;
36 DPRINT("USBMP: CreateRootHubPdo()\n");
38 Status
= IoCreateDevice(
40 sizeof(USBMP_DEVICE_EXTENSION
),
41 NULL
, /* DeviceName */
42 FILE_DEVICE_BUS_EXTENDER
,
43 FILE_DEVICE_SECURE_OPEN
| FILE_AUTOGENERATED_DEVICE_NAME
,
46 if (!NT_SUCCESS(Status
))
48 DPRINT("USBMP: IoCreateDevice() call failed with status 0x%08x\n", Status
);
52 Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
53 Pdo
->Flags
|= DO_POWER_PAGABLE
;
55 // zerofill device extension
56 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)Pdo
->DeviceExtension
;
57 RtlZeroMemory(DeviceExtension
, sizeof(USBMP_DEVICE_EXTENSION
));
59 DeviceExtension
->IsFDO
= FALSE
;
60 DeviceExtension
->FunctionalDeviceObject
= Fdo
;
62 Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
65 return STATUS_SUCCESS
;
70 IN PCWSTR PortTypeName
,
71 IN PUNICODE_STRING DeviceName
,
72 IN PCWSTR RegistryPath
)
74 UNICODE_STRING PathU
= RTL_CONSTANT_STRING(L
"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
75 OBJECT_ATTRIBUTES ObjectAttributes
;
76 HANDLE hDeviceMapKey
= (HANDLE
)-1;
77 HANDLE hPortKey
= (HANDLE
)-1;
78 UNICODE_STRING PortTypeNameU
;
81 InitializeObjectAttributes(&ObjectAttributes
, &PathU
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
82 Status
= ZwOpenKey(&hDeviceMapKey
, 0, &ObjectAttributes
);
83 if (!NT_SUCCESS(Status
))
85 DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status
);
89 RtlInitUnicodeString(&PortTypeNameU
, PortTypeName
);
90 InitializeObjectAttributes(&ObjectAttributes
, &PortTypeNameU
, OBJ_KERNEL_HANDLE
, hDeviceMapKey
, NULL
);
91 Status
= ZwCreateKey(&hPortKey
, KEY_SET_VALUE
, &ObjectAttributes
, 0, NULL
, REG_OPTION_VOLATILE
, NULL
);
92 if (!NT_SUCCESS(Status
))
94 DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status
);
98 Status
= ZwSetValueKey(hPortKey
, DeviceName
, 0, REG_SZ
, (PVOID
)RegistryPath
, wcslen(RegistryPath
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
));
99 if (!NT_SUCCESS(Status
))
101 DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status
);
105 Status
= STATUS_SUCCESS
;
108 if (hDeviceMapKey
!= (HANDLE
)-1)
109 ZwClose(hDeviceMapKey
);
110 if (hPortKey
!= (HANDLE
)-1)
117 IN PDRIVER_OBJECT DriverObject
,
118 IN PDEVICE_OBJECT Pdo
)
120 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\KeyboardPortUSB");
124 Status
= AddRegistryEntry(L
"KeyboardPort", &DeviceName
, L
"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\usbport");
125 if (!NT_SUCCESS(Status
))
127 DPRINT1("USBMP: AddRegistryEntry() for usb keyboard driver failed with status 0x%08lx\n", Status
);
131 Status
= IoCreateDevice(DriverObject
,
134 FILE_DEVICE_KEYBOARD
,
135 FILE_DEVICE_SECURE_OPEN
,
139 if (!NT_SUCCESS(Status
))
141 DPRINT1("USBMP: IoCreateDevice() for usb keyboard driver failed with status 0x%08lx\n", Status
);
145 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
146 DPRINT("USBMP: Created keyboard Fdo: %p\n", Fdo
);
148 return STATUS_SUCCESS
;
153 IN PDRIVER_OBJECT DriverObject
,
154 IN PDEVICE_OBJECT Pdo
)
156 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\PointerPortUSB");
160 Status
= AddRegistryEntry(L
"PointerPort", &DeviceName
, L
"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\usbport");
161 if (!NT_SUCCESS(Status
))
163 DPRINT1("USBMP: AddRegistryEntry() for usb mouse driver failed with status 0x%08lx\n", Status
);
167 Status
= IoCreateDevice(DriverObject
,
171 FILE_DEVICE_SECURE_OPEN
,
175 if (!NT_SUCCESS(Status
))
177 DPRINT1("USBMP: IoCreateDevice() for usb mouse driver failed with status 0x%08lx\n", Status
);
181 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
182 DPRINT("USBMP: Created mouse Fdo: %p\n", Fdo
);
184 return STATUS_SUCCESS
;
189 IN PDRIVER_OBJECT DriverObject
,
190 IN PDEVICE_OBJECT pdo
)
194 WCHAR DeviceBuffer
[20];
195 WCHAR LinkDeviceBuffer
[20];
196 UNICODE_STRING DeviceName
;
197 UNICODE_STRING LinkDeviceName
;
198 PUSBMP_DRIVER_EXTENSION DriverExtension
;
199 PUSBMP_DEVICE_EXTENSION DeviceExtension
;
202 // Allocate driver extension now
203 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
204 if (DriverExtension
== NULL
)
206 Status
= IoAllocateDriverObjectExtension(
209 sizeof(USBMP_DRIVER_EXTENSION
),
210 (PVOID
*)&DriverExtension
);
212 if (!NT_SUCCESS(Status
))
214 DPRINT("USBMP: Allocating DriverObjectExtension failed.\n");
219 // Create a unicode device name
220 DeviceNumber
= 0; //TODO: Allocate new device number every time
221 swprintf(DeviceBuffer
, L
"\\Device\\USBFDO-%lu", DeviceNumber
);
222 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
224 Status
= IoCreateDevice(DriverObject
,
225 sizeof(USBMP_DEVICE_EXTENSION
),
227 FILE_DEVICE_BUS_EXTENDER
,
232 if (!NT_SUCCESS(Status
))
234 DPRINT("USBMP: IoCreateDevice call failed with status 0x%08lx\n", Status
);
238 // zerofill device extension
239 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)fdo
->DeviceExtension
;
240 RtlZeroMemory(DeviceExtension
, sizeof(USBMP_DEVICE_EXTENSION
));
242 /* Create root hub Pdo */
243 Status
= CreateRootHubPdo(DriverObject
, fdo
, &DeviceExtension
->RootHubPdo
);
244 if (!NT_SUCCESS(Status
))
246 DPRINT("USBMP: CreateRootHubPdo() failed with status 0x%08lx\n", Status
);
251 /* Register device interface for controller */
252 Status
= IoRegisterDeviceInterface(
254 &GUID_DEVINTERFACE_USB_HOST_CONTROLLER
,
256 &DeviceExtension
->HcdInterfaceName
);
257 if (!NT_SUCCESS(Status
))
259 DPRINT("USBMP: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status
);
260 IoDeleteDevice(DeviceExtension
->RootHubPdo
);
265 DeviceExtension
->NextDeviceObject
= IoAttachDeviceToDeviceStack(fdo
, pdo
);
267 // Initialize device extension
268 DeviceExtension
->IsFDO
= TRUE
;
269 DeviceExtension
->DeviceNumber
= DeviceNumber
;
270 DeviceExtension
->PhysicalDeviceObject
= pdo
;
271 DeviceExtension
->FunctionalDeviceObject
= fdo
;
272 DeviceExtension
->DriverExtension
= DriverExtension
;
274 fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
276 /* FIXME: do a loop to find an available number */
277 swprintf(LinkDeviceBuffer
, L
"\\??\\HCD%lu", 0);
279 RtlInitUnicodeString(&LinkDeviceName
, LinkDeviceBuffer
);
281 Status
= IoCreateSymbolicLink(&LinkDeviceName
, &DeviceName
);
283 if (NT_SUCCESS(Status
))
284 Status
= AddDevice_Keyboard(DriverObject
, pdo
);
285 if (NT_SUCCESS(Status
))
286 Status
= AddDevice_Mouse(DriverObject
, pdo
);
288 if (!NT_SUCCESS(Status
))
290 DPRINT("USBMP: IoCreateSymbolicLink() call failed with status 0x%08x\n", Status
);
291 IoDeleteDevice(DeviceExtension
->RootHubPdo
);
297 return STATUS_SUCCESS
;
302 IN PDEVICE_OBJECT DeviceObject
,
305 NTSTATUS Status
= STATUS_NOT_SUPPORTED
;
307 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
309 DPRINT1("USBMP: FDO stub for major function 0x%lx\n",
310 IoGetCurrentIrpStackLocation(Irp
)->MajorFunction
);
314 return ForwardIrpAndForget(DeviceObject
, Irp
);
318 /* We can't forward request to the lower driver, because
319 * we are a Pdo, so we don't have lower driver...
321 DPRINT1("USBMP: PDO stub for major function 0x%lx\n",
322 IoGetCurrentIrpStackLocation(Irp
)->MajorFunction
);
328 Status
= Irp
->IoStatus
.Status
;
329 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
333 static NTSTATUS STDCALL
334 DispatchCreate(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
336 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
337 return UsbMpCreate(DeviceObject
, Irp
);
339 return IrpStub(DeviceObject
, Irp
);
342 static NTSTATUS STDCALL
343 DispatchClose(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
345 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
346 return UsbMpClose(DeviceObject
, Irp
);
348 return IrpStub(DeviceObject
, Irp
);
351 static NTSTATUS STDCALL
352 DispatchCleanup(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
354 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
355 return UsbMpCleanup(DeviceObject
, Irp
);
357 return IrpStub(DeviceObject
, Irp
);
360 static NTSTATUS STDCALL
361 DispatchDeviceControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
363 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
364 return UsbMpDeviceControlFdo(DeviceObject
, Irp
);
366 return UsbMpDeviceControlPdo(DeviceObject
, Irp
);
369 static NTSTATUS STDCALL
370 DispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
372 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
373 return UsbMpInternalDeviceControlFdo(DeviceObject
, Irp
);
375 return IrpStub(DeviceObject
, Irp
);
378 static NTSTATUS STDCALL
379 DispatchPnp(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
381 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
382 return UsbMpPnpFdo(DeviceObject
, Irp
);
384 return UsbMpPnpPdo(DeviceObject
, Irp
);
387 static NTSTATUS STDCALL
388 DispatchPower(PDEVICE_OBJECT fido
, PIRP Irp
)
390 DPRINT1("USBMP: IRP_MJ_POWER unimplemented\n");
391 Irp
->IoStatus
.Information
= 0;
392 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
393 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
394 return STATUS_SUCCESS
;
398 * Standard DriverEntry method.
401 DriverEntry(IN PDRIVER_OBJECT DriverObject
, IN PUNICODE_STRING RegPath
)
403 USBPORT_INTERFACE UsbPortInterface
;
406 DriverObject
->DriverUnload
= DriverUnload
;
407 DriverObject
->DriverExtension
->AddDevice
= AddDevice
;
409 for (i
= 0; i
< IRP_MJ_MAXIMUM_FUNCTION
; i
++)
410 DriverObject
->MajorFunction
[i
] = IrpStub
;
412 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = DispatchCreate
;
413 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = DispatchClose
;
414 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = DispatchCleanup
;
415 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = DispatchDeviceControl
;
416 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = DispatchInternalDeviceControl
;
417 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = DispatchPnp
;
418 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = DispatchPower
;
420 // Register in usbcore.sys
421 UsbPortInterface
.KbdConnectData
= &KbdClassInformation
;
422 UsbPortInterface
.MouseConnectData
= &MouseClassInformation
;
424 KbdClassInformation
.ClassService
= NULL
;
425 KbdClassInformation
.ClassDeviceObject
= NULL
;
426 MouseClassInformation
.ClassService
= NULL
;
427 MouseClassInformation
.ClassDeviceObject
= NULL
;
429 RegisterPortDriver(DriverObject
, &UsbPortInterface
);
431 return STATUS_SUCCESS
;