ReactOS  0.4.15-dev-5492-g47f3a4e
kbdclass.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Keyboard class driver
4  * FILE: drivers/kbdclass/kbdclass.c
5  * PURPOSE: Keyboard class driver
6  *
7  * PROGRAMMERS: HervĂ© Poussineau (hpoussin@reactos.org)
8  */
9 
10 #include "kbdclass.h"
11 
12 #include <stdio.h>
13 #include <pseh/pseh2.h>
14 #include <kbdmou.h>
15 #include <debug.h>
16 
17 static DRIVER_UNLOAD DriverUnload;
24 static DRIVER_ADD_DEVICE ClassAddDevice;
25 static DRIVER_STARTIO ClassStartIo;
26 static DRIVER_CANCEL ClassCancelRoutine;
27 static NTSTATUS
30  IN PIRP Irp,
31  BOOLEAN IsInStartIo);
32 
33 static VOID NTAPI
35 {
36  // nothing to do here yet
37 }
38 
39 static NTSTATUS NTAPI
42  IN PIRP Irp)
43 {
44  TRACE_(CLASS_NAME, "IRP_MJ_CREATE\n");
45 
46  if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
48 
49  /* FIXME: open all associated Port devices */
50  Irp->IoStatus.Status = STATUS_SUCCESS;
51  Irp->IoStatus.Information = 0;
53  return STATUS_SUCCESS;
54 }
55 
56 static NTSTATUS NTAPI
59  IN PIRP Irp)
60 {
61  TRACE_(CLASS_NAME, "IRP_MJ_CLOSE\n");
62 
63  if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
65 
66  /* FIXME: close all associated Port devices */
67  Irp->IoStatus.Status = STATUS_SUCCESS;
68  Irp->IoStatus.Information = 0;
70  return STATUS_SUCCESS;
71 }
72 
73 static NTSTATUS NTAPI
76  IN PIRP Irp)
77 {
78  TRACE_(CLASS_NAME, "IRP_MJ_CLEANUP\n");
79 
80  if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
82 
83  /* FIXME: cleanup all associated Port devices */
84  Irp->IoStatus.Status = STATUS_SUCCESS;
85  Irp->IoStatus.Information = 0;
87  return STATUS_SUCCESS;
88 }
89 
90 static NTSTATUS NTAPI
93  IN PIRP Irp)
94 {
95  PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
96  KIRQL OldIrql;
98 
99  TRACE_(CLASS_NAME, "IRP_MJ_READ\n");
100 
101  ASSERT(DeviceExtension->Common.IsClassDO);
102 
103  if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
105 
107  {
108  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
109  Irp->IoStatus.Information = 0;
111 
113  }
114 
115  KeAcquireSpinLock(&DeviceExtension->SpinLock, &OldIrql);
117  KeReleaseSpinLock(&DeviceExtension->SpinLock, OldIrql);
118  return Status;
119 }
120 
121 static NTSTATUS NTAPI
124  IN PIRP Irp)
125 {
126  //PCLASS_DEVICE_EXTENSION DeviceExtension;
128 
129  TRACE_(CLASS_NAME, "IRP_MJ_DEVICE_CONTROL\n");
130 
131  if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
133 
134  //DeviceExtension = (PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
135 
137  {
142  {
143  /* FIXME: We hope that all devices will return the same result.
144  * Ask only the first one */
145  PLIST_ENTRY Head = &((PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ListHead;
146  if (Head->Flink != Head)
147  {
148  /* We have at least one device */
152  return IoCallDriver(DevExt->DeviceObject, Irp);
153  }
154  break;
155  }
157  case IOCTL_KEYBOARD_SET_TYPEMATIC: /* not in MSDN, would seem logical */
158  {
159  /* Send it to all associated Port devices */
160  PLIST_ENTRY Head = &((PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ListHead;
161  PLIST_ENTRY Entry = Head->Flink;
163  while (Entry != Head)
164  {
166 
168 
170  {
171  if (!NT_SUCCESS(Irp->IoStatus.Status))
172  {
173  Status = Irp->IoStatus.Status;
174  }
175  }
176  else
177  {
179  }
180 
181  Entry = Entry->Flink;
182  }
183  break;
184  }
185  default:
186  WARN_(CLASS_NAME, "IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n",
188  ASSERT(FALSE);
189  break;
190  }
191 
192  Irp->IoStatus.Status = Status;
193  Irp->IoStatus.Information = 0;
195 
196  return Status;
197 }
198 
199 static NTSTATUS NTAPI
202  IN PIRP Irp)
203 {
205  PPORT_DEVICE_EXTENSION DeviceExtension;
206 
207  DeviceExtension = DeviceObject->DeviceExtension;
208  if (!DeviceExtension->Common.IsClassDO)
209  {
210  /* Forward port DO IRPs to lower device */
213  return PoCallDriver(DeviceExtension->LowerDevice, Irp);
214  }
215 
217  {
218  case IRP_MN_SET_POWER:
219  case IRP_MN_QUERY_POWER:
220  Irp->IoStatus.Status = STATUS_SUCCESS;
221  break;
222  }
223  Status = Irp->IoStatus.Status;
226  return Status;
227 }
228 
229 static NTSTATUS
233 {
234  UNICODE_STRING ParametersRegistryKey;
237 
238  /* HACK: We don't support multiple devices with this disabled */
239  ULONG DefaultConnectMultiplePorts = 1;
240  ULONG DefaultDataQueueSize = 0x64;
241  PCWSTR DefaultDeviceBaseName = L"KeyboardClass";
242 
243  ParametersRegistryKey.Length = 0;
244  ParametersRegistryKey.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(UNICODE_NULL);
245  ParametersRegistryKey.Buffer = ExAllocatePoolWithTag(PagedPool, ParametersRegistryKey.MaximumLength, CLASS_TAG);
246  if (!ParametersRegistryKey.Buffer)
247  {
248  WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
249  return STATUS_NO_MEMORY;
250  }
251  RtlCopyUnicodeString(&ParametersRegistryKey, RegistryPath);
252  RtlAppendUnicodeToString(&ParametersRegistryKey, L"\\Parameters");
253  ParametersRegistryKey.Buffer[ParametersRegistryKey.Length / sizeof(WCHAR)] = UNICODE_NULL;
254 
256 
258  Parameters[0].Name = L"ConnectMultiplePorts";
259  Parameters[0].EntryContext = &DriverExtension->ConnectMultiplePorts;
260  Parameters[0].DefaultType = REG_DWORD;
261  Parameters[0].DefaultData = &DefaultConnectMultiplePorts;
262  Parameters[0].DefaultLength = sizeof(ULONG);
263 
265  Parameters[1].Name = L"KeyboardDataQueueSize";
266  Parameters[1].EntryContext = &DriverExtension->DataQueueSize;
267  Parameters[1].DefaultType = REG_DWORD;
268  Parameters[1].DefaultData = &DefaultDataQueueSize;
269  Parameters[1].DefaultLength = sizeof(ULONG);
270 
272  Parameters[2].Name = L"KeyboardDeviceBaseName";
273  Parameters[2].EntryContext = &DriverExtension->DeviceBaseName;
274  Parameters[2].DefaultType = REG_SZ;
275  Parameters[2].DefaultData = (PVOID)DefaultDeviceBaseName;
276  Parameters[2].DefaultLength = 0;
277 
280  ParametersRegistryKey.Buffer,
281  Parameters,
282  NULL,
283  NULL);
284 
285  if (NT_SUCCESS(Status))
286  {
287  /* Check values */
288  if (DriverExtension->ConnectMultiplePorts != 0
289  && DriverExtension->ConnectMultiplePorts != 1)
290  {
291  DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts;
292  }
293  if (DriverExtension->DataQueueSize == 0)
294  {
295  DriverExtension->DataQueueSize = DefaultDataQueueSize;
296  }
297  }
299  {
300  /* Registry path doesn't exist. Set defaults */
301  DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts;
302  DriverExtension->DataQueueSize = DefaultDataQueueSize;
303  if (RtlCreateUnicodeString(&DriverExtension->DeviceBaseName, DefaultDeviceBaseName))
305  else
307  }
308 
309  ExFreePoolWithTag(ParametersRegistryKey.Buffer, CLASS_TAG);
310  return Status;
311 }
312 
313 static NTSTATUS
316  OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
317 {
319  ULONG DeviceId = 0;
320  ULONG PrefixLength;
321  UNICODE_STRING DeviceNameU;
322  PWSTR DeviceIdW = NULL; /* Pointer into DeviceNameU.Buffer */
324  PCLASS_DEVICE_EXTENSION DeviceExtension;
326 
327  TRACE_(CLASS_NAME, "CreateClassDeviceObject(0x%p)\n", DriverObject);
328 
329  /* Create new device object */
331  DeviceNameU.Length = 0;
332  DeviceNameU.MaximumLength =
333  (USHORT)wcslen(L"\\Device\\") * sizeof(WCHAR) /* "\Device\" */
334  + DriverExtension->DeviceBaseName.Length /* "KeyboardClass" */
335  + 4 * sizeof(WCHAR) /* Id between 0 and 9999 */
336  + sizeof(UNICODE_NULL); /* Final NULL char */
337  DeviceNameU.Buffer = ExAllocatePoolWithTag(PagedPool, DeviceNameU.MaximumLength, CLASS_TAG);
338  if (!DeviceNameU.Buffer)
339  {
340  WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
341  return STATUS_NO_MEMORY;
342  }
343  Status = RtlAppendUnicodeToString(&DeviceNameU, L"\\Device\\");
344  if (!NT_SUCCESS(Status))
345  {
346  WARN_(CLASS_NAME, "RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
347  goto cleanup;
348  }
349  Status = RtlAppendUnicodeStringToString(&DeviceNameU, &DriverExtension->DeviceBaseName);
350  if (!NT_SUCCESS(Status))
351  {
352  WARN_(CLASS_NAME, "RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
353  goto cleanup;
354  }
355  PrefixLength = DeviceNameU.MaximumLength - 4 * sizeof(WCHAR) - sizeof(UNICODE_NULL);
356  DeviceIdW = &DeviceNameU.Buffer[PrefixLength / sizeof(WCHAR)];
357  while (DeviceId < 9999)
358  {
359  DeviceNameU.Length = (USHORT)(PrefixLength + swprintf(DeviceIdW, L"%lu", DeviceId) * sizeof(WCHAR));
361  DriverObject,
362  sizeof(CLASS_DEVICE_EXTENSION),
363  &DeviceNameU,
366  FALSE,
367  &Fdo);
368  if (NT_SUCCESS(Status))
369  goto cleanup;
371  {
372  WARN_(CLASS_NAME, "IoCreateDevice() failed with status 0x%08lx\n", Status);
373  goto cleanup;
374  }
375  DeviceId++;
376  }
377  WARN_(CLASS_NAME, "Too many devices starting with '\\Device\\%wZ'\n", &DriverExtension->DeviceBaseName);
379 cleanup:
380  if (!NT_SUCCESS(Status))
381  {
382  ExFreePoolWithTag(DeviceNameU.Buffer, CLASS_TAG);
383  return Status;
384  }
385 
386  DeviceExtension = (PCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension;
387  RtlZeroMemory(DeviceExtension, sizeof(CLASS_DEVICE_EXTENSION));
388  DeviceExtension->Common.IsClassDO = TRUE;
389  DeviceExtension->DriverExtension = DriverExtension;
390  InitializeListHead(&DeviceExtension->ListHead);
391  KeInitializeSpinLock(&DeviceExtension->ListSpinLock);
392  KeInitializeSpinLock(&DeviceExtension->SpinLock);
393  DeviceExtension->InputCount = 0;
394  DeviceExtension->PortData = ExAllocatePoolWithTag(NonPagedPool, DeviceExtension->DriverExtension->DataQueueSize * sizeof(KEYBOARD_INPUT_DATA), CLASS_TAG);
395  if (!DeviceExtension->PortData)
396  {
397  ExFreePoolWithTag(DeviceNameU.Buffer, CLASS_TAG);
398  return STATUS_NO_MEMORY;
399  }
400  DeviceExtension->DeviceName = DeviceNameU.Buffer;
401  Fdo->Flags |= DO_POWER_PAGABLE;
402  Fdo->Flags |= DO_BUFFERED_IO; /* FIXME: Why is it needed for 1st stage setup? */
403  Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
404 
405  /* Add entry entry to HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
408  DriverExtension->DeviceBaseName.Buffer,
409  DeviceExtension->DeviceName,
410  REG_SZ,
411  DriverExtension->RegistryPath.Buffer,
412  DriverExtension->RegistryPath.MaximumLength);
413 
414  if (ClassDO)
415  *ClassDO = Fdo;
416 
417  return STATUS_SUCCESS;
418 }
419 
420 static NTSTATUS
422  IN PDEVICE_OBJECT ClassDeviceObject,
423  IN PIRP Irp,
424  IN PKEYBOARD_INPUT_DATA DataStart,
425  IN SIZE_T NumberOfEntries)
426 {
428 
429  if (ClassDeviceObject->Flags & DO_BUFFERED_IO)
430  {
432  Irp->AssociatedIrp.SystemBuffer,
433  DataStart,
434  NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
435  }
436  else if (ClassDeviceObject->Flags & DO_DIRECT_IO)
437  {
438  PVOID DestAddress = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
439  if (DestAddress)
440  {
442  DestAddress,
443  DataStart,
444  NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
445  }
446  else
448  }
449  else
450  {
451  _SEH2_TRY
452  {
454  Irp->UserBuffer,
455  DataStart,
456  NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
457  }
459  {
461  }
462  _SEH2_END;
463  }
464 
465  return Status;
466 }
467 
468 static BOOLEAN NTAPI
470  IN PDEVICE_OBJECT ClassDeviceObject,
471  IN OUT PKEYBOARD_INPUT_DATA DataStart,
472  IN PKEYBOARD_INPUT_DATA DataEnd,
473  IN OUT PULONG ConsumedCount)
474 {
475  PCLASS_DEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
476  KIRQL OldIrql;
477  SIZE_T InputCount = DataEnd - DataStart;
478  SIZE_T ReadSize;
479 
480  TRACE_(CLASS_NAME, "ClassCallback()\n");
481 
482  ASSERT(ClassDeviceExtension->Common.IsClassDO);
483 
484  KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql);
485  if (InputCount > 0)
486  {
487  if (ClassDeviceExtension->InputCount + InputCount > ClassDeviceExtension->DriverExtension->DataQueueSize)
488  {
489  /*
490  * We're exceeding the buffer, and data will be thrown away...
491  * FIXME: What could we do, as we are at DISPATCH_LEVEL?
492  */
493  ReadSize = ClassDeviceExtension->DriverExtension->DataQueueSize - ClassDeviceExtension->InputCount;
494  }
495  else
496  ReadSize = InputCount;
497 
498  /*
499  * Move the input data from the port data queue to our class data
500  * queue.
501  */
503  &ClassDeviceExtension->PortData[ClassDeviceExtension->InputCount],
504  (PCHAR)DataStart,
505  sizeof(KEYBOARD_INPUT_DATA) * ReadSize);
506 
507  /* Move the counter up */
508  ClassDeviceExtension->InputCount += ReadSize;
509 
510  (*ConsumedCount) += (ULONG)ReadSize;
511 
512  /* Complete pending IRP (if any) */
513  if (ClassDeviceExtension->PendingIrp)
514  HandleReadIrp(ClassDeviceObject, ClassDeviceExtension->PendingIrp, FALSE);
515  }
516  KeReleaseSpinLock(&ClassDeviceExtension->SpinLock, OldIrql);
517 
518  TRACE_(CLASS_NAME, "Leaving ClassCallback()\n");
519  return TRUE;
520 }
521 
522 /* Send IOCTL_INTERNAL_*_CONNECT to port */
523 static NTSTATUS
525  IN PDEVICE_OBJECT PortDO,
526  IN PDEVICE_OBJECT ClassDO)
527 {
528  KEVENT Event;
529  PIRP Irp;
531  CONNECT_DATA ConnectData;
533 
534  TRACE_(CLASS_NAME, "Connecting PortDO %p to ClassDO %p\n", PortDO, ClassDO);
535 
537 
538  ConnectData.ClassDeviceObject = ClassDO;
539  ConnectData.ClassService = ClassCallback;
540 
543  PortDO,
544  &ConnectData, sizeof(CONNECT_DATA),
545  NULL, 0,
546  TRUE, &Event, &IoStatus);
547  if (!Irp)
549 
550  Status = IoCallDriver(PortDO, Irp);
551 
552  if (Status == STATUS_PENDING)
554  else
555  IoStatus.Status = Status;
556 
557  if (NT_SUCCESS(IoStatus.Status))
558  {
559  ObReferenceObject(PortDO);
561  &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListHead,
562  &((PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension)->ListEntry,
563  &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListSpinLock);
564  if (ClassDO->StackSize <= PortDO->StackSize)
565  {
566  /* Increase the stack size, in case we have to
567  * forward some IRPs to the port device object
568  */
569  ClassDO->StackSize = PortDO->StackSize + 1;
570  }
571  }
572 
573  return IoStatus.Status;
574 }
575 
576 /* Send IOCTL_INTERNAL_*_DISCONNECT to port + destroy the Port DO */
577 static VOID
579  IN PDEVICE_OBJECT PortDO)
580 {
581  PPORT_DEVICE_EXTENSION DeviceExtension;
582  PCLASS_DEVICE_EXTENSION ClassDeviceExtension;
584  KEVENT Event;
585  PIRP Irp;
587  KIRQL OldIrql;
589 
590  TRACE_(CLASS_NAME, "Destroying PortDO %p\n", PortDO);
591 
592  DeviceExtension = (PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension;
593  ClassDeviceExtension = DeviceExtension->ClassDO->DeviceExtension;
594  DriverExtension = IoGetDriverObjectExtension(PortDO->DriverObject, PortDO->DriverObject);
595 
596  /* Send IOCTL_INTERNAL_*_DISCONNECT */
600  PortDO,
601  NULL, 0,
602  NULL, 0,
603  TRUE, &Event, &IoStatus);
604  if (Irp)
605  {
606  Status = IoCallDriver(PortDO, Irp);
607  if (Status == STATUS_PENDING)
609  }
610 
611  /* Remove from ClassDeviceExtension->ListHead list */
612  KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql);
613  RemoveEntryList(&DeviceExtension->ListEntry);
614  KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql);
615 
616  /* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
619  DriverExtension->DeviceBaseName.Buffer,
620  ClassDeviceExtension->DeviceName);
621 
622  if (DeviceExtension->LowerDevice)
623  IoDetachDevice(DeviceExtension->LowerDevice);
624  ObDereferenceObject(PortDO);
625 
626  if (!DriverExtension->ConnectMultiplePorts && DeviceExtension->ClassDO)
627  {
628  ExFreePoolWithTag(ClassDeviceExtension->PortData, CLASS_TAG);
629  ExFreePoolWithTag((PVOID)ClassDeviceExtension->DeviceName, CLASS_TAG);
630  IoDeleteDevice(DeviceExtension->ClassDO);
631  }
632 
633  IoDeleteDevice(PortDO);
634 }
635 
636 static NTSTATUS NTAPI
640 {
643  PPORT_DEVICE_EXTENSION DeviceExtension = NULL;
645 
646  TRACE_(CLASS_NAME, "ClassAddDevice called. Pdo = 0x%p\n", Pdo);
647 
649 
650  if (Pdo == NULL)
651  /* We may get a NULL Pdo at the first call as we're a legacy driver. Ignore it */
652  return STATUS_SUCCESS;
653 
654  /* Create new device object */
656  DriverObject,
657  sizeof(PORT_DEVICE_EXTENSION),
658  NULL,
659  Pdo->DeviceType,
660  Pdo->Characteristics & FILE_DEVICE_SECURE_OPEN ? FILE_DEVICE_SECURE_OPEN : 0,
661  FALSE,
662  &Fdo);
663  if (!NT_SUCCESS(Status))
664  {
665  WARN_(CLASS_NAME, "IoCreateDevice() failed with status 0x%08lx\n", Status);
666  goto cleanup;
667  }
669 
670  DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension;
671  RtlZeroMemory(DeviceExtension, sizeof(PORT_DEVICE_EXTENSION));
672  DeviceExtension->Common.IsClassDO = FALSE;
673  DeviceExtension->DeviceObject = Fdo;
674  DeviceExtension->PnpState = dsStopped;
676  if (!NT_SUCCESS(Status))
677  {
678  WARN_(CLASS_NAME, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
679  goto cleanup;
680  }
681  if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
682  Fdo->Flags |= DO_POWER_PAGABLE;
683  if (DeviceExtension->LowerDevice->Flags & DO_BUFFERED_IO)
684  Fdo->Flags |= DO_BUFFERED_IO;
685  if (DeviceExtension->LowerDevice->Flags & DO_DIRECT_IO)
686  Fdo->Flags |= DO_DIRECT_IO;
687 
688  if (DriverExtension->ConnectMultiplePorts)
689  DeviceExtension->ClassDO = DriverExtension->MainClassDeviceObject;
690  else
691  {
692  /* We need a new class device object for this Fdo */
694  DriverObject,
695  &DeviceExtension->ClassDO);
696  if (!NT_SUCCESS(Status))
697  {
698  WARN_(CLASS_NAME, "CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
699  goto cleanup;
700  }
701  }
702  Status = ConnectPortDriver(Fdo, DeviceExtension->ClassDO);
703  if (!NT_SUCCESS(Status))
704  {
705  WARN_(CLASS_NAME, "ConnectPortDriver() failed with status 0x%08lx\n", Status);
706  goto cleanup;
707  }
708  Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
709 
710  /* Register interface ; ignore the error (if any) as having
711  * a registered interface is not so important... */
713  Pdo,
714  &GUID_DEVINTERFACE_KEYBOARD,
715  NULL,
716  &DeviceExtension->InterfaceName);
717  if (!NT_SUCCESS(Status))
718  DeviceExtension->InterfaceName.Length = 0;
719 
720  return STATUS_SUCCESS;
721 
722 cleanup:
723  if (Fdo)
725  return Status;
726 }
727 
728 static VOID NTAPI
731  IN PIRP Irp)
732 {
733  PCLASS_DEVICE_EXTENSION ClassDeviceExtension = DeviceObject->DeviceExtension;
734  KIRQL OldIrql;
735  BOOLEAN wasQueued = FALSE;
736 
737  TRACE_(CLASS_NAME, "ClassCancelRoutine(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
738 
739  ASSERT(ClassDeviceExtension->Common.IsClassDO);
740 
741  IoReleaseCancelSpinLock(Irp->CancelIrql);
742 
743  KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql);
744 
745  if (ClassDeviceExtension->PendingIrp == Irp)
746  {
747  ClassDeviceExtension->PendingIrp = NULL;
748  wasQueued = TRUE;
749  }
750  KeReleaseSpinLock(&ClassDeviceExtension->SpinLock, OldIrql);
751 
752  if (wasQueued)
753  {
754  Irp->IoStatus.Status = STATUS_CANCELLED;
755  Irp->IoStatus.Information = 0;
757  }
758  else
759  {
760  DPRINT1("Cancelled IRP is not pending. Race condition?\n");
761  }
762 }
763 
764 static NTSTATUS
767  IN PIRP Irp,
768  BOOLEAN IsInStartIo)
769 {
770  PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
772  KIRQL OldIrql;
773 
774  TRACE_(CLASS_NAME, "HandleReadIrp(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
775 
776  ASSERT(DeviceExtension->Common.IsClassDO);
777 
778  if (DeviceExtension->InputCount > 0)
779  {
780  SIZE_T NumberOfEntries;
781 
782  NumberOfEntries = MIN(
783  DeviceExtension->InputCount,
785 
787  DeviceObject,
788  Irp,
789  DeviceExtension->PortData,
790  NumberOfEntries);
791 
792  if (NT_SUCCESS(Status))
793  {
794  if (DeviceExtension->InputCount > NumberOfEntries)
795  {
797  &DeviceExtension->PortData[0],
798  &DeviceExtension->PortData[NumberOfEntries],
799  (DeviceExtension->InputCount - NumberOfEntries) * sizeof(KEYBOARD_INPUT_DATA));
800  }
801 
802  DeviceExtension->InputCount -= NumberOfEntries;
803 
804  Irp->IoStatus.Information = NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA);
805  }
806 
807  /* Go to next packet and complete this request */
808  Irp->IoStatus.Status = Status;
809 
812  DeviceExtension->PendingIrp = NULL;
813  }
814  else
815  {
817  if (Irp->Cancel)
818  {
819  DeviceExtension->PendingIrp = NULL;
821  }
822  else
823  {
825  DeviceExtension->PendingIrp = Irp;
828  }
830  }
831  return Status;
832 }
833 
834 static NTSTATUS NTAPI
837  IN PIRP Irp)
838 {
839  PPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
844 
845  switch (IrpSp->MinorFunction)
846  {
847  case IRP_MN_START_DEVICE:
848  if (IoForwardIrpSynchronously(DeviceExtension->LowerDevice, Irp))
849  {
850  Status = Irp->IoStatus.Status;
851  }
852  else
853  {
855  }
856 
857  if (NT_SUCCESS(Status))
858  {
860  &DeviceExtension->InterfaceName,
862  NULL,
863  NULL);
864 
865  Status = ZwOpenFile(&DeviceExtension->FileHandle,
868  &Iosb,
869  0,
870  0);
871  if (!NT_SUCCESS(Status))
872  DeviceExtension->FileHandle = NULL;
873  }
874  else
875  DeviceExtension->FileHandle = NULL;
876  Irp->IoStatus.Status = Status;
878  return Status;
879 
880  case IRP_MN_STOP_DEVICE:
881  if (DeviceExtension->FileHandle)
882  {
883  ZwClose(DeviceExtension->FileHandle);
884  DeviceExtension->FileHandle = NULL;
885  }
887  break;
888 
890  if (DeviceExtension->FileHandle)
891  {
892  ZwClose(DeviceExtension->FileHandle);
893  DeviceExtension->FileHandle = NULL;
894  }
896  Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
898  return Status;
899 
900  default:
901  Status = Irp->IoStatus.Status;
902  break;
903  }
904 
905  Irp->IoStatus.Status = Status;
907  {
909  return IoCallDriver(DeviceExtension->LowerDevice, Irp);
910  }
911  else
912  {
914  return Status;
915  }
916 }
917 
918 static VOID NTAPI
921  IN PIRP Irp)
922 {
923  PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
924  KIRQL OldIrql;
925 
926  TRACE_(CLASS_NAME, "ClassStartIo(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
927 
928  ASSERT(DeviceExtension->Common.IsClassDO);
929 
930  KeAcquireSpinLock(&DeviceExtension->SpinLock, &OldIrql);
932  KeReleaseSpinLock(&DeviceExtension->SpinLock, OldIrql);
933 }
934 
935 static VOID NTAPI
938  IN PVOID Context, /* PCLASS_DRIVER_EXTENSION */
939  IN ULONG Count)
940 {
941  UNICODE_STRING DeviceMapKeyU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
943  UNICODE_STRING PortBaseName = { 0, 0, NULL };
944  PKEY_VALUE_BASIC_INFORMATION KeyValueInformation = NULL;
946  HANDLE hDeviceMapKey = (HANDLE)-1;
947  HANDLE hPortKey = (HANDLE)-1;
948  ULONG Index = 0;
951 
952  TRACE_(CLASS_NAME, "SearchForLegacyDrivers(%p %p %lu)\n",
954 
955  if (Count != 1)
956  return;
958 
959  /* Create port base name, by replacing Class by Port at the end of the class base name */
962  &DriverExtension->DeviceBaseName,
963  &PortBaseName);
964  if (!NT_SUCCESS(Status))
965  {
966  WARN_(CLASS_NAME, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status);
967  goto cleanup;
968  }
969  PortBaseName.Length -= (sizeof(L"Class") - sizeof(UNICODE_NULL));
970  RtlAppendUnicodeToString(&PortBaseName, L"Port");
971 
972  /* Allocate memory */
974  KeyValueInformation = ExAllocatePoolWithTag(PagedPool, Size, CLASS_TAG);
975  if (!KeyValueInformation)
976  {
977  WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
979  goto cleanup;
980  }
981 
982  /* Open HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
984  Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
986  {
987  INFO_(CLASS_NAME, "HKLM\\HARDWARE\\DEVICEMAP is non-existent\n");
989  goto cleanup;
990  }
991  else if (!NT_SUCCESS(Status))
992  {
993  WARN_(CLASS_NAME, "ZwOpenKey() failed with status 0x%08lx\n", Status);
994  goto cleanup;
995  }
996 
997  /* Open sub key */
999  Status = ZwOpenKey(&hPortKey, KEY_QUERY_VALUE, &ObjectAttributes);
1001  {
1002  INFO_(CLASS_NAME, "HKLM\\HARDWARE\\DEVICEMAP\\%wZ is non-existent\n", &PortBaseName);
1004  goto cleanup;
1005  }
1006  else if (!NT_SUCCESS(Status))
1007  {
1008  WARN_(CLASS_NAME, "ZwOpenKey() failed with status 0x%08lx\n", Status);
1009  goto cleanup;
1010  }
1011 
1012  /* Read each value name */
1013  while (ZwEnumerateValueKey(hPortKey, Index++, KeyValueBasicInformation, KeyValueInformation, Size, &ResultLength) == STATUS_SUCCESS)
1014  {
1016  PDEVICE_OBJECT PortDeviceObject = NULL;
1018 
1019  PortName.Length = PortName.MaximumLength = (USHORT)KeyValueInformation->NameLength;
1020  PortName.Buffer = KeyValueInformation->Name;
1021 
1022  /* Open the device object pointer */
1024  if (!NT_SUCCESS(Status))
1025  {
1026  WARN_(CLASS_NAME, "IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", &PortName, Status);
1027  continue;
1028  }
1029  INFO_(CLASS_NAME, "Legacy driver found\n");
1030 
1031  Status = ClassAddDevice(DriverObject, PortDeviceObject);
1032  if (!NT_SUCCESS(Status))
1033  {
1034  /* FIXME: Log the error */
1035  WARN_(CLASS_NAME, "ClassAddDevice() failed with status 0x%08lx\n", Status);
1036  }
1037 
1039  }
1040 
1041 cleanup:
1042  if (KeyValueInformation != NULL)
1043  ExFreePoolWithTag(KeyValueInformation, CLASS_TAG);
1044  if (hDeviceMapKey != (HANDLE)-1)
1045  ZwClose(hDeviceMapKey);
1046  if (hPortKey != (HANDLE)-1)
1047  ZwClose(hPortKey);
1048 }
1049 
1050 /*
1051  * Standard DriverEntry method.
1052  */
1057 {
1059  NTSTATUS Status;
1060 
1062  DriverObject,
1063  DriverObject,
1064  sizeof(CLASS_DRIVER_EXTENSION),
1065  (PVOID*)&DriverExtension);
1066  if (!NT_SUCCESS(Status))
1067  {
1068  WARN_(CLASS_NAME, "IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status);
1069  return Status;
1070  }
1072 
1075  RegistryPath,
1076  &DriverExtension->RegistryPath);
1077  if (!NT_SUCCESS(Status))
1078  {
1079  WARN_(CLASS_NAME, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status);
1080  return Status;
1081  }
1082 
1084  if (!NT_SUCCESS(Status))
1085  {
1086  WARN_(CLASS_NAME, "ReadRegistryEntries() failed with status 0x%08lx\n", Status);
1087  return Status;
1088  }
1089 
1090  if (DriverExtension->ConnectMultiplePorts == 1)
1091  {
1093  DriverObject,
1094  &DriverExtension->MainClassDeviceObject);
1095  if (!NT_SUCCESS(Status))
1096  {
1097  WARN_(CLASS_NAME, "CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
1098  return Status;
1099  }
1100  }
1101 
1102  DriverObject->DriverExtension->AddDevice = ClassAddDevice;
1103  DriverObject->DriverUnload = DriverUnload;
1104 
1105  DriverObject->MajorFunction[IRP_MJ_CREATE] = ClassCreate;
1106  DriverObject->MajorFunction[IRP_MJ_CLOSE] = ClassClose;
1107  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = ClassCleanup;
1108  DriverObject->MajorFunction[IRP_MJ_READ] = ClassRead;
1109  DriverObject->MajorFunction[IRP_MJ_POWER] = ClassPower;
1110  DriverObject->MajorFunction[IRP_MJ_PNP] = ClassPnp;
1113  DriverObject->DriverStartIo = ClassStartIo;
1114 
1115  /* We will detect the legacy devices later */
1117  DriverObject,
1119  DriverExtension);
1120 
1121  return STATUS_SUCCESS;
1122 }
_SEH2_TRY
Definition: create.c:4226
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
signed char * PCHAR
Definition: retypes.h:7
#define CLASS_TAG
Definition: kbdclass.h:11
#define DO_POWER_PAGABLE
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
return STATUS_NOT_SUPPORTED
#define IOCTL_KEYBOARD_QUERY_TYPEMATIC
Definition: ntddkbd.h:41
struct _KEY_VALUE_BASIC_INFORMATION KEY_VALUE_BASIC_INFORMATION
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION
Definition: ntddkbd.h:38
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define INFO_(ch,...)
Definition: debug.h:159
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1804
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define IRP_MN_QUERY_POWER
USHORT MaximumLength
Definition: env_spec_w32.h:370
static DRIVER_DISPATCH ClassRead
Definition: kbdclass.c:21
struct _IO_STACK_LOCATION::@3754::@3771 DeviceIoControl
#define TRUE
Definition: types.h:120
static DRIVER_DISPATCH ClassCleanup
Definition: kbdclass.c:20
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:56
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
#define IO_KEYBOARD_INCREMENT
Definition: iotypes.h:601
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
static DRIVER_ADD_DEVICE ClassAddDevice
Definition: kbdclass.c:24
_SEH2_END
Definition: create.c:4400
struct _IO_STACK_LOCATION::@3754::@3758 Read
IoSetCancelRoutine(Irp, CancelRoutine)
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
LIST_ENTRY ListEntry
Definition: kbdclass.h:44
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1775
static NTSTATUS NTAPI ClassPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: kbdclass.c:835
struct _CLASS_DEVICE_EXTENSION * PCLASS_DEVICE_EXTENSION
T MIN(T a, T b)
Definition: polytest.cpp:79
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
PDEVICE_OBJECT ClassDO
Definition: kbdclass.h:48
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define L(x)
Definition: ntvdm.h:50
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
_In_ PIRP Irp
Definition: csq.h:116
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
static DRIVER_DISPATCH ClassClose
Definition: kbdclass.c:19
#define IOCTL_KEYBOARD_SET_TYPEMATIC
Definition: ntddkbd.h:44
#define FILE_READ_DATA
Definition: nt_native.h:628
UNICODE_STRING InterfaceName
Definition: kbdclass.h:50
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_ WDFDRIVER _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ PDEVICE_OBJECT _In_opt_ PDEVICE_OBJECT _In_opt_ PDEVICE_OBJECT Pdo
Definition: wdfminiport.h:64
static VOID NTAPI SearchForLegacyDrivers(IN PDRIVER_OBJECT DriverObject, IN PVOID Context, IN ULONG Count)
Definition: kbdclass.c:936
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1697
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:240
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
static NTSTATUS ReadRegistryEntries(IN PUNICODE_STRING RegistryPath, IN PCLASS_DRIVER_EXTENSION DriverExtension)
Definition: kbdclass.c:230
#define IoCompleteRequest
Definition: irp.c:1240
static DRIVER_DISPATCH ClassPower
Definition: kbdclass.c:23
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
void * PVOID
Definition: retypes.h:9
struct _KEYBOARD_INPUT_DATA KEYBOARD_INPUT_DATA
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
Status
Definition: gdiplustypes.h:24
#define TRACE_(x)
Definition: compat.h:76
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define IOCTL_KEYBOARD_QUERY_INDICATORS
Definition: ntddkbd.h:35
#define IOCTL_INTERNAL_KEYBOARD_DISCONNECT
Definition: kbdmou.h:59
static NTSTATUS ConnectPortDriver(IN PDEVICE_OBJECT PortDO, IN PDEVICE_OBJECT ClassDO)
Definition: kbdclass.c:524
int Count
Definition: noreturn.cpp:7
#define IRP_MN_STOP_DEVICE
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
NTSTATUS NTAPI IoAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice, IN OUT PDEVICE_OBJECT *AttachedToDeviceObject)
Definition: device.c:980
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
VOID NTAPI IoSetStartIoAttributes(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DeferredStartIo, IN BOOLEAN NonCancelable)
Definition: device.c:1798
_In_ WDFCOLLECTION _In_ ULONG Index
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
static NTSTATUS FillEntries(IN PDEVICE_OBJECT ClassDeviceObject, IN PIRP Irp, IN PKEYBOARD_INPUT_DATA DataStart, IN SIZE_T NumberOfEntries)
Definition: kbdclass.c:421
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
NTSTATUS DuplicateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString)
Definition: misc.c:31
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
PDEVICE_OBJECT LowerDevice
Definition: kbdclass.h:47
static NTSTATUS HandleReadIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, BOOLEAN IsInStartIo)
Definition: kbdclass.c:765
#define MAX_PATH
Definition: compat.h:34
static DRIVER_STARTIO ClassStartIo
Definition: kbdclass.c:25
#define IRP_MN_START_DEVICE
#define ObDereferenceObject
Definition: obfuncs.h:203
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
PVOID HANDLE
Definition: typedefs.h:73
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
* PFILE_OBJECT
Definition: iotypes.h:1998
PVOID ClassService
Definition: kbdmou.h:82
#define IOCTL_INTERNAL_KEYBOARD_CONNECT
Definition: kbdmou.h:56
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
struct _PORT_DEVICE_EXTENSION * PPORT_DEVICE_EXTENSION
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
#define VOID
Definition: acefi.h:82
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1882
#define IRP_MN_SET_POWER
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
Definition: typedefs.h:119
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
int _cdecl swprintf(const WCHAR *,...)
DRIVER_DISPATCH(nfs41_FsdDispatch)
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
static VOID DestroyPortDriver(IN PDEVICE_OBJECT PortDO)
Definition: kbdclass.c:578
static BOOLEAN NTAPI ClassCallback(IN PDEVICE_OBJECT ClassDeviceObject, IN OUT PKEYBOARD_INPUT_DATA DataStart, IN PKEYBOARD_INPUT_DATA DataEnd, IN OUT PULONG ConsumedCount)
Definition: kbdclass.c:469
ULONG_PTR SIZE_T
Definition: typedefs.h:80
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
static DRIVER_CANCEL ClassCancelRoutine
Definition: kbdclass.c:26
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:746
struct _CLASS_DRIVER_EXTENSION * PCLASS_DRIVER_EXTENSION
unsigned short USHORT
Definition: pedump.c:61
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
static DRIVER_UNLOAD DriverUnload
Definition: kbdclass.c:17
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_CLEANUP
#define OUT
Definition: typedefs.h:40
#define ObReferenceObject
Definition: obfuncs.h:204
#define IOCTL_KEYBOARD_QUERY_ATTRIBUTES
Definition: ntddkbd.h:32
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31
return Iosb
Definition: create.c:4402
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:155
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
char * cleanup(char *str)
Definition: wpickclick.c:99
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
static NTSTATUS CreateClassDeviceObject(IN PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
Definition: kbdclass.c:314
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define STATUS_TOO_MANY_NAMES
Definition: ntstatus.h:441
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165
#define IOCTL_KEYBOARD_SET_INDICATORS
Definition: ntddkbd.h:47
PDEVICE_OBJECT DeviceObject
Definition: kbdclass.h:45
IoMarkIrpPending(Irp)
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PORT_DEVICE_STATE PnpState
Definition: kbdclass.h:46
#define WARN_(ch,...)
Definition: debug.h:157
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: kbdclass.c:1054
#define FILE_DEVICE_KEYBOARD
Definition: winioctl.h:117
base of all file and directory entries
Definition: entries.h:82
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
static DRIVER_DISPATCH ClassCreate
Definition: kbdclass.c:18
IN PUNICODE_STRING PortName
Definition: conport.c:35
static DRIVER_DISPATCH ClassDeviceControl
Definition: kbdclass.c:22
PDEVICE_OBJECT ClassDeviceObject
Definition: kbdmou.h:81
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68