ReactOS  0.4.14-dev-115-g4576127
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 
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 
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 
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 {
96  KIRQL OldIrql;
98 
99  TRACE_(CLASS_NAME, "IRP_MJ_READ\n");
100 
101  ASSERT(DeviceExtension->Common.IsClassDO);
102 
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 
133 
134  //DeviceExtension = (PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
135 
136  switch (IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode)
137  {
142  {
143  /* FIXME: We hope that all devices will return the same result.
144  * Ask only the first one */
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 */
161  PLIST_ENTRY Entry = Head->Flink;
163  while (Entry != Head)
164  {
166  NTSTATUS IntermediateStatus;
167 
169  IntermediateStatus = ForwardIrpAndWait(DevExt->DeviceObject, Irp);
170  if (!NT_SUCCESS(IntermediateStatus))
171  Status = IntermediateStatus;
172  Entry = Entry->Flink;
173  }
174  break;
175  }
176  default:
177  WARN_(CLASS_NAME, "IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n",
178  IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode);
179  ASSERT(FALSE);
180  break;
181  }
182 
183  Irp->IoStatus.Status = Status;
184  Irp->IoStatus.Information = 0;
186 
187  return Status;
188 }
189 
190 static NTSTATUS NTAPI
193  IN PIRP Irp)
194 {
196  PPORT_DEVICE_EXTENSION DeviceExtension;
197 
198  DeviceExtension = DeviceObject->DeviceExtension;
199  if (!DeviceExtension->Common.IsClassDO)
200  {
201  /* Forward some IRPs to lower device */
202  switch (IoGetCurrentIrpStackLocation(Irp)->MajorFunction)
203  {
204  case IRP_MJ_POWER:
207  return PoCallDriver(DeviceExtension->LowerDevice, Irp);
208  default:
209  {
210  ERR_(CLASS_NAME, "Port DO stub for major function 0x%lx\n",
211  IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
212  ASSERT(FALSE);
213  }
214  }
215  }
216  else
217  {
218  ERR_(CLASS_NAME, "Class DO stub for major function 0x%lx\n",
219  IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
220  ASSERT(FALSE);
221  }
222 
223  Irp->IoStatus.Status = Status;
225  return Status;
226 }
227 
228 static NTSTATUS
232 {
233  UNICODE_STRING ParametersRegistryKey;
236 
237  /* HACK: We don't support multiple devices with this disabled */
238  ULONG DefaultConnectMultiplePorts = 1;
239  ULONG DefaultDataQueueSize = 0x64;
240  PCWSTR DefaultDeviceBaseName = L"KeyboardClass";
241 
242  ParametersRegistryKey.Length = 0;
243  ParametersRegistryKey.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(UNICODE_NULL);
244  ParametersRegistryKey.Buffer = ExAllocatePoolWithTag(PagedPool, ParametersRegistryKey.MaximumLength, CLASS_TAG);
245  if (!ParametersRegistryKey.Buffer)
246  {
247  WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
248  return STATUS_NO_MEMORY;
249  }
250  RtlCopyUnicodeString(&ParametersRegistryKey, RegistryPath);
251  RtlAppendUnicodeToString(&ParametersRegistryKey, L"\\Parameters");
252  ParametersRegistryKey.Buffer[ParametersRegistryKey.Length / sizeof(WCHAR)] = UNICODE_NULL;
253 
255 
257  Parameters[0].Name = L"ConnectMultiplePorts";
258  Parameters[0].EntryContext = &DriverExtension->ConnectMultiplePorts;
259  Parameters[0].DefaultType = REG_DWORD;
260  Parameters[0].DefaultData = &DefaultConnectMultiplePorts;
261  Parameters[0].DefaultLength = sizeof(ULONG);
262 
264  Parameters[1].Name = L"KeyboardDataQueueSize";
265  Parameters[1].EntryContext = &DriverExtension->DataQueueSize;
266  Parameters[1].DefaultType = REG_DWORD;
267  Parameters[1].DefaultData = &DefaultDataQueueSize;
268  Parameters[1].DefaultLength = sizeof(ULONG);
269 
271  Parameters[2].Name = L"KeyboardDeviceBaseName";
272  Parameters[2].EntryContext = &DriverExtension->DeviceBaseName;
273  Parameters[2].DefaultType = REG_SZ;
274  Parameters[2].DefaultData = (PVOID)DefaultDeviceBaseName;
275  Parameters[2].DefaultLength = 0;
276 
279  ParametersRegistryKey.Buffer,
280  Parameters,
281  NULL,
282  NULL);
283 
284  if (NT_SUCCESS(Status))
285  {
286  /* Check values */
287  if (DriverExtension->ConnectMultiplePorts != 0
288  && DriverExtension->ConnectMultiplePorts != 1)
289  {
290  DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts;
291  }
292  if (DriverExtension->DataQueueSize == 0)
293  {
294  DriverExtension->DataQueueSize = DefaultDataQueueSize;
295  }
296  }
298  {
299  /* Registry path doesn't exist. Set defaults */
300  DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts;
301  DriverExtension->DataQueueSize = DefaultDataQueueSize;
302  if (RtlCreateUnicodeString(&DriverExtension->DeviceBaseName, DefaultDeviceBaseName))
304  else
306  }
307 
308  ExFreePoolWithTag(ParametersRegistryKey.Buffer, CLASS_TAG);
309  return Status;
310 }
311 
312 static NTSTATUS
315  OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
316 {
318  ULONG DeviceId = 0;
319  ULONG PrefixLength;
320  UNICODE_STRING DeviceNameU;
321  PWSTR DeviceIdW = NULL; /* Pointer into DeviceNameU.Buffer */
322  PDEVICE_OBJECT Fdo;
323  PCLASS_DEVICE_EXTENSION DeviceExtension;
325 
326  TRACE_(CLASS_NAME, "CreateClassDeviceObject(0x%p)\n", DriverObject);
327 
328  /* Create new device object */
330  DeviceNameU.Length = 0;
331  DeviceNameU.MaximumLength =
332  wcslen(L"\\Device\\") * sizeof(WCHAR) /* "\Device\" */
333  + DriverExtension->DeviceBaseName.Length /* "KeyboardClass" */
334  + 4 * sizeof(WCHAR) /* Id between 0 and 9999 */
335  + sizeof(UNICODE_NULL); /* Final NULL char */
336  DeviceNameU.Buffer = ExAllocatePoolWithTag(PagedPool, DeviceNameU.MaximumLength, CLASS_TAG);
337  if (!DeviceNameU.Buffer)
338  {
339  WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
340  return STATUS_NO_MEMORY;
341  }
342  Status = RtlAppendUnicodeToString(&DeviceNameU, L"\\Device\\");
343  if (!NT_SUCCESS(Status))
344  {
345  WARN_(CLASS_NAME, "RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
346  goto cleanup;
347  }
348  Status = RtlAppendUnicodeStringToString(&DeviceNameU, &DriverExtension->DeviceBaseName);
349  if (!NT_SUCCESS(Status))
350  {
351  WARN_(CLASS_NAME, "RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
352  goto cleanup;
353  }
354  PrefixLength = DeviceNameU.MaximumLength - 4 * sizeof(WCHAR) - sizeof(UNICODE_NULL);
355  DeviceIdW = &DeviceNameU.Buffer[PrefixLength / sizeof(WCHAR)];
356  while (DeviceId < 9999)
357  {
358  DeviceNameU.Length = (USHORT)(PrefixLength + swprintf(DeviceIdW, L"%lu", DeviceId) * sizeof(WCHAR));
360  DriverObject,
361  sizeof(CLASS_DEVICE_EXTENSION),
362  &DeviceNameU,
365  FALSE,
366  &Fdo);
367  if (NT_SUCCESS(Status))
368  goto cleanup;
370  {
371  WARN_(CLASS_NAME, "IoCreateDevice() failed with status 0x%08lx\n", Status);
372  goto cleanup;
373  }
374  DeviceId++;
375  }
376  WARN_(CLASS_NAME, "Too many devices starting with '\\Device\\%wZ'\n", &DriverExtension->DeviceBaseName);
378 cleanup:
379  if (!NT_SUCCESS(Status))
380  {
381  ExFreePoolWithTag(DeviceNameU.Buffer, CLASS_TAG);
382  return Status;
383  }
384 
385  DeviceExtension = (PCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension;
386  RtlZeroMemory(DeviceExtension, sizeof(CLASS_DEVICE_EXTENSION));
387  DeviceExtension->Common.IsClassDO = TRUE;
388  DeviceExtension->DriverExtension = DriverExtension;
389  InitializeListHead(&DeviceExtension->ListHead);
390  KeInitializeSpinLock(&DeviceExtension->ListSpinLock);
391  KeInitializeSpinLock(&DeviceExtension->SpinLock);
392  DeviceExtension->InputCount = 0;
393  DeviceExtension->PortData = ExAllocatePoolWithTag(NonPagedPool, DeviceExtension->DriverExtension->DataQueueSize * sizeof(KEYBOARD_INPUT_DATA), CLASS_TAG);
394  if (!DeviceExtension->PortData)
395  {
396  ExFreePoolWithTag(DeviceNameU.Buffer, CLASS_TAG);
397  return STATUS_NO_MEMORY;
398  }
399  DeviceExtension->DeviceName = DeviceNameU.Buffer;
400  Fdo->Flags |= DO_POWER_PAGABLE;
401  Fdo->Flags |= DO_BUFFERED_IO; /* FIXME: Why is it needed for 1st stage setup? */
402  Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
403 
404  /* Add entry entry to HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
407  DriverExtension->DeviceBaseName.Buffer,
408  DeviceExtension->DeviceName,
409  REG_SZ,
410  DriverExtension->RegistryPath.Buffer,
411  DriverExtension->RegistryPath.MaximumLength);
412 
413  if (ClassDO)
414  *ClassDO = Fdo;
415 
416  return STATUS_SUCCESS;
417 }
418 
419 static NTSTATUS
421  IN PDEVICE_OBJECT ClassDeviceObject,
422  IN PIRP Irp,
423  IN PKEYBOARD_INPUT_DATA DataStart,
424  IN SIZE_T NumberOfEntries)
425 {
427 
428  if (ClassDeviceObject->Flags & DO_BUFFERED_IO)
429  {
431  Irp->AssociatedIrp.SystemBuffer,
432  DataStart,
433  NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
434  }
435  else if (ClassDeviceObject->Flags & DO_DIRECT_IO)
436  {
437  PVOID DestAddress = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
438  if (DestAddress)
439  {
441  DestAddress,
442  DataStart,
443  NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
444  }
445  else
447  }
448  else
449  {
450  _SEH2_TRY
451  {
453  Irp->UserBuffer,
454  DataStart,
455  NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
456  }
458  {
460  }
461  _SEH2_END;
462  }
463 
464  return Status;
465 }
466 
467 static BOOLEAN NTAPI
469  IN PDEVICE_OBJECT ClassDeviceObject,
470  IN OUT PKEYBOARD_INPUT_DATA DataStart,
471  IN PKEYBOARD_INPUT_DATA DataEnd,
472  IN OUT PULONG ConsumedCount)
473 {
474  PCLASS_DEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
475  KIRQL OldIrql;
476  SIZE_T InputCount = DataEnd - DataStart;
477  SIZE_T ReadSize;
478 
479  TRACE_(CLASS_NAME, "ClassCallback()\n");
480 
481  ASSERT(ClassDeviceExtension->Common.IsClassDO);
482 
483  KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql);
484  if (InputCount > 0)
485  {
486  if (ClassDeviceExtension->InputCount + InputCount > ClassDeviceExtension->DriverExtension->DataQueueSize)
487  {
488  /*
489  * We're exceeding the buffer, and data will be thrown away...
490  * FIXME: What could we do, as we are at DISPATCH_LEVEL?
491  */
492  ReadSize = ClassDeviceExtension->DriverExtension->DataQueueSize - ClassDeviceExtension->InputCount;
493  }
494  else
495  ReadSize = InputCount;
496 
497  /*
498  * Move the input data from the port data queue to our class data
499  * queue.
500  */
502  &ClassDeviceExtension->PortData[ClassDeviceExtension->InputCount],
503  (PCHAR)DataStart,
504  sizeof(KEYBOARD_INPUT_DATA) * ReadSize);
505 
506  /* Move the counter up */
507  ClassDeviceExtension->InputCount += ReadSize;
508 
509  (*ConsumedCount) += (ULONG)ReadSize;
510 
511  /* Complete pending IRP (if any) */
512  if (ClassDeviceExtension->PendingIrp)
513  HandleReadIrp(ClassDeviceObject, ClassDeviceExtension->PendingIrp, FALSE);
514  }
515  KeReleaseSpinLock(&ClassDeviceExtension->SpinLock, OldIrql);
516 
517  TRACE_(CLASS_NAME, "Leaving ClassCallback()\n");
518  return TRUE;
519 }
520 
521 /* Send IOCTL_INTERNAL_*_CONNECT to port */
522 static NTSTATUS
524  IN PDEVICE_OBJECT PortDO,
525  IN PDEVICE_OBJECT ClassDO)
526 {
527  KEVENT Event;
528  PIRP Irp;
530  CONNECT_DATA ConnectData;
532 
533  TRACE_(CLASS_NAME, "Connecting PortDO %p to ClassDO %p\n", PortDO, ClassDO);
534 
536 
537  ConnectData.ClassDeviceObject = ClassDO;
538  ConnectData.ClassService = ClassCallback;
539 
542  PortDO,
543  &ConnectData, sizeof(CONNECT_DATA),
544  NULL, 0,
545  TRUE, &Event, &IoStatus);
546  if (!Irp)
548 
549  Status = IoCallDriver(PortDO, Irp);
550 
551  if (Status == STATUS_PENDING)
553  else
554  IoStatus.Status = Status;
555 
556  if (NT_SUCCESS(IoStatus.Status))
557  {
558  ObReferenceObject(PortDO);
560  &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListHead,
561  &((PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension)->ListEntry,
562  &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListSpinLock);
563  if (ClassDO->StackSize <= PortDO->StackSize)
564  {
565  /* Increase the stack size, in case we have to
566  * forward some IRPs to the port device object
567  */
568  ClassDO->StackSize = PortDO->StackSize + 1;
569  }
570  }
571 
572  return IoStatus.Status;
573 }
574 
575 /* Send IOCTL_INTERNAL_*_DISCONNECT to port + destroy the Port DO */
576 static VOID
578  IN PDEVICE_OBJECT PortDO)
579 {
580  PPORT_DEVICE_EXTENSION DeviceExtension;
581  PCLASS_DEVICE_EXTENSION ClassDeviceExtension;
583  KEVENT Event;
584  PIRP Irp;
586  KIRQL OldIrql;
588 
589  TRACE_(CLASS_NAME, "Destroying PortDO %p\n", PortDO);
590 
591  DeviceExtension = (PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension;
592  ClassDeviceExtension = DeviceExtension->ClassDO->DeviceExtension;
593  DriverExtension = IoGetDriverObjectExtension(PortDO->DriverObject, PortDO->DriverObject);
594 
595  /* Send IOCTL_INTERNAL_*_DISCONNECT */
599  PortDO,
600  NULL, 0,
601  NULL, 0,
602  TRUE, &Event, &IoStatus);
603  if (Irp)
604  {
605  Status = IoCallDriver(PortDO, Irp);
606  if (Status == STATUS_PENDING)
608  }
609 
610  /* Remove from ClassDeviceExtension->ListHead list */
611  KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql);
612  RemoveEntryList(&DeviceExtension->ListEntry);
613  KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql);
614 
615  /* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
618  DriverExtension->DeviceBaseName.Buffer,
619  ClassDeviceExtension->DeviceName);
620 
621  if (DeviceExtension->LowerDevice)
622  IoDetachDevice(DeviceExtension->LowerDevice);
623  ObDereferenceObject(PortDO);
624 
625  if (!DriverExtension->ConnectMultiplePorts && DeviceExtension->ClassDO)
626  {
627  ExFreePoolWithTag(ClassDeviceExtension->PortData, CLASS_TAG);
628  ExFreePoolWithTag((PVOID)ClassDeviceExtension->DeviceName, CLASS_TAG);
629  IoDeleteDevice(DeviceExtension->ClassDO);
630  }
631 
632  IoDeleteDevice(PortDO);
633 }
634 
635 static NTSTATUS NTAPI
639 {
641  PDEVICE_OBJECT Fdo = NULL;
642  PPORT_DEVICE_EXTENSION DeviceExtension = NULL;
644 
645  TRACE_(CLASS_NAME, "ClassAddDevice called. Pdo = 0x%p\n", Pdo);
646 
648 
649  if (Pdo == NULL)
650  /* We may get a NULL Pdo at the first call as we're a legacy driver. Ignore it */
651  return STATUS_SUCCESS;
652 
653  /* Create new device object */
655  DriverObject,
656  sizeof(PORT_DEVICE_EXTENSION),
657  NULL,
658  Pdo->DeviceType,
659  Pdo->Characteristics & FILE_DEVICE_SECURE_OPEN ? FILE_DEVICE_SECURE_OPEN : 0,
660  FALSE,
661  &Fdo);
662  if (!NT_SUCCESS(Status))
663  {
664  WARN_(CLASS_NAME, "IoCreateDevice() failed with status 0x%08lx\n", Status);
665  goto cleanup;
666  }
668 
669  DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension;
670  RtlZeroMemory(DeviceExtension, sizeof(PORT_DEVICE_EXTENSION));
671  DeviceExtension->Common.IsClassDO = FALSE;
672  DeviceExtension->DeviceObject = Fdo;
673  DeviceExtension->PnpState = dsStopped;
674  Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
675  if (!NT_SUCCESS(Status))
676  {
677  WARN_(CLASS_NAME, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
678  goto cleanup;
679  }
680  if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
681  Fdo->Flags |= DO_POWER_PAGABLE;
682  if (DeviceExtension->LowerDevice->Flags & DO_BUFFERED_IO)
683  Fdo->Flags |= DO_BUFFERED_IO;
684  if (DeviceExtension->LowerDevice->Flags & DO_DIRECT_IO)
685  Fdo->Flags |= DO_DIRECT_IO;
686 
687  if (DriverExtension->ConnectMultiplePorts)
688  DeviceExtension->ClassDO = DriverExtension->MainClassDeviceObject;
689  else
690  {
691  /* We need a new class device object for this Fdo */
693  DriverObject,
694  &DeviceExtension->ClassDO);
695  if (!NT_SUCCESS(Status))
696  {
697  WARN_(CLASS_NAME, "CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
698  goto cleanup;
699  }
700  }
701  Status = ConnectPortDriver(Fdo, DeviceExtension->ClassDO);
702  if (!NT_SUCCESS(Status))
703  {
704  WARN_(CLASS_NAME, "ConnectPortDriver() failed with status 0x%08lx\n", Status);
705  goto cleanup;
706  }
707  Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
708 
709  /* Register interface ; ignore the error (if any) as having
710  * a registered interface is not so important... */
712  Pdo,
713  &GUID_DEVINTERFACE_KEYBOARD,
714  NULL,
715  &DeviceExtension->InterfaceName);
716  if (!NT_SUCCESS(Status))
717  DeviceExtension->InterfaceName.Length = 0;
718 
719  return STATUS_SUCCESS;
720 
721 cleanup:
722  if (Fdo)
723  DestroyPortDriver(Fdo);
724  return Status;
725 }
726 
727 static VOID NTAPI
730  IN PIRP Irp)
731 {
732  PCLASS_DEVICE_EXTENSION ClassDeviceExtension = DeviceObject->DeviceExtension;
733  KIRQL OldIrql;
734  BOOLEAN wasQueued = FALSE;
735 
736  TRACE_(CLASS_NAME, "ClassCancelRoutine(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
737 
738  ASSERT(ClassDeviceExtension->Common.IsClassDO);
739 
740  IoReleaseCancelSpinLock(Irp->CancelIrql);
741 
742  KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql);
743 
744  if (ClassDeviceExtension->PendingIrp == Irp)
745  {
746  ClassDeviceExtension->PendingIrp = NULL;
747  wasQueued = TRUE;
748  }
749  KeReleaseSpinLock(&ClassDeviceExtension->SpinLock, OldIrql);
750 
751  if (wasQueued)
752  {
753  Irp->IoStatus.Status = STATUS_CANCELLED;
754  Irp->IoStatus.Information = 0;
756  }
757  else
758  {
759  DPRINT1("Cancelled IRP is not pending. Race condition?\n");
760  }
761 }
762 
763 static NTSTATUS
766  IN PIRP Irp,
767  BOOLEAN IsInStartIo)
768 {
771  KIRQL OldIrql;
772 
773  TRACE_(CLASS_NAME, "HandleReadIrp(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
774 
775  ASSERT(DeviceExtension->Common.IsClassDO);
776 
777  if (DeviceExtension->InputCount > 0)
778  {
779  SIZE_T NumberOfEntries;
780 
781  NumberOfEntries = MIN(
782  DeviceExtension->InputCount,
784 
786  DeviceObject,
787  Irp,
788  DeviceExtension->PortData,
789  NumberOfEntries);
790 
791  if (NT_SUCCESS(Status))
792  {
793  if (DeviceExtension->InputCount > NumberOfEntries)
794  {
796  &DeviceExtension->PortData[0],
797  &DeviceExtension->PortData[NumberOfEntries],
798  (DeviceExtension->InputCount - NumberOfEntries) * sizeof(KEYBOARD_INPUT_DATA));
799  }
800 
801  DeviceExtension->InputCount -= NumberOfEntries;
802 
803  Irp->IoStatus.Information = NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA);
804  }
805 
806  /* Go to next packet and complete this request */
807  Irp->IoStatus.Status = Status;
808 
811  DeviceExtension->PendingIrp = NULL;
812  }
813  else
814  {
816  if (Irp->Cancel)
817  {
818  DeviceExtension->PendingIrp = NULL;
820  }
821  else
822  {
824  DeviceExtension->PendingIrp = Irp;
827  }
829  }
830  return Status;
831 }
832 
833 static NTSTATUS NTAPI
836  IN PIRP Irp)
837 {
843 
844  switch (IrpSp->MinorFunction)
845  {
846  case IRP_MN_START_DEVICE:
848  if (NT_SUCCESS(Status))
849  {
851  &DeviceExtension->InterfaceName,
853  NULL,
854  NULL);
855 
856  Status = ZwOpenFile(&DeviceExtension->FileHandle,
859  &Iosb,
860  0,
861  0);
862  if (!NT_SUCCESS(Status))
863  DeviceExtension->FileHandle = NULL;
864  }
865  else
866  DeviceExtension->FileHandle = NULL;
867  Irp->IoStatus.Status = Status;
869  return Status;
870 
871  case IRP_MN_STOP_DEVICE:
872  if (DeviceExtension->FileHandle)
873  {
874  ZwClose(DeviceExtension->FileHandle);
875  DeviceExtension->FileHandle = NULL;
876  }
878  break;
879 
881  if (DeviceExtension->FileHandle)
882  {
883  ZwClose(DeviceExtension->FileHandle);
884  DeviceExtension->FileHandle = NULL;
885  }
887  Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
889  return Status;
890 
891  default:
892  Status = Irp->IoStatus.Status;
893  break;
894  }
895 
896  Irp->IoStatus.Status = Status;
898  {
900  return IoCallDriver(DeviceExtension->LowerDevice, Irp);
901  }
902  else
903  {
905  return Status;
906  }
907 }
908 
909 static VOID NTAPI
912  IN PIRP Irp)
913 {
915  KIRQL OldIrql;
916 
917  TRACE_(CLASS_NAME, "ClassStartIo(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
918 
919  ASSERT(DeviceExtension->Common.IsClassDO);
920 
921  KeAcquireSpinLock(&DeviceExtension->SpinLock, &OldIrql);
923  KeReleaseSpinLock(&DeviceExtension->SpinLock, OldIrql);
924 }
925 
926 static VOID NTAPI
929  IN PVOID Context, /* PCLASS_DRIVER_EXTENSION */
930  IN ULONG Count)
931 {
932  UNICODE_STRING DeviceMapKeyU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
934  UNICODE_STRING PortBaseName = { 0, 0, NULL };
935  PKEY_VALUE_BASIC_INFORMATION KeyValueInformation = NULL;
937  HANDLE hDeviceMapKey = (HANDLE)-1;
938  HANDLE hPortKey = (HANDLE)-1;
939  ULONG Index = 0;
942 
943  TRACE_(CLASS_NAME, "SearchForLegacyDrivers(%p %p %lu)\n",
945 
946  if (Count != 1)
947  return;
949 
950  /* Create port base name, by replacing Class by Port at the end of the class base name */
953  &DriverExtension->DeviceBaseName,
954  &PortBaseName);
955  if (!NT_SUCCESS(Status))
956  {
957  WARN_(CLASS_NAME, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status);
958  goto cleanup;
959  }
960  PortBaseName.Length -= (sizeof(L"Class") - sizeof(UNICODE_NULL));
961  RtlAppendUnicodeToString(&PortBaseName, L"Port");
962 
963  /* Allocate memory */
965  KeyValueInformation = ExAllocatePoolWithTag(PagedPool, Size, CLASS_TAG);
966  if (!KeyValueInformation)
967  {
968  WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
970  goto cleanup;
971  }
972 
973  /* Open HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
975  Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
977  {
978  INFO_(CLASS_NAME, "HKLM\\HARDWARE\\DEVICEMAP is non-existent\n");
980  goto cleanup;
981  }
982  else if (!NT_SUCCESS(Status))
983  {
984  WARN_(CLASS_NAME, "ZwOpenKey() failed with status 0x%08lx\n", Status);
985  goto cleanup;
986  }
987 
988  /* Open sub key */
990  Status = ZwOpenKey(&hPortKey, KEY_QUERY_VALUE, &ObjectAttributes);
992  {
993  INFO_(CLASS_NAME, "HKLM\\HARDWARE\\DEVICEMAP\\%wZ is non-existent\n", &PortBaseName);
995  goto cleanup;
996  }
997  else if (!NT_SUCCESS(Status))
998  {
999  WARN_(CLASS_NAME, "ZwOpenKey() failed with status 0x%08lx\n", Status);
1000  goto cleanup;
1001  }
1002 
1003  /* Read each value name */
1004  while (ZwEnumerateValueKey(hPortKey, Index++, KeyValueBasicInformation, KeyValueInformation, Size, &ResultLength) == STATUS_SUCCESS)
1005  {
1007  PDEVICE_OBJECT PortDeviceObject = NULL;
1009 
1010  PortName.Length = PortName.MaximumLength = (USHORT)KeyValueInformation->NameLength;
1011  PortName.Buffer = KeyValueInformation->Name;
1012 
1013  /* Open the device object pointer */
1015  if (!NT_SUCCESS(Status))
1016  {
1017  WARN_(CLASS_NAME, "IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", &PortName, Status);
1018  continue;
1019  }
1020  INFO_(CLASS_NAME, "Legacy driver found\n");
1021 
1022  Status = ClassAddDevice(DriverObject, PortDeviceObject);
1023  if (!NT_SUCCESS(Status))
1024  {
1025  /* FIXME: Log the error */
1026  WARN_(CLASS_NAME, "ClassAddDevice() failed with status 0x%08lx\n", Status);
1027  }
1028 
1030  }
1031 
1032 cleanup:
1033  if (KeyValueInformation != NULL)
1034  ExFreePoolWithTag(KeyValueInformation, CLASS_TAG);
1035  if (hDeviceMapKey != (HANDLE)-1)
1036  ZwClose(hDeviceMapKey);
1037  if (hPortKey != (HANDLE)-1)
1038  ZwClose(hPortKey);
1039 }
1040 
1041 /*
1042  * Standard DriverEntry method.
1043  */
1048 {
1050  ULONG i;
1051  NTSTATUS Status;
1052 
1054  DriverObject,
1055  DriverObject,
1056  sizeof(CLASS_DRIVER_EXTENSION),
1057  (PVOID*)&DriverExtension);
1058  if (!NT_SUCCESS(Status))
1059  {
1060  WARN_(CLASS_NAME, "IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status);
1061  return Status;
1062  }
1064 
1067  RegistryPath,
1068  &DriverExtension->RegistryPath);
1069  if (!NT_SUCCESS(Status))
1070  {
1071  WARN_(CLASS_NAME, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status);
1072  return Status;
1073  }
1074 
1076  if (!NT_SUCCESS(Status))
1077  {
1078  WARN_(CLASS_NAME, "ReadRegistryEntries() failed with status 0x%08lx\n", Status);
1079  return Status;
1080  }
1081 
1082  if (DriverExtension->ConnectMultiplePorts == 1)
1083  {
1085  DriverObject,
1086  &DriverExtension->MainClassDeviceObject);
1087  if (!NT_SUCCESS(Status))
1088  {
1089  WARN_(CLASS_NAME, "CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
1090  return Status;
1091  }
1092  }
1093 
1096 
1097  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1099 
1108 
1109  /* We will detect the legacy devices later */
1111  DriverObject,
1113  DriverExtension);
1114 
1115  return STATUS_SUCCESS;
1116 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#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:55
#define IN
Definition: typedefs.h:38
#define IOCTL_KEYBOARD_QUERY_TYPEMATIC
Definition: ntddkbd.h:41
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
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
_In_ PDEVICE_OBJECT Pdo
Definition: classpnp.h:301
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
#define INFO_(ch,...)
Definition: debug.h:159
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1764
USHORT MaximumLength
Definition: env_spec_w32.h:370
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
NTSTATUS NTAPI PoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: power.c:485
static DRIVER_DISPATCH ClassRead
Definition: kbdclass.c:21
_In_ PIRP Irp
Definition: csq.h:116
static DRIVER_DISPATCH ClassCleanup
Definition: kbdclass.c:20
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
#define IO_KEYBOARD_INCREMENT
Definition: iotypes.h:569
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define ERR_(ch,...)
Definition: debug.h:156
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
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
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
static DRIVER_ADD_DEVICE ClassAddDevice
Definition: kbdclass.c:24
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
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:263
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
_SEH2_TRY
Definition: create.c:4250
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1735
static NTSTATUS NTAPI ClassPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: kbdclass.c:834
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
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
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
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2174
static VOID NTAPI SearchForLegacyDrivers(IN PDRIVER_OBJECT DriverObject, IN PVOID Context, IN ULONG Count)
Definition: kbdclass.c:927
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static NTSTATUS ReadRegistryEntries(IN PUNICODE_STRING RegistryPath, IN PCLASS_DRIVER_EXTENSION DriverExtension)
Definition: kbdclass.c:229
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
void * PVOID
Definition: retypes.h:9
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
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
#define TRACE_(x)
Definition: compat.h:66
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#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:523
#define IRP_MN_STOP_DEVICE
__wchar_t WCHAR
Definition: xmlstorage.h:180
return Iosb
Definition: create.c:4426
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
static NTSTATUS FillEntries(IN PDEVICE_OBJECT ClassDeviceObject, IN PIRP Irp, IN PKEYBOARD_INPUT_DATA DataStart, IN SIZE_T NumberOfEntries)
Definition: kbdclass.c:420
NTSTATUS DuplicateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString)
Definition: misc.c:72
#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:764
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define MAX_PATH
Definition: compat.h:26
#define swprintf(buf, format,...)
Definition: sprintf.c:56
static DRIVER_STARTIO ClassStartIo
Definition: kbdclass.c:25
#define IRP_MN_START_DEVICE
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
static const UCHAR Index[8]
Definition: usbohci.c:18
PVOID HANDLE
Definition: typedefs.h:71
DRIVER_DISPATCH ForwardIrpAndWait
Definition: i8042prt.h:343
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
* PFILE_OBJECT
Definition: iotypes.h:1955
PVOID ClassService
Definition: kbdmou.h:82
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define IOCTL_INTERNAL_KEYBOARD_CONNECT
Definition: kbdmou.h:56
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
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
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
struct _PORT_DEVICE_EXTENSION * PPORT_DEVICE_EXTENSION
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
static const WCHAR L[]
Definition: oid.c:1250
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
#define VOID
Definition: acefi.h:82
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
Definition: typedefs.h:117
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
DRIVER_DISPATCH(nfs41_FsdDispatch)
static DRIVER_DISPATCH IrpStub
Definition: kbdclass.c:23
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
Status
Definition: gdiplustypes.h:24
static VOID DestroyPortDriver(IN PDEVICE_OBJECT PortDO)
Definition: kbdclass.c:577
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:468
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
ULONG_PTR SIZE_T
Definition: typedefs.h:78
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
static DRIVER_CANCEL ClassCancelRoutine
Definition: kbdclass.c:26
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2112
_SEH2_END
Definition: create.c:4424
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:626
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
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
static DRIVER_UNLOAD DriverUnload
Definition: kbdclass.c:17
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
unsigned int * PULONG
Definition: retypes.h:1
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
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:39
#define ObReferenceObject
Definition: obfuncs.h:204
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
#define IOCTL_KEYBOARD_QUERY_ATTRIBUTES
Definition: ntddkbd.h:32
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
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:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
char * cleanup(char *str)
Definition: wpickclick.c:99
PDRIVER_STARTIO DriverStartIo
Definition: iotypes.h:2179
static NTSTATUS CreateClassDeviceObject(IN PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
Definition: kbdclass.c:313
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define STATUS_TOO_MANY_NAMES
Definition: ntstatus.h:427
#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
return STATUS_SUCCESS
Definition: btrfs.c:2966
IoMarkIrpPending(Irp)
#define REG_DWORD
Definition: sdbapi.c:596
PORT_DEVICE_STATE PnpState
Definition: kbdclass.h:46
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define WARN_(ch,...)
Definition: debug.h:157
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: kbdclass.c:1045
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define FILE_DEVICE_KEYBOARD
Definition: winioctl.h:116
base of all file and directory entries
Definition: entries.h:82
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#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