ReactOS 0.4.17-dev-1321-g5c122a9
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 <kbdmou.h>
14#include <hidclass.h>
15#include <poclass.h>
16#include <pseh/pseh2.h>
17#include <debug.h>
18
19static DRIVER_UNLOAD DriverUnload;
26static DRIVER_ADD_DEVICE ClassAddDevice;
27static DRIVER_STARTIO ClassStartIo;
28static DRIVER_CANCEL ClassCancelRoutine;
29static NTSTATUS
34
35static VOID NTAPI
37{
38 // nothing to do here yet
39}
40
41static NTSTATUS NTAPI
44 IN PIRP Irp)
45{
46 TRACE_(CLASS_NAME, "IRP_MJ_CREATE\n");
47
48 if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
50
51 /* FIXME: open all associated Port devices */
52 Irp->IoStatus.Status = STATUS_SUCCESS;
53 Irp->IoStatus.Information = 0;
55 return STATUS_SUCCESS;
56}
57
58static NTSTATUS NTAPI
61 IN PIRP Irp)
62{
63 TRACE_(CLASS_NAME, "IRP_MJ_CLOSE\n");
64
65 if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
67
68 /* FIXME: close all associated Port devices */
69 Irp->IoStatus.Status = STATUS_SUCCESS;
70 Irp->IoStatus.Information = 0;
72 return STATUS_SUCCESS;
73}
74
75static NTSTATUS NTAPI
78 IN PIRP Irp)
79{
80 TRACE_(CLASS_NAME, "IRP_MJ_CLEANUP\n");
81
82 if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
84
85 /* FIXME: cleanup all associated Port devices */
86 Irp->IoStatus.Status = STATUS_SUCCESS;
87 Irp->IoStatus.Information = 0;
89 return STATUS_SUCCESS;
90}
91
92static NTSTATUS NTAPI
95 IN PIRP Irp)
96{
97 PCOMMON_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
99
100 TRACE_(CLASS_NAME, "IRP_MJ_READ\n");
101
103 {
104 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
105 Irp->IoStatus.Information = 0;
107
109 }
110
111 if (DeviceExtension->IsClassDO)
112 {
113 ReadData = ((PCLASS_DEVICE_EXTENSION)DeviceExtension)->ReadData;
114 }
115 else
116 {
118 PCLASS_DEVICE_EXTENSION Class = (PCLASS_DEVICE_EXTENSION)Port->ClassDO->DeviceExtension;
119 ReadData = Class->ReadData;
120 }
121
123}
124
125static NTSTATUS NTAPI
128 IN PIRP Irp)
129{
131
132 TRACE_(CLASS_NAME, "IRP_MJ_DEVICE_CONTROL\n");
133
135 {
140 {
141 if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
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 */
150 DeviceObject = DevExt->DeviceObject;
151 }
152 else
154 }
155 if (DeviceObject)
156 {
160 }
161 break;
162 }
164 case IOCTL_KEYBOARD_SET_TYPEMATIC: /* not in MSDN, would seem logical */
165 {
166 if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
167 {
168 /* Send it to all associated Port devices */
169 PLIST_ENTRY Head = &((PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ListHead;
170 PLIST_ENTRY Entry = Head->Flink;
172 while (Entry != Head)
173 {
175
177
179 {
180 if (!NT_SUCCESS(Irp->IoStatus.Status))
181 {
182 Status = Irp->IoStatus.Status;
183 }
184 }
185 else
186 {
188 }
189
190 Entry = Entry->Flink;
191 }
192 }
193 else
194 {
195 PPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
197 return IoCallDriver(DeviceExtension->LowerDevice, Irp);
198 }
199 break;
200 }
201 /* Every IOCTL HID, except IOCTL_HID_GET_INPUT_REPORT/IOCTL_HID_SET_OUTPUT_REPORT */
220 /* IOCTL used by Power Manager */
223 {
224 PPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
225 if (!DeviceExtension->Common.IsClassDO)
226 {
228 return IoCallDriver(DeviceExtension->LowerDevice, Irp);
229 }
230 break;
231 }
232 default:
233 WARN_(CLASS_NAME, "IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n",
235 ASSERT(FALSE);
236 break;
237 }
238
239 Irp->IoStatus.Status = Status;
240 Irp->IoStatus.Information = 0;
242
243 return Status;
244}
245
246static NTSTATUS NTAPI
249 IN PIRP Irp)
250{
252 PPORT_DEVICE_EXTENSION DeviceExtension;
253
254 DeviceExtension = DeviceObject->DeviceExtension;
255 if (!DeviceExtension->Common.IsClassDO)
256 {
257 /* Forward port DO IRPs to lower device */
260 return PoCallDriver(DeviceExtension->LowerDevice, Irp);
261 }
262
264 {
265 case IRP_MN_SET_POWER:
267 Irp->IoStatus.Status = STATUS_SUCCESS;
268 break;
269 }
270 Status = Irp->IoStatus.Status;
273 return Status;
274}
275
276static NTSTATUS
280{
281 UNICODE_STRING ParametersRegistryKey;
284
285 ULONG DefaultConnectMultiplePorts = 1;
286 ULONG DefaultDataQueueSize = 0x64;
287 PCWSTR DefaultDeviceBaseName = L"KeyboardClass";
288
289 ParametersRegistryKey.Length = 0;
290 ParametersRegistryKey.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(UNICODE_NULL);
291 ParametersRegistryKey.Buffer = ExAllocatePoolWithTag(PagedPool, ParametersRegistryKey.MaximumLength, CLASS_TAG);
292 if (!ParametersRegistryKey.Buffer)
293 {
294 WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
295 return STATUS_NO_MEMORY;
296 }
297 RtlCopyUnicodeString(&ParametersRegistryKey, RegistryPath);
298 RtlAppendUnicodeToString(&ParametersRegistryKey, L"\\Parameters");
299 ParametersRegistryKey.Buffer[ParametersRegistryKey.Length / sizeof(WCHAR)] = UNICODE_NULL;
300
302
304 Parameters[0].Name = L"ConnectMultiplePorts";
305 Parameters[0].EntryContext = &DriverExtension->ConnectMultiplePorts;
306 Parameters[0].DefaultType = REG_DWORD;
307 Parameters[0].DefaultData = &DefaultConnectMultiplePorts;
308 Parameters[0].DefaultLength = sizeof(ULONG);
309
311 Parameters[1].Name = L"KeyboardDataQueueSize";
312 Parameters[1].EntryContext = &DriverExtension->DataQueueSize;
313 Parameters[1].DefaultType = REG_DWORD;
314 Parameters[1].DefaultData = &DefaultDataQueueSize;
315 Parameters[1].DefaultLength = sizeof(ULONG);
316
318 Parameters[2].Name = L"KeyboardDeviceBaseName";
319 Parameters[2].EntryContext = &DriverExtension->DeviceBaseName;
320 Parameters[2].DefaultType = REG_SZ;
321 Parameters[2].DefaultData = (PVOID)DefaultDeviceBaseName;
322 Parameters[2].DefaultLength = 0;
323
326 ParametersRegistryKey.Buffer,
328 NULL,
329 NULL);
330
331 if (NT_SUCCESS(Status))
332 {
333 /* Check values */
334 if (DriverExtension->ConnectMultiplePorts != 0
335 && DriverExtension->ConnectMultiplePorts != 1)
336 {
337 DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts;
338 }
339 if (DriverExtension->DataQueueSize == 0)
340 {
341 DriverExtension->DataQueueSize = DefaultDataQueueSize;
342 }
343 }
345 {
346 /* Registry path doesn't exist. Set defaults */
347 DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts;
348 DriverExtension->DataQueueSize = DefaultDataQueueSize;
349 if (RtlCreateUnicodeString(&DriverExtension->DeviceBaseName, DefaultDeviceBaseName))
351 else
353 }
354
355 ExFreePoolWithTag(ParametersRegistryKey.Buffer, CLASS_TAG);
356 return Status;
357}
358
359static NTSTATUS
362 OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
363{
365 ULONG DeviceId = 0;
366 ULONG PrefixLength;
367 UNICODE_STRING DeviceNameU;
368 PWSTR DeviceIdW = NULL; /* Pointer into DeviceNameU.Buffer */
370 PCLASS_DEVICE_EXTENSION DeviceExtension;
372
373 TRACE_(CLASS_NAME, "CreateClassDeviceObject(0x%p)\n", DriverObject);
374
375 /* Create new device object */
377 DeviceNameU.Length = 0;
378 DeviceNameU.MaximumLength =
379 (USHORT)wcslen(L"\\Device\\") * sizeof(WCHAR) /* "\Device\" */
380 + DriverExtension->DeviceBaseName.Length /* "KeyboardClass" */
381 + 4 * sizeof(WCHAR) /* Id between 0 and 9999 */
382 + sizeof(UNICODE_NULL); /* Final NULL char */
383 DeviceNameU.Buffer = ExAllocatePoolWithTag(PagedPool, DeviceNameU.MaximumLength, CLASS_TAG);
384 if (!DeviceNameU.Buffer)
385 {
386 WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
387 return STATUS_NO_MEMORY;
388 }
389 Status = RtlAppendUnicodeToString(&DeviceNameU, L"\\Device\\");
390 if (!NT_SUCCESS(Status))
391 {
392 WARN_(CLASS_NAME, "RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
393 goto cleanup;
394 }
395 Status = RtlAppendUnicodeStringToString(&DeviceNameU, &DriverExtension->DeviceBaseName);
396 if (!NT_SUCCESS(Status))
397 {
398 WARN_(CLASS_NAME, "RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
399 goto cleanup;
400 }
401 PrefixLength = DeviceNameU.MaximumLength - 4 * sizeof(WCHAR) - sizeof(UNICODE_NULL);
402 DeviceIdW = &DeviceNameU.Buffer[PrefixLength / sizeof(WCHAR)];
403 while (DeviceId < 9999)
404 {
405 DeviceNameU.Length = (USHORT)(PrefixLength + _swprintf(DeviceIdW, L"%lu", DeviceId) * sizeof(WCHAR));
409 &DeviceNameU,
412 FALSE,
413 &Fdo);
414 if (NT_SUCCESS(Status))
415 goto cleanup;
417 {
418 WARN_(CLASS_NAME, "IoCreateDevice() failed with status 0x%08lx\n", Status);
419 goto cleanup;
420 }
421 DeviceId++;
422 }
423 WARN_(CLASS_NAME, "Too many devices starting with '\\Device\\%wZ'\n", &DriverExtension->DeviceBaseName);
425cleanup:
426 if (!NT_SUCCESS(Status))
427 {
428 ExFreePoolWithTag(DeviceNameU.Buffer, CLASS_TAG);
429 return Status;
430 }
431
432 DeviceExtension = (PCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension;
433 RtlZeroMemory(DeviceExtension, sizeof(CLASS_DEVICE_EXTENSION));
434 DeviceExtension->Common.IsClassDO = TRUE;
435 DeviceExtension->DriverExtension = DriverExtension;
436 InitializeListHead(&DeviceExtension->ListHead);
437 KeInitializeSpinLock(&DeviceExtension->ListSpinLock);
438 DeviceExtension->ReadData = ExAllocatePoolZero(NonPagedPool, sizeof(READ_DATA), CLASS_TAG);
439 if (!DeviceExtension->ReadData)
440 {
441 ExFreePoolWithTag(DeviceNameU.Buffer, CLASS_TAG);
442 return STATUS_NO_MEMORY;
443 }
444 KeInitializeSpinLock(&DeviceExtension->ReadData->SpinLock);
445 DeviceExtension->ReadData->PortData = ExAllocatePoolWithTag(NonPagedPool, DeviceExtension->DriverExtension->DataQueueSize * sizeof(KEYBOARD_INPUT_DATA), CLASS_TAG);
446 if (!DeviceExtension->ReadData->PortData)
447 {
448 ExFreePoolWithTag(DeviceNameU.Buffer, CLASS_TAG);
449 ExFreePoolWithTag(DeviceExtension->ReadData, CLASS_TAG);
450 return STATUS_NO_MEMORY;
451 }
452 DeviceExtension->DeviceName = DeviceNameU.Buffer;
453 Fdo->Flags |= DO_POWER_PAGABLE;
454 Fdo->Flags |= DO_BUFFERED_IO; /* FIXME: Why is it needed for 1st stage setup? */
455 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
456
457 /* Add entry entry to HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
460 DriverExtension->DeviceBaseName.Buffer,
461 DeviceExtension->DeviceName,
462 REG_SZ,
463 DriverExtension->RegistryPath.Buffer,
464 DriverExtension->RegistryPath.MaximumLength);
465
466 if (ClassDO)
467 *ClassDO = Fdo;
468
469 return STATUS_SUCCESS;
470}
471
472static NTSTATUS
474 IN PDEVICE_OBJECT ClassDeviceObject,
477 IN SIZE_T NumberOfEntries)
478{
480
481 if (!Destination)
482 return STATUS_UNSUCCESSFUL;
483
484 if (ClassDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO))
485 {
488 Source,
489 NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
490 }
491 else
492 {
494 {
497 Source,
498 NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
499 }
501 {
503 }
504 _SEH2_END;
505 }
506
507 return Status;
508}
509
510static BOOLEAN NTAPI
512 IN PDEVICE_OBJECT ClassDeviceObject,
513 IN OUT PKEYBOARD_INPUT_DATA DataStart,
514 IN PKEYBOARD_INPUT_DATA DataEnd,
515 IN OUT PULONG ConsumedCount)
516{
517 PCLASS_DEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
519 SIZE_T InputCount = DataEnd - DataStart;
520 SIZE_T ReadSize;
521
522 TRACE_(CLASS_NAME, "ClassCallback()\n");
523
524 ASSERT(ClassDeviceExtension->Common.IsClassDO);
525
526 if (InputCount > 0)
527 {
528 KeAcquireSpinLock(&ClassDeviceExtension->ReadData->SpinLock, &OldIrql);
529 if (ClassDeviceExtension->ReadData->InputCount + InputCount > ClassDeviceExtension->DriverExtension->DataQueueSize)
530 {
531 /*
532 * We're exceeding the buffer, and data will be thrown away...
533 * FIXME: What could we do, as we are at DISPATCH_LEVEL?
534 */
535 ReadSize = ClassDeviceExtension->DriverExtension->DataQueueSize - ClassDeviceExtension->ReadData->InputCount;
536 }
537 else
538 ReadSize = InputCount;
539
540 /*
541 * Move the input data from the port data queue to our class data
542 * queue.
543 */
545 &ClassDeviceExtension->ReadData->PortData[ClassDeviceExtension->ReadData->InputCount],
546 (PCHAR)DataStart,
547 sizeof(KEYBOARD_INPUT_DATA) * ReadSize);
548
549 /* Move the counter up */
550 ClassDeviceExtension->ReadData->InputCount += ReadSize;
551
552 (*ConsumedCount) += (ULONG)ReadSize;
553
554 KeReleaseSpinLock(&ClassDeviceExtension->ReadData->SpinLock, OldIrql);
555
556 /* Complete pending IRP (if any) */
557 HandleReadIrp(ClassDeviceObject, ClassDeviceExtension->ReadData, NULL);
558 }
559
560 TRACE_(CLASS_NAME, "Leaving ClassCallback()\n");
561 return TRUE;
562}
563
564/* Send IOCTL_INTERNAL_*_CONNECT to port */
565static NTSTATUS
567 IN PDEVICE_OBJECT PortDO,
568 IN PDEVICE_OBJECT ClassDO)
569{
571 PIRP Irp;
573 CONNECT_DATA ConnectData;
575
576 TRACE_(CLASS_NAME, "Connecting PortDO %p to ClassDO %p\n", PortDO, ClassDO);
577
579
580 ConnectData.ClassDeviceObject = ClassDO;
581 ConnectData.ClassService = ClassCallback;
582
585 PortDO,
586 &ConnectData, sizeof(CONNECT_DATA),
587 NULL, 0,
588 TRUE, &Event, &IoStatus);
589 if (!Irp)
591
592 Status = IoCallDriver(PortDO, Irp);
593
594 if (Status == STATUS_PENDING)
596 else
597 IoStatus.Status = Status;
598
599 if (NT_SUCCESS(IoStatus.Status))
600 {
601 ObReferenceObject(PortDO);
603 &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListHead,
604 &((PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension)->ListEntry,
605 &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListSpinLock);
606 if (ClassDO->StackSize <= PortDO->StackSize)
607 {
608 /* Increase the stack size, in case we have to
609 * forward some IRPs to the port device object
610 */
611 ClassDO->StackSize = PortDO->StackSize + 1;
612 }
613 }
614
615 return IoStatus.Status;
616}
617
618/* Send IOCTL_INTERNAL_*_DISCONNECT to port + destroy the Port DO */
619static VOID
621 IN PDEVICE_OBJECT PortDO)
622{
623 PPORT_DEVICE_EXTENSION DeviceExtension;
624 PCLASS_DEVICE_EXTENSION ClassDeviceExtension;
627 PIRP Irp;
631
632 TRACE_(CLASS_NAME, "Destroying PortDO %p\n", PortDO);
633
634 DeviceExtension = (PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension;
635 ClassDeviceExtension = DeviceExtension->ClassDO->DeviceExtension;
636 DriverExtension = IoGetDriverObjectExtension(PortDO->DriverObject, PortDO->DriverObject);
637
638 /* Send IOCTL_INTERNAL_*_DISCONNECT */
642 PortDO,
643 NULL, 0,
644 NULL, 0,
645 TRUE, &Event, &IoStatus);
646 if (Irp)
647 {
648 Status = IoCallDriver(PortDO, Irp);
649 if (Status == STATUS_PENDING)
651 }
652
653 /* Remove from ClassDeviceExtension->ListHead list */
654 KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql);
655 RemoveEntryList(&DeviceExtension->ListEntry);
656 KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql);
657
658 /* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
661 DriverExtension->DeviceBaseName.Buffer,
662 ClassDeviceExtension->DeviceName);
663
664 if (DeviceExtension->LowerDevice)
665 IoDetachDevice(DeviceExtension->LowerDevice);
666 ObDereferenceObject(PortDO);
667
668 if (!DriverExtension->ConnectMultiplePorts && DeviceExtension->ClassDO)
669 {
670 ExFreePoolWithTag(ClassDeviceExtension->ReadData->PortData, CLASS_TAG);
671 ExFreePoolWithTag(ClassDeviceExtension->ReadData, CLASS_TAG);
672 ExFreePoolWithTag((PVOID)ClassDeviceExtension->DeviceName, CLASS_TAG);
673 IoDeleteDevice(DeviceExtension->ClassDO);
674 }
675
676 IoDeleteDevice(PortDO);
677}
678
679static NTSTATUS NTAPI
683{
686 PPORT_DEVICE_EXTENSION DeviceExtension = NULL;
688
689 TRACE_(CLASS_NAME, "ClassAddDevice called. Pdo = 0x%p\n", Pdo);
690
692
693 if (Pdo == NULL)
694 /* We may get a NULL Pdo at the first call as we're a legacy driver. Ignore it */
695 return STATUS_SUCCESS;
696
697 /* Create new device object */
700 sizeof(PORT_DEVICE_EXTENSION),
701 NULL,
702 Pdo->DeviceType,
703 Pdo->Characteristics & FILE_DEVICE_SECURE_OPEN ? FILE_DEVICE_SECURE_OPEN : 0,
704 FALSE,
705 &Fdo);
706 if (!NT_SUCCESS(Status))
707 {
708 WARN_(CLASS_NAME, "IoCreateDevice() failed with status 0x%08lx\n", Status);
709 goto cleanup;
710 }
712
713 DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension;
714 RtlZeroMemory(DeviceExtension, sizeof(PORT_DEVICE_EXTENSION));
715 DeviceExtension->Common.IsClassDO = FALSE;
716 DeviceExtension->DeviceObject = Fdo;
717 DeviceExtension->PnpState = dsStopped;
719 if (!NT_SUCCESS(Status))
720 {
721 WARN_(CLASS_NAME, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
722 goto cleanup;
723 }
724 if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
725 Fdo->Flags |= DO_POWER_PAGABLE;
726 if (DeviceExtension->LowerDevice->Flags & DO_BUFFERED_IO)
727 Fdo->Flags |= DO_BUFFERED_IO;
728 if (DeviceExtension->LowerDevice->Flags & DO_DIRECT_IO)
729 Fdo->Flags |= DO_DIRECT_IO;
730
731 if (DriverExtension->ConnectMultiplePorts)
732 DeviceExtension->ClassDO = DriverExtension->MainClassDeviceObject;
733 else
734 {
735 /* We need a new class device object for this Fdo */
738 &DeviceExtension->ClassDO);
739 if (!NT_SUCCESS(Status))
740 {
741 WARN_(CLASS_NAME, "CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
742 goto cleanup;
743 }
744 }
745 Status = ConnectPortDriver(Fdo, DeviceExtension->ClassDO);
746 if (!NT_SUCCESS(Status))
747 {
748 WARN_(CLASS_NAME, "ConnectPortDriver() failed with status 0x%08lx\n", Status);
749 goto cleanup;
750 }
751 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
752
753 /* Register interface ; ignore the error (if any) as having
754 * a registered interface is not so important... */
756 Pdo,
757 &GUID_DEVINTERFACE_KEYBOARD,
758 NULL,
759 &DeviceExtension->InterfaceName);
760 if (!NT_SUCCESS(Status))
761 DeviceExtension->InterfaceName.Length = 0;
762
763 return STATUS_SUCCESS;
764
765cleanup:
766 if (Fdo)
768 return Status;
769}
770
771static VOID NTAPI
774 IN PIRP Irp)
775{
776 PCOMMON_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
779 BOOLEAN wasQueued = FALSE;
780
781 TRACE_(CLASS_NAME, "ClassCancelRoutine(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
782
783 if (DeviceExtension->IsClassDO)
784 {
785 ReadData = ((PCLASS_DEVICE_EXTENSION)DeviceExtension)->ReadData;
786 }
787 else
788 {
790 PCLASS_DEVICE_EXTENSION Class = (PCLASS_DEVICE_EXTENSION)Port->ClassDO->DeviceExtension;
791 ReadData = Class->ReadData;
792 }
793
794 IoReleaseCancelSpinLock(Irp->CancelIrql);
795
796 KeAcquireSpinLock(&ReadData->SpinLock, &OldIrql);
797
798 if (ReadData->PendingIrp == Irp)
799 {
800 ReadData->PendingIrp = NULL;
801 wasQueued = TRUE;
802 }
804
805 if (wasQueued)
806 {
807 Irp->IoStatus.Status = STATUS_CANCELLED;
808 Irp->IoStatus.Information = 0;
810 }
811 else
812 {
813 DPRINT1("Cancelled IRP is not pending. Race condition?\n");
814 }
815}
816
817static NTSTATUS
822{
825
826 TRACE_(CLASS_NAME, "HandleReadIrp(DeviceObject %p, ReadData %p, Irp %p)\n", DeviceObject, ReadData, Irp);
827
828 if (!Irp)
829 Irp = ReadData->PendingIrp;
830 if (!Irp)
831 return STATUS_SUCCESS;
832
833 if (ReadData->InputCount > 0)
834 {
835 SIZE_T NumberOfEntries;
837
838 if (DeviceObject->Flags & DO_BUFFERED_IO)
839 Destination = Irp->AssociatedIrp.SystemBuffer;
840 else if (DeviceObject->Flags & DO_DIRECT_IO)
842 else
843 Destination = Irp->UserBuffer;
844
845 KeAcquireSpinLock(&ReadData->SpinLock, &OldIrql);
846 NumberOfEntries = MIN(
847 ReadData->InputCount,
849
852 ReadData->PortData,
854 NumberOfEntries);
855
856 if (NT_SUCCESS(Status))
857 {
858 if (ReadData->InputCount > NumberOfEntries)
859 {
861 &ReadData->PortData[0],
862 &ReadData->PortData[NumberOfEntries],
863 (ReadData->InputCount - NumberOfEntries) * sizeof(KEYBOARD_INPUT_DATA));
864 }
865
866 ReadData->InputCount -= NumberOfEntries;
867
868 Irp->IoStatus.Information = NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA);
869 }
870
871 /* Go to next packet and complete this request */
872 Irp->IoStatus.Status = Status;
873
876 ReadData->PendingIrp = NULL;
878
879 return Status;
880 }
881
883 if (Irp->Cancel)
884 {
885 ReadData->PendingIrp = NULL;
887 }
888 else
889 {
891 ReadData->PendingIrp = Irp;
894 }
896 return Status;
897}
898
899static NTSTATUS NTAPI
902 IN PIRP Irp)
903{
904 PPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
909
910 switch (IrpSp->MinorFunction)
911 {
913 if (IoForwardIrpSynchronously(DeviceExtension->LowerDevice, Irp))
914 {
915 Status = Irp->IoStatus.Status;
916 }
917 else
918 {
920 }
921
922 if (NT_SUCCESS(Status))
923 {
925 &DeviceExtension->InterfaceName,
927 NULL,
928 NULL);
929
930 Status = ZwOpenFile(&DeviceExtension->FileHandle,
933 &Iosb,
934 0,
935 0);
936 if (!NT_SUCCESS(Status))
937 DeviceExtension->FileHandle = NULL;
938 }
939 else
940 DeviceExtension->FileHandle = NULL;
941 if (DeviceExtension->InterfaceName.Length != 0)
942 IoSetDeviceInterfaceState(&DeviceExtension->InterfaceName, TRUE);
943 Irp->IoStatus.Status = Status;
945 return Status;
946
948 if (DeviceExtension->FileHandle)
949 {
950 ZwClose(DeviceExtension->FileHandle);
951 DeviceExtension->FileHandle = NULL;
952 }
954 break;
955
957 if (DeviceExtension->InterfaceName.Length != 0)
959 if (DeviceExtension->FileHandle)
960 {
961 ZwClose(DeviceExtension->FileHandle);
962 DeviceExtension->FileHandle = NULL;
963 }
965 Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
967 return Status;
968
969 default:
970 Status = Irp->IoStatus.Status;
971 break;
972 }
973
974 Irp->IoStatus.Status = Status;
976 {
978 return IoCallDriver(DeviceExtension->LowerDevice, Irp);
979 }
980 else
981 {
983 return Status;
984 }
985}
986
987static VOID NTAPI
990 IN PIRP Irp)
991{
992 PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
993
994 TRACE_(CLASS_NAME, "ClassStartIo(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
995
996 ASSERT(DeviceExtension->Common.IsClassDO);
997
998 HandleReadIrp(DeviceObject, DeviceExtension->ReadData, Irp);
999}
1000
1001static VOID NTAPI
1004 IN PVOID Context, /* PCLASS_DRIVER_EXTENSION */
1005 IN ULONG Count)
1006{
1007 UNICODE_STRING DeviceMapKeyU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
1009 UNICODE_STRING PortBaseName = { 0, 0, NULL };
1010 PKEY_VALUE_BASIC_INFORMATION KeyValueInformation = NULL;
1012 HANDLE hDeviceMapKey = (HANDLE)-1;
1013 HANDLE hPortKey = (HANDLE)-1;
1014 ULONG Index = 0;
1017
1018 TRACE_(CLASS_NAME, "SearchForLegacyDrivers(%p %p %lu)\n",
1020
1021 if (Count != 1)
1022 return;
1024
1025 /* Create port base name, by replacing Class by Port at the end of the class base name */
1028 &DriverExtension->DeviceBaseName,
1029 &PortBaseName);
1030 if (!NT_SUCCESS(Status))
1031 {
1032 WARN_(CLASS_NAME, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status);
1033 goto cleanup;
1034 }
1035 PortBaseName.Length -= (sizeof(L"Class") - sizeof(UNICODE_NULL));
1036 RtlAppendUnicodeToString(&PortBaseName, L"Port");
1037
1038 /* Allocate memory */
1040 KeyValueInformation = ExAllocatePoolWithTag(PagedPool, Size, CLASS_TAG);
1041 if (!KeyValueInformation)
1042 {
1043 WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
1045 goto cleanup;
1046 }
1047
1048 /* Open HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
1050 Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
1052 {
1053 INFO_(CLASS_NAME, "HKLM\\HARDWARE\\DEVICEMAP is non-existent\n");
1055 goto cleanup;
1056 }
1057 else if (!NT_SUCCESS(Status))
1058 {
1059 WARN_(CLASS_NAME, "ZwOpenKey() failed with status 0x%08lx\n", Status);
1060 goto cleanup;
1061 }
1062
1063 /* Open sub key */
1067 {
1068 INFO_(CLASS_NAME, "HKLM\\HARDWARE\\DEVICEMAP\\%wZ is non-existent\n", &PortBaseName);
1070 goto cleanup;
1071 }
1072 else if (!NT_SUCCESS(Status))
1073 {
1074 WARN_(CLASS_NAME, "ZwOpenKey() failed with status 0x%08lx\n", Status);
1075 goto cleanup;
1076 }
1077
1078 /* Read each value name */
1079 while (ZwEnumerateValueKey(hPortKey, Index++, KeyValueBasicInformation, KeyValueInformation, Size, &ResultLength) == STATUS_SUCCESS)
1080 {
1082 PDEVICE_OBJECT PortDeviceObject = NULL;
1084
1085 PortName.Length = PortName.MaximumLength = (USHORT)KeyValueInformation->NameLength;
1086 PortName.Buffer = KeyValueInformation->Name;
1087
1088 /* Open the device object pointer */
1090 if (!NT_SUCCESS(Status))
1091 {
1092 WARN_(CLASS_NAME, "IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", &PortName, Status);
1093 continue;
1094 }
1095 INFO_(CLASS_NAME, "Legacy driver found\n");
1096
1097 Status = ClassAddDevice(DriverObject, PortDeviceObject);
1098 if (!NT_SUCCESS(Status))
1099 {
1100 /* FIXME: Log the error */
1101 WARN_(CLASS_NAME, "ClassAddDevice() failed with status 0x%08lx\n", Status);
1102 }
1103
1105 }
1106
1107cleanup:
1108 if (KeyValueInformation != NULL)
1109 ExFreePoolWithTag(KeyValueInformation, CLASS_TAG);
1110 if (hDeviceMapKey != (HANDLE)-1)
1111 ZwClose(hDeviceMapKey);
1112 if (hPortKey != (HANDLE)-1)
1113 ZwClose(hPortKey);
1114}
1115
1116/*
1117 * Standard DriverEntry method.
1118 */
1123{
1126
1130 sizeof(CLASS_DRIVER_EXTENSION),
1132 if (!NT_SUCCESS(Status))
1133 {
1134 WARN_(CLASS_NAME, "IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status);
1135 return Status;
1136 }
1138
1142 &DriverExtension->RegistryPath);
1143 if (!NT_SUCCESS(Status))
1144 {
1145 WARN_(CLASS_NAME, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status);
1146 return Status;
1147 }
1148
1150 if (!NT_SUCCESS(Status))
1151 {
1152 WARN_(CLASS_NAME, "ReadRegistryEntries() failed with status 0x%08lx\n", Status);
1153 return Status;
1154 }
1155
1156 if (DriverExtension->ConnectMultiplePorts == 1)
1157 {
1160 &DriverExtension->MainClassDeviceObject);
1161 if (!NT_SUCCESS(Status))
1162 {
1163 WARN_(CLASS_NAME, "CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
1164 return Status;
1165 }
1166 }
1167
1168 DriverObject->DriverExtension->AddDevice = ClassAddDevice;
1169 DriverObject->DriverUnload = DriverUnload;
1170
1171 DriverObject->MajorFunction[IRP_MJ_CREATE] = ClassCreate;
1172 DriverObject->MajorFunction[IRP_MJ_CLOSE] = ClassClose;
1173 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = ClassCleanup;
1174 DriverObject->MajorFunction[IRP_MJ_READ] = ClassRead;
1175 DriverObject->MajorFunction[IRP_MJ_POWER] = ClassPower;
1176 DriverObject->MajorFunction[IRP_MJ_PNP] = ClassPnp;
1179 DriverObject->DriverStartIo = ClassStartIo;
1180
1181 /* We will detect the legacy devices later */
1186
1187 return STATUS_SUCCESS;
1188}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
static UNICODE_STRING PortName
#define VOID
Definition: acefi.h:82
unsigned char BOOLEAN
Definition: actypes.h:127
#define REG_SZ
Definition: layer.c:22
LONG NTSTATUS
Definition: precomp.h:26
#define MIN(x, y)
Definition: rdesktop.h:171
#define DPRINT1
Definition: precomp.h:8
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
_In_ HANDLE _In_ CONST PDXGKMDT_OPM_GET_INFO_PARAMETERS Parameters
Definition: dispmprt.h:321
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
#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:33
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define TRACE_(x)
Definition: compat.h:76
#define MAX_PATH
Definition: compat.h:34
static void cleanup(void)
Definition: main.c:1335
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define L(x)
Definition: resources.c:13
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4138
return Iosb
Definition: create.c:4403
@ ReadData
Definition: amstream.idl:63
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#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 KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:24
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
CPPORT Port[4]
Definition: headless.c:38
#define IOCTL_HID_GET_DRIVER_CONFIG
Definition: hidclass.h:74
#define IOCTL_HID_GET_MANUFACTURER_STRING
Definition: hidclass.h:64
#define IOCTL_HID_GET_COLLECTION_DESCRIPTOR
Definition: hidclass.h:58
#define IOCTL_HID_GET_PRODUCT_STRING
Definition: hidclass.h:67
#define IOCTL_HID_SET_POLL_FREQUENCY_MSEC
Definition: hidclass.h:72
#define IOCTL_GET_NUM_DEVICE_INPUT_BUFFERS
Definition: hidclass.h:65
#define IOCTL_HID_GET_INDEXED_STRING
Definition: hidclass.h:76
#define IOCTL_SET_NUM_DEVICE_INPUT_BUFFERS
Definition: hidclass.h:70
#define IOCTL_HID_GET_SERIALNUMBER_STRING
Definition: hidclass.h:68
#define IOCTL_HID_GET_POLL_FREQUENCY_MSEC
Definition: hidclass.h:66
#define IOCTL_HID_GET_MS_GENRE_DESCRIPTOR
Definition: hidclass.h:77
#define IOCTL_HID_SET_FEATURE
Definition: hidclass.h:69
#define IOCTL_HID_FLUSH_QUEUE
Definition: hidclass.h:57
#define IOCTL_HID_GET_HARDWARE_ID
Definition: hidclass.h:61
#define IOCTL_GET_PHYSICAL_DESCRIPTOR
Definition: hidclass.h:56
#define IOCTL_HID_SET_DRIVER_CONFIG
Definition: hidclass.h:75
#define IOCTL_HID_GET_FEATURE
Definition: hidclass.h:60
#define IOCTL_HID_GET_COLLECTION_INFORMATION
Definition: hidclass.h:59
return ZwOpenKey(Handle, KEY_READ, &Attributes)
ZwClose(Handle)
_In_ UCXUSBDEVICE _In_ PDEVICE_OBJECT Pdo
Definition: hubucx.h:280
struct _PORT_DEVICE_EXTENSION * PPORT_DEVICE_EXTENSION
NTSTATUS DuplicateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString)
Definition: misc.c:31
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
@ dsStopped
Definition: isapnp.h:30
static DRIVER_DISPATCH ClassDeviceControl
Definition: kbdclass.c:24
static DRIVER_DISPATCH ClassRead
Definition: kbdclass.c:23
static VOID DestroyPortDriver(IN PDEVICE_OBJECT PortDO)
Definition: kbdclass.c:620
static DRIVER_ADD_DEVICE ClassAddDevice
Definition: kbdclass.c:26
static DRIVER_CANCEL ClassCancelRoutine
Definition: kbdclass.c:28
static VOID NTAPI SearchForLegacyDrivers(IN PDRIVER_OBJECT DriverObject, IN PVOID Context, IN ULONG Count)
Definition: kbdclass.c:1002
static NTSTATUS ReadRegistryEntries(IN PUNICODE_STRING RegistryPath, IN PCLASS_DRIVER_EXTENSION DriverExtension)
Definition: kbdclass.c:277
static DRIVER_DISPATCH ClassClose
Definition: kbdclass.c:21
static NTSTATUS ConnectPortDriver(IN PDEVICE_OBJECT PortDO, IN PDEVICE_OBJECT ClassDO)
Definition: kbdclass.c:566
static NTSTATUS NTAPI ClassPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: kbdclass.c:900
static DRIVER_DISPATCH ClassCleanup
Definition: kbdclass.c:22
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:511
static NTSTATUS FillEntries(IN PDEVICE_OBJECT ClassDeviceObject, IN PKEYBOARD_INPUT_DATA Source, OUT PKEYBOARD_INPUT_DATA Destination, IN SIZE_T NumberOfEntries)
Definition: kbdclass.c:473
static NTSTATUS HandleReadIrp(IN PDEVICE_OBJECT DeviceObject, IN PREAD_DATA ReadData, IN PIRP Irp OPTIONAL)
Definition: kbdclass.c:818
static NTSTATUS CreateClassDeviceObject(IN PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
Definition: kbdclass.c:360
static DRIVER_DISPATCH ClassPower
Definition: kbdclass.c:25
static DRIVER_DISPATCH ClassCreate
Definition: kbdclass.c:20
static DRIVER_STARTIO ClassStartIo
Definition: kbdclass.c:27
static DRIVER_UNLOAD DriverUnload
Definition: kbdclass.c:19
struct _CLASS_DRIVER_EXTENSION * PCLASS_DRIVER_EXTENSION
#define CLASS_TAG
Definition: kbdclass.h:11
#define IOCTL_INTERNAL_KEYBOARD_CONNECT
Definition: kbdmou.h:56
#define IOCTL_INTERNAL_KEYBOARD_DISCONNECT
Definition: kbdmou.h:59
_In_ PIRP Irp
Definition: kse.h:79
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
@ NormalPagePriority
Definition: imports.h:54
#define _swprintf(buf, format,...)
Definition: sprintf.c:56
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3171
#define KernelMode
Definition: asm.h:38
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)
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3051
DRIVER_DISPATCH(nfs41_FsdDispatch)
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
struct _KEY_VALUE_BASIC_INFORMATION KEY_VALUE_BASIC_INFORMATION
#define FILE_READ_DATA
Definition: nt_native.h:628
@ KeyValueBasicInformation
Definition: nt_native.h:1183
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
#define UNICODE_NULL
struct _KEYBOARD_INPUT_DATA KEYBOARD_INPUT_DATA
#define IOCTL_KEYBOARD_QUERY_TYPEMATIC
Definition: ntddkbd.h:41
#define IOCTL_KEYBOARD_QUERY_INDICATORS
Definition: ntddkbd.h:35
#define IOCTL_KEYBOARD_SET_INDICATORS
Definition: ntddkbd.h:47
#define IOCTL_KEYBOARD_QUERY_ATTRIBUTES
Definition: ntddkbd.h:32
#define IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION
Definition: ntddkbd.h:38
#define IOCTL_KEYBOARD_SET_TYPEMATIC
Definition: ntddkbd.h:44
@ NotificationEvent
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
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:1038
NTSTATUS NTAPI IoAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice, IN OUT PDEVICE_OBJECT *AttachedToDeviceObject)
Definition: device.c:987
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1306
VOID NTAPI IoSetStartIoAttributes(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DeferredStartIo, IN BOOLEAN NonCancelable)
Definition: device.c:1817
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1261
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1455
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:1451
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1807
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1925
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1818
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1847
#define IoCompleteRequest
Definition: irp.c:1272
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:913
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1657
#define IoCallDriver
Definition: irp.c:1257
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:758
#define STATUS_TOO_MANY_NAMES
Definition: ntstatus.h:535
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31
short WCHAR
Definition: pedump.c:58
unsigned short USHORT
Definition: pedump.c:61
#define IOCTL_GET_SYS_BUTTON_CAPS
Definition: poclass.h:59
#define IOCTL_GET_SYS_BUTTON_EVENT
Definition: poclass.h:62
#define FILE_DEVICE_KEYBOARD
Definition: winioctl.h:56
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define REG_DWORD
Definition: sdbapi.c:615
#define INFO_(ch,...)
Definition: debug.h:159
#define WARN_(ch,...)
Definition: debug.h:157
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PVOID ClassService
Definition: kbdmou.h:82
PDEVICE_OBJECT ClassDeviceObject
Definition: kbdmou.h:81
PVOID DeviceExtension
Definition: env_spec_w32.h:418
struct _IO_STACK_LOCATION::@5136::@5140 Read
struct _IO_STACK_LOCATION::@1823::@1824 DeviceIoControl
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PDEVICE_OBJECT DeviceObject
Definition: kbdclass.h:53
UNICODE_STRING InterfaceName
Definition: kbdclass.h:58
PORT_DEVICE_STATE PnpState
Definition: kbdclass.h:54
LIST_ENTRY ListEntry
Definition: kbdclass.h:52
PDEVICE_OBJECT ClassDO
Definition: kbdclass.h:56
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:50
PDEVICE_OBJECT LowerDevice
Definition: kbdclass.h:55
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_PENDING
Definition: telnetd.h:14
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
_In_ PGUID _In_ ULONG _Out_ PULONG ResultLength
Definition: ucxcontroller.h:83
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
USHORT Count
Definition: userreq.cpp:200
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1705
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2721
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_START_DEVICE
#define IRP_MN_REMOVE_DEVICE
#define DO_POWER_PAGABLE
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_MN_SET_POWER
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define IRP_MN_STOP_DEVICE
#define IRP_MJ_POWER
#define IO_KEYBOARD_INCREMENT
Definition: iotypes.h:601
#define IRP_MN_QUERY_POWER
#define IRP_MJ_CLEANUP
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ Suspended
Definition: ketypes.h:472
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204