ReactOS 0.4.15-dev-7958-gcd0bb1a
kbdclass.c File Reference
#include "kbdclass.h"
#include <stdio.h>
#include <pseh/pseh2.h>
#include <kbdmou.h>
#include <debug.h>
Include dependency graph for kbdclass.c:

Go to the source code of this file.

Functions

static NTSTATUS HandleReadIrp (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, BOOLEAN IsInStartIo)
 
static VOID NTAPI DriverUnload (IN PDRIVER_OBJECT DriverObject)
 
static NTSTATUS NTAPI ClassCreate (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static NTSTATUS NTAPI ClassClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static NTSTATUS NTAPI ClassCleanup (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static NTSTATUS NTAPI ClassRead (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static NTSTATUS NTAPI ClassDeviceControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static NTSTATUS NTAPI ClassPower (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static NTSTATUS ReadRegistryEntries (IN PUNICODE_STRING RegistryPath, IN PCLASS_DRIVER_EXTENSION DriverExtension)
 
static NTSTATUS CreateClassDeviceObject (IN PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
 
static NTSTATUS FillEntries (IN PDEVICE_OBJECT ClassDeviceObject, IN PIRP Irp, IN PKEYBOARD_INPUT_DATA DataStart, IN SIZE_T NumberOfEntries)
 
static BOOLEAN NTAPI ClassCallback (IN PDEVICE_OBJECT ClassDeviceObject, IN OUT PKEYBOARD_INPUT_DATA DataStart, IN PKEYBOARD_INPUT_DATA DataEnd, IN OUT PULONG ConsumedCount)
 
static NTSTATUS ConnectPortDriver (IN PDEVICE_OBJECT PortDO, IN PDEVICE_OBJECT ClassDO)
 
static VOID DestroyPortDriver (IN PDEVICE_OBJECT PortDO)
 
static NTSTATUS NTAPI ClassAddDevice (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT Pdo)
 
static VOID NTAPI ClassCancelRoutine (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static NTSTATUS NTAPI ClassPnp (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static VOID NTAPI ClassStartIo (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static VOID NTAPI SearchForLegacyDrivers (IN PDRIVER_OBJECT DriverObject, IN PVOID Context, IN ULONG Count)
 
NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 

Variables

static DRIVER_UNLOAD DriverUnload
 
static DRIVER_DISPATCH ClassCreate
 
static DRIVER_DISPATCH ClassClose
 
static DRIVER_DISPATCH ClassCleanup
 
static DRIVER_DISPATCH ClassRead
 
static DRIVER_DISPATCH ClassDeviceControl
 
static DRIVER_DISPATCH ClassPower
 
static DRIVER_ADD_DEVICE ClassAddDevice
 
static DRIVER_STARTIO ClassStartIo
 
static DRIVER_CANCEL ClassCancelRoutine
 

Function Documentation

◆ ClassAddDevice()

static NTSTATUS NTAPI ClassAddDevice ( IN PDRIVER_OBJECT  DriverObject,
IN PDEVICE_OBJECT  Pdo 
)
static

Definition at line 637 of file kbdclass.c.

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 */
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 */
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
722cleanup:
723 if (Fdo)
725 return Status;
726}
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TRACE_(x)
Definition: compat.h:76
static void cleanup(void)
Definition: main.c:1335
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
Status
Definition: gdiplustypes.h:25
struct _PORT_DEVICE_EXTENSION * PPORT_DEVICE_EXTENSION
@ dsStopped
Definition: isapnp.h:34
static VOID DestroyPortDriver(IN PDEVICE_OBJECT PortDO)
Definition: kbdclass.c:578
static NTSTATUS ConnectPortDriver(IN PDEVICE_OBJECT PortDO, IN PDEVICE_OBJECT ClassDO)
Definition: kbdclass.c:524
static NTSTATUS CreateClassDeviceObject(IN PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
Definition: kbdclass.c:314
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
NTSTATUS NTAPI IoAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice, IN OUT PDEVICE_OBJECT *AttachedToDeviceObject)
Definition: device.c:980
VOID NTAPI IoSetStartIoAttributes(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DeferredStartIo, IN BOOLEAN NonCancelable)
Definition: device.c:1798
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1904
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31
#define WARN_(ch,...)
Definition: debug.h:157
#define STATUS_SUCCESS
Definition: shellext.h:65
PDEVICE_OBJECT DeviceObject
Definition: kbdclass.h:45
UNICODE_STRING InterfaceName
Definition: kbdclass.h:50
PORT_DEVICE_STATE PnpState
Definition: kbdclass.h:46
PDEVICE_OBJECT ClassDO
Definition: kbdclass.h:48
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42
PDEVICE_OBJECT LowerDevice
Definition: kbdclass.h:47
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
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:72
#define DO_POWER_PAGABLE

◆ ClassCallback()

static BOOLEAN NTAPI ClassCallback ( IN PDEVICE_OBJECT  ClassDeviceObject,
IN OUT PKEYBOARD_INPUT_DATA  DataStart,
IN PKEYBOARD_INPUT_DATA  DataEnd,
IN OUT PULONG  ConsumedCount 
)
static

Definition at line 469 of file kbdclass.c.

474{
475 PCLASS_DEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
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}
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
static NTSTATUS HandleReadIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, BOOLEAN IsInStartIo)
Definition: kbdclass.c:765
#define ASSERT(a)
Definition: mode.c:44
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by ConnectPortDriver().

◆ ClassCancelRoutine()

static VOID NTAPI ClassCancelRoutine ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 729 of file kbdclass.c.

732{
733 PCLASS_DEVICE_EXTENSION ClassDeviceExtension = DeviceObject->DeviceExtension;
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}
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IO_NO_INCREMENT
Definition: iotypes.h:598

◆ ClassCleanup()

static NTSTATUS NTAPI ClassCleanup ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 74 of file kbdclass.c.

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}
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341

◆ ClassClose()

static NTSTATUS NTAPI ClassClose ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 57 of file kbdclass.c.

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}

◆ ClassCreate()

static NTSTATUS NTAPI ClassCreate ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 40 of file kbdclass.c.

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}

◆ ClassDeviceControl()

static NTSTATUS NTAPI ClassDeviceControl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 122 of file kbdclass.c.

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}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#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
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
base of all file and directory entries
Definition: entries.h:83
struct _IO_STACK_LOCATION::@1564::@1565 DeviceIoControl
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
#define IRP_MJ_INTERNAL_DEVICE_CONTROL

◆ ClassPnp()

static NTSTATUS NTAPI ClassPnp ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 835 of file kbdclass.c.

838{
839 PPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
844
845 switch (IrpSp->MinorFunction)
846 {
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
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}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
return Iosb
Definition: create.c:4402
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
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 NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define FILE_READ_DATA
Definition: nt_native.h:628
#define IRP_MN_START_DEVICE
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE

Referenced by DriverEntry().

◆ ClassPower()

static NTSTATUS NTAPI ClassPower ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 200 of file kbdclass.c.

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:
220 Irp->IoStatus.Status = STATUS_SUCCESS;
221 break;
222 }
223 Status = Irp->IoStatus.Status;
226 return Status;
227}
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:758
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1699
#define IRP_MN_SET_POWER
#define IRP_MN_QUERY_POWER

◆ ClassRead()

static NTSTATUS NTAPI ClassRead ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 91 of file kbdclass.c.

94{
95 PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
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}
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
struct _IO_STACK_LOCATION::@3978::@3982 Read

◆ ClassStartIo()

static VOID NTAPI ClassStartIo ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 919 of file kbdclass.c.

922{
923 PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
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}

◆ ConnectPortDriver()

static NTSTATUS ConnectPortDriver ( IN PDEVICE_OBJECT  PortDO,
IN PDEVICE_OBJECT  ClassDO 
)
static

Definition at line 524 of file kbdclass.c.

527{
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}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
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
#define IOCTL_INTERNAL_KEYBOARD_CONNECT
Definition: kbdmou.h:56
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
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 STATUS_PENDING
Definition: ntstatus.h:82
PVOID ClassService
Definition: kbdmou.h:82
PDEVICE_OBJECT ClassDeviceObject
Definition: kbdmou.h:81
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
@ Suspended
Definition: ketypes.h:420
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by ClassAddDevice().

◆ CreateClassDeviceObject()

static NTSTATUS CreateClassDeviceObject ( IN PDRIVER_OBJECT  DriverObject,
OUT PDEVICE_OBJECT *ClassDO  OPTIONAL 
)
static

Definition at line 314 of file kbdclass.c.

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));
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);
379cleanup:
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}
#define swprintf
Definition: precomp.h:40
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
#define CLASS_TAG
Definition: kbdclass.h:11
#define REG_SZ
Definition: layer.c:22
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165
#define UNICODE_NULL
#define STATUS_TOO_MANY_NAMES
Definition: ntstatus.h:441
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define FILE_DEVICE_KEYBOARD
Definition: winioctl.h:117
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ClassAddDevice(), and DriverEntry().

