ReactOS 0.4.15-dev-8241-g63935f8
fdo.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Universal Serial Bus Human Interface Device Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/hid/hidclass/fdo.c
5 * PURPOSE: HID Class Driver
6 * PROGRAMMERS:
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
9 */
10
11#include "precomp.h"
12
13#define NDEBUG
14#include <debug.h>
15
20 IN PIRP Irp,
22{
23 //
24 // set event
25 //
27
28 //
29 // completion is done in the HidClassFDO_QueryCapabilities routine
30 //
32}
33
38{
39 PIRP Irp;
42 PIO_STACK_LOCATION IoStack;
43 PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
44
45 //
46 // get device extension
47 //
48 FDODeviceExtension = DeviceObject->DeviceExtension;
49 ASSERT(FDODeviceExtension->Common.IsFDO);
50
51 //
52 // init event
53 //
55
56 //
57 // now allocate the irp
58 //
59 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
60 if (!Irp)
61 {
62 //
63 // no memory
64 //
66 }
67
68 //
69 // get next stack location
70 //
72
73 //
74 // init stack location
75 //
76 IoStack->MajorFunction = IRP_MJ_PNP;
78 IoStack->Parameters.DeviceCapabilities.Capabilities = Capabilities;
79
80 //
81 // set completion routine
82 //
84
85 //
86 // init capabilities
87 //
89 Capabilities->Size = sizeof(DEVICE_CAPABILITIES);
90 Capabilities->Version = 1; // FIXME hardcoded constant
91 Capabilities->Address = MAXULONG;
92 Capabilities->UINumber = MAXULONG;
93
94 //
95 // pnp irps have default completion code
96 //
97 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
98
99 //
100 // call lower device
101 //
103 if (Status == STATUS_PENDING)
104 {
105 //
106 // wait for completion
107 //
109 }
110
111 //
112 // get status
113 //
114 Status = Irp->IoStatus.Status;
115
116 //
117 // complete request
118 //
119 IoFreeIrp(Irp);
120
121 //
122 // done
123 //
124 return Status;
125}
126
128NTAPI
131 IN PIRP Irp,
133{
134 //
135 // signal event
136 //
138
139 //
140 // done
141 //
143}
144
145
149 IN PIRP Irp)
150{
152 PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
154 PIO_STACK_LOCATION IoStack;
155
156 //
157 // init event
158 //
160
161 //
162 // get device extension
163 //
164 CommonDeviceExtension = DeviceObject->DeviceExtension;
165
166 //
167 // set completion routine
168 //
170
171 ASSERT(Irp->CurrentLocation > 0);
172 //
173 // create stack location
174 //
176
177 //
178 // get next stack location
179 //
181
182 //
183 // store device object
184 //
185 IoStack->DeviceObject = DeviceObject;
186
187 //
188 // sanity check
189 //
190 ASSERT(CommonDeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction] != NULL);
191
192 //
193 // call minidriver (hidusb)
194 //
195 Status = CommonDeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction](DeviceObject, Irp);
196
197 //
198 // wait for the request to finish
199 //
200 if (Status == STATUS_PENDING)
201 {
203
204 //
205 // update status
206 //
207 Status = Irp->IoStatus.Status;
208 }
209
210 //
211 // done
212 //
213 return Status;
214}
215
219 IN PIRP Irp)
220{
221 PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
223 PIO_STACK_LOCATION IoStack;
224
225 //
226 // get device extension
227 //
228 CommonDeviceExtension = DeviceObject->DeviceExtension;
229
230 ASSERT(Irp->CurrentLocation > 0);
231
232 //
233 // create stack location
234 //
236
237 //
238 // get next stack location
239 //
241
242 //
243 // store device object
244 //
245 IoStack->DeviceObject = DeviceObject;
246
247 //
248 // sanity check
249 //
250 ASSERT(CommonDeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction] != NULL);
251
252 //
253 // call driver
254 //
255 Status = CommonDeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction](DeviceObject, Irp);
256
257 //
258 // done
259 //
260 return Status;
261}
262
266{
267 PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
268 PIRP Irp;
269 PIO_STACK_LOCATION IoStack;
271
272 //
273 // get device extension
274 //
275 FDODeviceExtension = DeviceObject->DeviceExtension;
276 ASSERT(FDODeviceExtension->Common.IsFDO);
277
278 //
279 // let's allocate irp
280 //
281 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
282 if (!Irp)
283 {
284 //
285 // no memory
286 //
288 }
289
290 //
291 // get stack location
292 //
294
295 //
296 // init stack location
297 //
300 IoStack->Parameters.DeviceIoControl.OutputBufferLength = sizeof(HID_DESCRIPTOR);
301 IoStack->Parameters.DeviceIoControl.InputBufferLength = 0;
302 IoStack->Parameters.DeviceIoControl.Type3InputBuffer = NULL;
303 Irp->UserBuffer = &FDODeviceExtension->HidDescriptor;
304
305 //
306 // send request
307 //
309 if (!NT_SUCCESS(Status))
310 {
311 //
312 // failed to get device descriptor
313 //
314 DPRINT1("[HIDCLASS] IOCTL_HID_GET_DEVICE_DESCRIPTOR failed with %x\n", Status);
315 IoFreeIrp(Irp);
316 return Status;
317 }
318
319 //
320 // let's get device attributes
321 //
323 IoStack->Parameters.DeviceIoControl.OutputBufferLength = sizeof(HID_DEVICE_ATTRIBUTES);
324 Irp->UserBuffer = &FDODeviceExtension->Common.Attributes;
325
326 //
327 // send request
328 //
330 if (!NT_SUCCESS(Status))
331 {
332 //
333 // failed to get device descriptor
334 //
335 DPRINT1("[HIDCLASS] IOCTL_HID_GET_DEVICE_ATTRIBUTES failed with %x\n", Status);
336 IoFreeIrp(Irp);
337 return Status;
338 }
339
340 //
341 // sanity checks
342 //
343 ASSERT(FDODeviceExtension->HidDescriptor.bLength == sizeof(HID_DESCRIPTOR));
344 ASSERT(FDODeviceExtension->HidDescriptor.bNumDescriptors > 0);
345 ASSERT(FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength > 0);
346 ASSERT(FDODeviceExtension->HidDescriptor.DescriptorList[0].bReportType == HID_REPORT_DESCRIPTOR_TYPE);
347
348 //
349 // now allocate space for the report descriptor
350 //
352 FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength,
354 if (!FDODeviceExtension->ReportDescriptor)
355 {
356 //
357 // not enough memory
358 //
359 IoFreeIrp(Irp);
361 }
362
363 //
364 // init stack location
365 //
367 IoStack->Parameters.DeviceIoControl.OutputBufferLength = FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength;
368 Irp->UserBuffer = FDODeviceExtension->ReportDescriptor;
369
370 //
371 // send request
372 //
374 if (!NT_SUCCESS(Status))
375 {
376 //
377 // failed to get device descriptor
378 //
379 DPRINT1("[HIDCLASS] IOCTL_HID_GET_REPORT_DESCRIPTOR failed with %x\n", Status);
380 IoFreeIrp(Irp);
381 return Status;
382 }
383
384 //
385 // completed successfully
386 //
387 IoFreeIrp(Irp);
388 return STATUS_SUCCESS;
389}
390
391
395 IN PIRP Irp)
396{
398 PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
399
400 //
401 // get device extension
402 //
403 FDODeviceExtension = DeviceObject->DeviceExtension;
404 ASSERT(FDODeviceExtension->Common.IsFDO);
405
406 //
407 // query capabilities
408 //
410 if (!NT_SUCCESS(Status))
411 {
412 DPRINT1("[HIDCLASS] Failed to retrieve capabilities %x\n", Status);
413 Irp->IoStatus.Status = Status;
415 return Status;
416 }
417
418 //
419 // let's start the lower device too
420 //
423 if (!NT_SUCCESS(Status))
424 {
425 DPRINT1("[HIDCLASS] Failed to start lower device with %x\n", Status);
426 Irp->IoStatus.Status = Status;
428 return Status;
429 }
430
431 //
432 // let's get the descriptors
433 //
435 if (!NT_SUCCESS(Status))
436 {
437 DPRINT1("[HIDCLASS] Failed to retrieve the descriptors %x\n", Status);
438 Irp->IoStatus.Status = Status;
440 return Status;
441 }
442
443 //
444 // now get the the collection description
445 //
446 Status = HidP_GetCollectionDescription(FDODeviceExtension->ReportDescriptor, FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength, NonPagedPool, &FDODeviceExtension->Common.DeviceDescription);
447 if (!NT_SUCCESS(Status))
448 {
449 DPRINT1("[HIDCLASS] Failed to retrieve the collection description %x\n", Status);
450 Irp->IoStatus.Status = Status;
452 return Status;
453 }
454
455 //
456 // complete request
457 //
458 Irp->IoStatus.Status = Status;
460 return Status;
461}
462
466 IN PIRP Irp)
467{
469 PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
470
471 //
472 // get device extension
473 //
474 FDODeviceExtension = DeviceObject->DeviceExtension;
475 ASSERT(FDODeviceExtension->Common.IsFDO);
476
477 /* FIXME cleanup */
478
479 //
480 // dispatch to minidriver
481 //
484
485 //
486 // complete request
487 //
488 Irp->IoStatus.Status = Status;
490
491 //
492 // detach and delete device
493 //
496
497 return Status;
498}
499
503 OUT PDEVICE_RELATIONS *OutRelations)
504{
505 PDEVICE_RELATIONS DeviceRelations;
506 PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
507 ULONG Index;
508
509 //
510 // get device extension
511 //
512 FDODeviceExtension = DeviceObject->DeviceExtension;
513 ASSERT(FDODeviceExtension->Common.IsFDO);
514
515 //
516 // allocate result
517 //
518 DeviceRelations = ExAllocatePoolWithTag(NonPagedPool,
519 sizeof(DEVICE_RELATIONS) + (FDODeviceExtension->DeviceRelations->Count - 1) * sizeof(PDEVICE_OBJECT),
521 if (!DeviceRelations)
522 {
523 //
524 // no memory
525 //
526 *OutRelations = NULL;
528 }
529
530 //
531 // copy device objects
532 //
533 for (Index = 0; Index < FDODeviceExtension->DeviceRelations->Count; Index++)
534 {
535 //
536 // reference pdo
537 //
538 ObReferenceObject(FDODeviceExtension->DeviceRelations->Objects[Index]);
539
540 //
541 // store object
542 //
543 DeviceRelations->Objects[Index] = FDODeviceExtension->DeviceRelations->Objects[Index];
544 }
545
546 //
547 // set object count
548 //
549 DeviceRelations->Count = FDODeviceExtension->DeviceRelations->Count;
550
551 //
552 // store result
553 //
554 *OutRelations = DeviceRelations;
555 return STATUS_SUCCESS;
556}
557
561 IN PIRP Irp)
562{
563 PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
564 PIO_STACK_LOCATION IoStack;
566 PDEVICE_RELATIONS DeviceRelations;
567
568 //
569 // get device extension
570 //
571 FDODeviceExtension = DeviceObject->DeviceExtension;
572 ASSERT(FDODeviceExtension->Common.IsFDO);
573
574 //
575 // get current irp stack location
576 //
578
579 //
580 // check relations type
581 //
582 if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
583 {
584 //
585 // only bus relations are handled
586 //
588 return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
589 }
590
591 if (FDODeviceExtension->DeviceRelations == NULL)
592 {
593 //
594 // time to create the pdos
595 //
597 if (!NT_SUCCESS(Status))
598 {
599 //
600 // failed
601 //
602 DPRINT1("[HIDCLASS] HidClassPDO_CreatePDO failed with %x\n", Status);
603 Irp->IoStatus.Status = Status;
605 return STATUS_SUCCESS;
606 }
607 //
608 // sanity check
609 //
610 ASSERT(FDODeviceExtension->DeviceRelations->Count > 0);
611 }
612
613 //
614 // now copy device relations
615 //
617 //
618 // store result
619 //
620 Irp->IoStatus.Status = Status;
621 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
622
623 //
624 // complete request
625 //
627 return Status;
628}
629
633 IN PIRP Irp)
634{
635 PIO_STACK_LOCATION IoStack;
636 PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
638
639 //
640 // get device extension
641 //
642 FDODeviceExtension = DeviceObject->DeviceExtension;
643 ASSERT(FDODeviceExtension->Common.IsFDO);
644
645 //
646 // get current irp stack location
647 //
649 switch (IoStack->MinorFunction)
650 {
652 {
654 }
656 {
658 }
660 {
662 }
667 {
668 //
669 // set status to success and fall through
670 //
671 Irp->IoStatus.Status = STATUS_SUCCESS;
672 }
673 default:
674 {
675 //
676 // dispatch to mini driver
677 //
680 return Status;
681 }
682 }
683}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_In_ PIRP Irp
Definition: csq.h:116
#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:32
#define HIDCLASS_TAG
Definition: precomp.h:10
#define ULONG_PTR
Definition: config.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#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 NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:25
NTSTATUS HidClassFDO_RemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:464
NTSTATUS NTAPI HidClassFDO_DispatchRequestSynchronousCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: fdo.c:129
NTSTATUS NTAPI HidClassFDO_QueryCapabilitiesCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: fdo.c:18
NTSTATUS HidClassFDO_DispatchRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:217
NTSTATUS HidClassFDO_StartDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:393
NTSTATUS HidClassFDO_DeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:559
NTSTATUS HidClassFDO_GetDescriptors(IN PDEVICE_OBJECT DeviceObject)
Definition: fdo.c:264
NTSTATUS HidClassFDO_DispatchRequestSynchronous(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:147
NTSTATUS HidClassFDO_QueryCapabilities(IN PDEVICE_OBJECT DeviceObject, IN OUT PDEVICE_CAPABILITIES Capabilities)
Definition: fdo.c:35
NTSTATUS HidClassFDO_CopyDeviceRelations(IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_RELATIONS *OutRelations)
Definition: fdo.c:501
NTSTATUS HidClassFDO_PnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:631
NTSTATUS HidClassPDO_CreatePDO(IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_RELATIONS *OutDeviceRelations)
Definition: pdo.c:660
_Must_inspect_result_ typedef _Out_ PHIDP_CAPS Capabilities
Definition: hidclass.h:103
NTSTATUS NTAPI HidP_GetCollectionDescription(IN PHIDP_REPORT_DESCRIPTOR ReportDesc, IN ULONG DescLength, IN POOL_TYPE PoolType, OUT PHIDP_DEVICE_DESC DeviceDescription)
Definition: hidp.c:61
#define IOCTL_HID_GET_DEVICE_DESCRIPTOR
Definition: hidport.h:84
#define IOCTL_HID_GET_DEVICE_ATTRIBUTES
Definition: hidport.h:91
#define HID_REPORT_DESCRIPTOR_TYPE
Definition: hidport.h:95
struct _HID_DEVICE_ATTRIBUTES HID_DEVICE_ATTRIBUTES
#define IOCTL_HID_GET_REPORT_DESCRIPTOR
Definition: hidport.h:85
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define ASSERT(a)
Definition: mode.c:44
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
HIDP_DEVICE_DESC DeviceDescription
Definition: precomp.h:44
PHIDCLASS_DRIVER_EXTENSION DriverExtension
Definition: precomp.h:39
HID_DEVICE_ATTRIBUTES Attributes
Definition: precomp.h:49
HID_DEVICE_EXTENSION HidDeviceExtension
Definition: precomp.h:29
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: precomp.h:17
PDEVICE_RELATIONS DeviceRelations
Definition: precomp.h:78
HIDCLASS_COMMON_DEVICE_EXTENSION Common
Definition: precomp.h:58
DEVICE_CAPABILITIES Capabilities
Definition: precomp.h:63
HID_DESCRIPTOR HidDescriptor
Definition: precomp.h:68
PUCHAR ReportDescriptor
Definition: precomp.h:73
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
UCHAR bNumDescriptors
Definition: hidport.h:39
struct _HID_DESCRIPTOR::_HID_DESCRIPTOR_DESC_LIST DescriptorList[1]
UCHAR bLength
Definition: hidport.h:35
PDEVICE_OBJECT NextDeviceObject
Definition: hidport.h:18
struct _IO_STACK_LOCATION::@3991::@4016 QueryDeviceRelations
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
struct _IO_STACK_LOCATION::@3991::@4018 DeviceCapabilities
union _IO_STACK_LOCATION::@1573 Parameters
struct _IO_STACK_LOCATION::@1573::@1574 DeviceIoControl
#define MAXULONG
Definition: typedefs.h:251
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define HID_DESCRIPTOR
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2680
#define IRP_MN_CANCEL_STOP_DEVICE
DEVICE_CAPABILITIES
Definition: iotypes.h:965
@ BusRelations
Definition: iotypes.h:2152
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_START_DEVICE
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_QUERY_CAPABILITIES
* PDEVICE_CAPABILITIES
Definition: iotypes.h:965
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define IRP_MN_QUERY_REMOVE_DEVICE
@ Executive
Definition: ketypes.h:415
#define ObReferenceObject
Definition: obfuncs.h:204