2 * PROJECT: ReactOS USB Port Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBPort I/O control functions
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
15 USBPORT_UserGetHcName(IN PDEVICE_OBJECT FdoDevice
,
16 IN PUSBUSER_CONTROLLER_UNICODE_NAME ControllerName
,
17 IN PUSB_UNICODE_NAME UnicodeName
)
19 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
24 DPRINT("USBPORT_UserGetHcName: ... \n");
26 FdoExtension
= FdoDevice
->DeviceExtension
;
28 Length
= ControllerName
->Header
.RequestBufferLength
-
29 sizeof(USBUSER_CONTROLLER_UNICODE_NAME
);
31 RtlZeroMemory(UnicodeName
, Length
);
33 Status
= IoGetDeviceProperty(FdoExtension
->CommonExtension
.LowerPdoDevice
,
34 DevicePropertyDriverKeyName
,
39 if (!NT_SUCCESS(Status
))
41 if (Status
== STATUS_BUFFER_TOO_SMALL
)
43 ControllerName
->Header
.UsbUserStatusCode
= UsbUserBufferTooSmall
;
47 ControllerName
->Header
.UsbUserStatusCode
= UsbUserInvalidParameter
;
52 ControllerName
->Header
.UsbUserStatusCode
= UsbUserSuccess
;
53 UnicodeName
->Length
= ResultLength
+ sizeof(UNICODE_NULL
);
56 ControllerName
->Header
.ActualBufferLength
= sizeof(USBUSER_CONTROLLER_UNICODE_NAME
) +
62 USBPORT_GetSymbolicName(IN PDEVICE_OBJECT RootHubPdo
,
63 IN PUNICODE_STRING DestinationString
)
65 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
66 PUNICODE_STRING RootHubName
;
73 DPRINT("USBPORT_GetSymbolicName: ... \n");
75 PdoExtension
= RootHubPdo
->DeviceExtension
;
76 RootHubName
= &PdoExtension
->CommonExtension
.SymbolicLinkName
;
77 Buffer
= RootHubName
->Buffer
;
81 return STATUS_UNSUCCESSFUL
;
84 LengthName
= RootHubName
->Length
;
86 SourceString
= ExAllocatePoolWithTag(PagedPool
, LengthName
, USB_PORT_TAG
);
90 RtlInitUnicodeString(DestinationString
, NULL
);
91 return STATUS_INSUFFICIENT_RESOURCES
;
94 RtlZeroMemory(SourceString
, LengthName
);
100 if (*Buffer
== L
'\\')
110 if (Character
== UNICODE_NULL
)
118 while (*Buffer
!= L
'\\');
120 if (*Buffer
== L
'\\')
126 Length
= (ULONG_PTR
)Buffer
- (ULONG_PTR
)RootHubName
->Buffer
;
133 RtlCopyMemory(SourceString
,
134 (PVOID
)((ULONG_PTR
)RootHubName
->Buffer
+ Length
),
135 RootHubName
->Length
- Length
);
137 RtlInitUnicodeString(DestinationString
, SourceString
);
139 DPRINT("USBPORT_RegisterDeviceInterface: DestinationString - %wZ\n",
142 return STATUS_SUCCESS
;
147 USBPORT_UserGetRootHubName(IN PDEVICE_OBJECT FdoDevice
,
148 IN PUSBUSER_CONTROLLER_UNICODE_NAME RootHubName
,
149 IN PUSB_UNICODE_NAME UnicodeName
)
151 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
152 UNICODE_STRING UnicodeString
;
154 ULONG ResultLength
= 0;
157 DPRINT("USBPORT_UserGetRootHubName: ... \n");
159 FdoExtension
= FdoDevice
->DeviceExtension
;
161 Length
= RootHubName
->Header
.RequestBufferLength
-
162 sizeof(USBUSER_CONTROLLER_UNICODE_NAME
);
164 RtlZeroMemory(UnicodeName
, Length
);
166 Status
= USBPORT_GetSymbolicName(FdoExtension
->RootHubPdo
, &UnicodeString
);
168 if (NT_SUCCESS(Status
))
170 ResultLength
= UnicodeString
.Length
;
172 if (UnicodeString
.Length
> Length
)
174 UnicodeString
.Length
= Length
;
175 Status
= STATUS_BUFFER_TOO_SMALL
;
178 if (UnicodeString
.Length
)
180 RtlCopyMemory(UnicodeName
->String
,
181 UnicodeString
.Buffer
,
182 UnicodeString
.Length
);
185 RtlFreeUnicodeString(&UnicodeString
);
188 if (!NT_SUCCESS(Status
))
190 if (Status
== STATUS_BUFFER_TOO_SMALL
)
192 RootHubName
->Header
.UsbUserStatusCode
= UsbUserBufferTooSmall
;
196 RootHubName
->Header
.UsbUserStatusCode
= UsbUserInvalidParameter
;
201 RootHubName
->Header
.UsbUserStatusCode
= UsbUserSuccess
;
202 UnicodeName
->Length
= ResultLength
+ sizeof(UNICODE_NULL
);
205 RootHubName
->Header
.ActualBufferLength
= sizeof(USBUSER_CONTROLLER_UNICODE_NAME
) +
211 USBPORT_GetUnicodeName(IN PDEVICE_OBJECT FdoDevice
,
213 IN PULONG Information
)
215 PUSB_HCD_DRIVERKEY_NAME DriverKey
;
216 PIO_STACK_LOCATION IoStack
;
217 ULONG OutputBufferLength
;
220 PUSBUSER_CONTROLLER_UNICODE_NAME ControllerName
;
221 PUSB_UNICODE_NAME UnicodeName
;
224 DPRINT("USBPORT_GetUnicodeName: ... \n");
227 DriverKey
= Irp
->AssociatedIrp
.SystemBuffer
;
229 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
230 OutputBufferLength
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
231 IoControlCode
= IoStack
->Parameters
.DeviceIoControl
.IoControlCode
;
233 if (OutputBufferLength
< sizeof(USB_UNICODE_NAME
))
235 return STATUS_BUFFER_TOO_SMALL
;
238 Length
= sizeof(USBUSER_CONTROLLER_UNICODE_NAME
);
242 ControllerName
= ExAllocatePoolWithTag(PagedPool
,
248 return STATUS_INSUFFICIENT_RESOURCES
;
251 RtlZeroMemory(ControllerName
, Length
);
253 ControllerName
->Header
.RequestBufferLength
= Length
;
254 UnicodeName
= &ControllerName
->UnicodeName
;
256 if (IoControlCode
== IOCTL_GET_HCD_DRIVERKEY_NAME
)
258 ControllerName
->Header
.UsbUserRequest
= USBUSER_GET_CONTROLLER_DRIVER_KEY
;
259 USBPORT_UserGetHcName(FdoDevice
, ControllerName
, UnicodeName
);
263 ControllerName
->Header
.UsbUserRequest
= USBUSER_GET_ROOTHUB_SYMBOLIC_NAME
;
264 USBPORT_UserGetRootHubName(FdoDevice
, ControllerName
, UnicodeName
);
267 if (ControllerName
->Header
.UsbUserStatusCode
!= UsbUserBufferTooSmall
)
272 Length
= ControllerName
->Header
.ActualBufferLength
;
274 ExFreePoolWithTag(ControllerName
, USB_PORT_TAG
);
277 if (ControllerName
->Header
.UsbUserStatusCode
!= UsbUserSuccess
)
279 ExFreePoolWithTag(ControllerName
, USB_PORT_TAG
);
280 return STATUS_UNSUCCESSFUL
;
283 ActualLength
= sizeof(ULONG
) + ControllerName
->UnicodeName
.Length
;
285 DriverKey
->ActualLength
= ActualLength
;
287 if (OutputBufferLength
< ActualLength
)
289 DriverKey
->DriverKeyName
[0] = UNICODE_NULL
;
290 *Information
= sizeof(USB_UNICODE_NAME
);
294 RtlCopyMemory(DriverKey
->DriverKeyName
,
295 ControllerName
->UnicodeName
.String
,
296 ControllerName
->UnicodeName
.Length
);
298 *Information
= DriverKey
->ActualLength
;
301 ExFreePoolWithTag(ControllerName
, USB_PORT_TAG
);
303 return STATUS_SUCCESS
;
308 USBPORT_PdoDeviceControl(IN PDEVICE_OBJECT PdoDevice
,
311 DPRINT1("USBPORT_PdoDeviceControl: UNIMPLEMENTED. FIXME. \n");
317 USBPORT_PdoInternalDeviceControl(IN PDEVICE_OBJECT PdoDevice
,
320 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
321 PIO_STACK_LOCATION IoStack
;
325 PdoExtension
= PdoDevice
->DeviceExtension
;
326 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
327 IoCtl
= IoStack
->Parameters
.DeviceIoControl
.IoControlCode
;
329 //DPRINT("USBPORT_PdoInternalDeviceControl: PdoDevice - %p, Irp - %p, IoCtl - %x\n",
334 if (IoCtl
== IOCTL_INTERNAL_USB_SUBMIT_URB
)
336 return USBPORT_HandleSubmitURB(PdoDevice
, Irp
, URB_FROM_IRP(Irp
));
339 if (IoCtl
== IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
)
341 DPRINT("USBPORT_PdoInternalDeviceControl: IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n");
343 if (IoStack
->Parameters
.Others
.Argument1
)
344 *(PVOID
*)IoStack
->Parameters
.Others
.Argument1
= PdoDevice
;
346 if (IoStack
->Parameters
.Others
.Argument2
)
347 *(PVOID
*)IoStack
->Parameters
.Others
.Argument2
= PdoDevice
;
349 Status
= STATUS_SUCCESS
;
353 if (IoCtl
== IOCTL_INTERNAL_USB_GET_HUB_COUNT
)
355 DPRINT("USBPORT_PdoInternalDeviceControl: IOCTL_INTERNAL_USB_GET_HUB_COUNT\n");
357 if (IoStack
->Parameters
.Others
.Argument1
)
359 ++*(PULONG
)IoStack
->Parameters
.Others
.Argument1
;
362 Status
= STATUS_SUCCESS
;
366 if (IoCtl
== IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE
)
368 DPRINT("USBPORT_PdoInternalDeviceControl: IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
370 if (IoStack
->Parameters
.Others
.Argument1
)
372 *(PVOID
*)IoStack
->Parameters
.Others
.Argument1
= &PdoExtension
->DeviceHandle
;
375 Status
= STATUS_SUCCESS
;
379 if (IoCtl
== IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION
)
381 DPRINT("USBPORT_PdoInternalDeviceControl: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
382 return USBPORT_IdleNotification(PdoDevice
, Irp
);
385 DPRINT("USBPORT_PdoInternalDeviceControl: INVALID INTERNAL DEVICE CONTROL\n");
386 Status
= STATUS_INVALID_DEVICE_REQUEST
;
389 Irp
->IoStatus
.Status
= Status
;
390 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
396 USBPORT_FdoDeviceControl(IN PDEVICE_OBJECT FdoDevice
,
399 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
400 PIO_STACK_LOCATION IoStack
;
402 NTSTATUS Status
= STATUS_INVALID_DEVICE_REQUEST
;
403 ULONG_PTR Information
= 0;
405 DPRINT("USBPORT_FdoDeviceControl: Irp - %p\n", Irp
);
407 FdoExtension
= FdoDevice
->DeviceExtension
;
409 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
410 ControlCode
= IoStack
->Parameters
.DeviceIoControl
.IoControlCode
;
414 case IOCTL_USB_DIAGNOSTIC_MODE_ON
:
415 DPRINT("USBPORT_FdoDeviceControl: IOCTL_USB_DIAGNOSTIC_MODE_ON\n");
416 FdoExtension
->Flags
|= USBPORT_FLAG_DIAGNOSTIC_MODE
;
419 case IOCTL_USB_DIAGNOSTIC_MODE_OFF
:
420 DPRINT("USBPORT_FdoDeviceControl: IOCTL_USB_DIAGNOSTIC_MODE_OFF\n");
421 FdoExtension
->Flags
&= ~USBPORT_FLAG_DIAGNOSTIC_MODE
;
424 case IOCTL_USB_GET_NODE_INFORMATION
:
425 DPRINT1("USBPORT_FdoDeviceControl: IOCTL_USB_GET_NODE_INFORMATION\n");
426 Status
= USBPORT_GetUnicodeName(FdoDevice
, Irp
, &Information
);
429 case IOCTL_GET_HCD_DRIVERKEY_NAME
:
430 DPRINT1("USBPORT_FdoDeviceControl: IOCTL_GET_HCD_DRIVERKEY_NAME\n");
431 Status
= USBPORT_GetUnicodeName(FdoDevice
, Irp
, &Information
);
434 case IOCTL_USB_USER_REQUEST
:
435 DPRINT1("USBPORT_FdoDeviceControl: IOCTL_USB_USER_REQUEST UNIMPLEMENTED. FIXME\n");
439 DPRINT1("USBPORT_FdoDeviceControl: Not supported IoControlCode - %x\n",
441 Status
= STATUS_INVALID_DEVICE_REQUEST
;
445 Irp
->IoStatus
.Status
= Status
;
446 Irp
->IoStatus
.Information
= Information
;
447 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
454 USBPORT_FdoInternalDeviceControl(IN PDEVICE_OBJECT FdoDevice
,
457 DPRINT1("USBPORT_FdoInternalDeviceControl: UNIMPLEMENTED. FIXME. \n");