◆ DestroyPortDriver()

static VOID DestroyPortDriver ( IN PDEVICE_OBJECT  PortDO)
static

Definition at line 578 of file kbdclass.c.

580{
581 PPORT_DEVICE_EXTENSION DeviceExtension;
582 PCLASS_DEVICE_EXTENSION ClassDeviceExtension;
585 PIRP Irp;
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}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
#define IOCTL_INTERNAL_KEYBOARD_DISCONNECT
Definition: kbdmou.h:59
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PVOID DeviceExtension
Definition: env_spec_w32.h:418
LIST_ENTRY ListEntry
Definition: kbdclass.h:44
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by ClassAddDevice(), and ClassPnp().

◆ DriverEntry()

NTSTATUS NTAPI DriverEntry ( IN PDRIVER_OBJECT  DriverObject,
IN PUNICODE_STRING  RegistryPath 
)

Definition at line 1054 of file kbdclass.c.

1057{
1060
1064 sizeof(CLASS_DRIVER_EXTENSION),
1066 if (!NT_SUCCESS(Status))
1067 {
1068 WARN_(CLASS_NAME, "IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status);
1069 return Status;
1070 }
1072
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 {
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 */
1120
1121 return STATUS_SUCCESS;
1122}
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
NTSTATUS DuplicateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString)
Definition: misc.c:31
static DRIVER_DISPATCH ClassDeviceControl
Definition: kbdclass.c:22
static DRIVER_DISPATCH ClassRead
Definition: kbdclass.c:21
static DRIVER_ADD_DEVICE ClassAddDevice
Definition: kbdclass.c:24
static VOID NTAPI SearchForLegacyDrivers(IN PDRIVER_OBJECT DriverObject, IN PVOID Context, IN ULONG Count)
Definition: kbdclass.c:936
static NTSTATUS ReadRegistryEntries(IN PUNICODE_STRING RegistryPath, IN PCLASS_DRIVER_EXTENSION DriverExtension)
Definition: kbdclass.c:230
static DRIVER_DISPATCH ClassClose
Definition: kbdclass.c:19
static NTSTATUS NTAPI ClassPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: kbdclass.c:835
static DRIVER_DISPATCH ClassCleanup
Definition: kbdclass.c:20
static DRIVER_DISPATCH ClassPower
Definition: kbdclass.c:23
static DRIVER_DISPATCH ClassCreate
Definition: kbdclass.c:18
static DRIVER_STARTIO ClassStartIo
Definition: kbdclass.c:25
static DRIVER_UNLOAD DriverUnload
Definition: kbdclass.c:17
VOID NTAPI IoRegisterDriverReinitialization(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
Definition: driver.c:1797
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1826
#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
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
#define IRP_MJ_POWER
#define IRP_MJ_CLEANUP

◆ DriverUnload()

static VOID NTAPI DriverUnload ( IN PDRIVER_OBJECT  DriverObject)
static

Definition at line 34 of file kbdclass.c.

35{
36 // nothing to do here yet
37}

◆ FillEntries()

static NTSTATUS FillEntries ( IN PDEVICE_OBJECT  ClassDeviceObject,
IN PIRP  Irp,
IN PKEYBOARD_INPUT_DATA  DataStart,
IN SIZE_T  NumberOfEntries 
)
static

Definition at line 421 of file kbdclass.c.

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 {
452 {
454 Irp->UserBuffer,
455 DataStart,
456 NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
457 }
459 {
461 }
462 _SEH2_END;
463 }
464
465 return Status;
466}
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
@ NormalPagePriority
Definition: imports.h:56
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)

Referenced by HandleReadIrp().

◆ HandleReadIrp()

static NTSTATUS HandleReadIrp ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
BOOLEAN  IsInStartIo 
)
static

Definition at line 765 of file kbdclass.c.

769{
770 PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
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
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}
#define VOID
Definition: acefi.h:82
#define MIN(x, y)
Definition: rdesktop.h:171
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
static NTSTATUS FillEntries(IN PDEVICE_OBJECT ClassDeviceObject, IN PIRP Irp, IN PKEYBOARD_INPUT_DATA DataStart, IN SIZE_T NumberOfEntries)
Definition: kbdclass.c:421
static DRIVER_CANCEL ClassCancelRoutine
Definition: kbdclass.c:26
struct _KEYBOARD_INPUT_DATA KEYBOARD_INPUT_DATA
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define IO_KEYBOARD_INCREMENT
Definition: iotypes.h:601

Referenced by ClassCallback(), ClassRead(), and ClassStartIo().

◆ ReadRegistryEntries()

static NTSTATUS ReadRegistryEntries ( IN PUNICODE_STRING  RegistryPath,
IN PCLASS_DRIVER_EXTENSION  DriverExtension 
)
static

Definition at line 230 of file kbdclass.c.

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,
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}
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
#define REG_DWORD
Definition: sdbapi.c:596
const uint16_t * PCWSTR
Definition: typedefs.h:57
void * PVOID
Definition: typedefs.h:50
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by DriverEntry().

◆ SearchForLegacyDrivers()

static VOID NTAPI SearchForLegacyDrivers ( IN PDRIVER_OBJECT  DriverObject,
IN PVOID  Context,
IN ULONG  Count 
)
static

Definition at line 936 of file kbdclass.c.

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
1041cleanup:
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}
static UNICODE_STRING PortName
#define MAX_PATH
Definition: compat.h:34
struct _CLASS_DRIVER_EXTENSION * PCLASS_DRIVER_EXTENSION
int Count
Definition: noreturn.cpp:7
struct _KEY_VALUE_BASIC_INFORMATION KEY_VALUE_BASIC_INFORMATION
@ KeyValueBasicInformation
Definition: nt_native.h:1180
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
#define INFO_(ch,...)
Definition: debug.h:159
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
PVOID HANDLE
Definition: typedefs.h:73
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_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:4533
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by DriverEntry().

Variable Documentation

◆ ClassAddDevice

DRIVER_ADD_DEVICE ClassAddDevice
static

Definition at line 24 of file kbdclass.c.

Referenced by _IRQL_requires_max_(), DriverEntry(), and SearchForLegacyDrivers().

◆ ClassCancelRoutine

DRIVER_CANCEL ClassCancelRoutine
static

Definition at line 26 of file kbdclass.c.

Referenced by HandleReadIrp().

◆ ClassCleanup

DRIVER_DISPATCH ClassCleanup
static

Definition at line 20 of file kbdclass.c.

Referenced by DriverEntry().

◆ ClassClose

DRIVER_DISPATCH ClassClose
static

Definition at line 19 of file kbdclass.c.

Referenced by DriverEntry().

◆ ClassCreate

DRIVER_DISPATCH ClassCreate
static

Definition at line 18 of file kbdclass.c.

Referenced by DriverEntry().

◆ ClassDeviceControl

DRIVER_DISPATCH ClassDeviceControl
static

Definition at line 22 of file kbdclass.c.

Referenced by DiskDeviceControl(), DriverEntry(), and ScsiFlopDeviceControl().

◆ ClassPower

DRIVER_DISPATCH ClassPower
static

Definition at line 23 of file kbdclass.c.

Referenced by DriverEntry().

◆ ClassRead

DRIVER_DISPATCH ClassRead
static

Definition at line 21 of file kbdclass.c.

Referenced by DriverEntry().

◆ ClassStartIo

DRIVER_STARTIO ClassStartIo
static

Definition at line 25 of file kbdclass.c.

Referenced by DriverEntry().

◆ DriverUnload

DRIVER_UNLOAD DriverUnload
static

Definition at line 17 of file kbdclass.c.

Referenced by _Function_class_(), and DriverEntry().