ReactOS  0.4.14-dev-41-g31d7680
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 IrpStub (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 IrpStub
 
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 636 of file kbdclass.c.

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 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define DO_POWER_PAGABLE
#define TRUE
Definition: types.h:120
_In_ PDEVICE_OBJECT Pdo
Definition: classpnp.h:301
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42
LONG NTSTATUS
Definition: precomp.h:26
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
PDEVICE_OBJECT ClassDO
Definition: kbdclass.h:48
UNICODE_STRING InterfaceName
Definition: kbdclass.h:50
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define TRACE_(x)
Definition: compat.h:66
static NTSTATUS ConnectPortDriver(IN PDEVICE_OBJECT PortDO, IN PDEVICE_OBJECT ClassDO)
Definition: kbdclass.c:523
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
VOID NTAPI IoSetStartIoAttributes(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DeferredStartIo, IN BOOLEAN NonCancelable)
Definition: device.c:1798
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
PDEVICE_OBJECT LowerDevice
Definition: kbdclass.h:47
struct _PORT_DEVICE_EXTENSION * PPORT_DEVICE_EXTENSION
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
Status
Definition: gdiplustypes.h:24
static VOID DestroyPortDriver(IN PDEVICE_OBJECT PortDO)
Definition: kbdclass.c:577
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
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
char * cleanup(char *str)
Definition: wpickclick.c:99
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
PDEVICE_OBJECT DeviceObject
Definition: kbdclass.h:45
return STATUS_SUCCESS
Definition: btrfs.c:2966
PORT_DEVICE_STATE PnpState
Definition: kbdclass.h:46
#define WARN_(ch,...)
Definition: debug.h:157

◆ 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 468 of file kbdclass.c.

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 }
signed char * PCHAR
Definition: retypes.h:7
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define TRACE_(x)
Definition: compat.h:66
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
unsigned int ULONG
Definition: retypes.h:1

Referenced by ConnectPortDriver().

◆ ClassCancelRoutine()

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

Definition at line 728 of file kbdclass.c.

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 }
#define TRUE
Definition: types.h:120
_In_ PIRP Irp
Definition: csq.h:116
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:66
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define DPRINT1
Definition: precomp.h:8
#define IO_NO_INCREMENT
Definition: iotypes.h:566

◆ 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 
82 
83  /* FIXME: cleanup all associated Port devices */
84  Irp->IoStatus.Status = STATUS_SUCCESS;
85  Irp->IoStatus.Information = 0;
87  return STATUS_SUCCESS;
88 }
_In_ PIRP Irp
Definition: csq.h:116
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:66
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define IO_NO_INCREMENT
Definition: iotypes.h:566
return STATUS_SUCCESS
Definition: btrfs.c:2966

◆ 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 
65 
66  /* FIXME: close all associated Port devices */
67  Irp->IoStatus.Status = STATUS_SUCCESS;
68  Irp->IoStatus.Information = 0;
70  return STATUS_SUCCESS;
71 }
_In_ PIRP Irp
Definition: csq.h:116
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:66
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define IO_NO_INCREMENT
Definition: iotypes.h:566
return STATUS_SUCCESS
Definition: btrfs.c:2966

◆ 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 
48 
49  /* FIXME: open all associated Port devices */
50  Irp->IoStatus.Status = STATUS_SUCCESS;
51  Irp->IoStatus.Information = 0;
53  return STATUS_SUCCESS;
54 }
_In_ PIRP Irp
Definition: csq.h:116
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:66
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define IO_NO_INCREMENT
Definition: iotypes.h:566
return STATUS_SUCCESS
Definition: btrfs.c:2966

◆ 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 
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 }
#define IOCTL_KEYBOARD_QUERY_TYPEMATIC
Definition: ntddkbd.h:41
#define IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION
Definition: ntddkbd.h:38
_In_ PIRP Irp
Definition: csq.h:116
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
LONG NTSTATUS
Definition: precomp.h:26
struct _CLASS_DEVICE_EXTENSION * PCLASS_DEVICE_EXTENSION
#define IOCTL_KEYBOARD_SET_TYPEMATIC
Definition: ntddkbd.h:44
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IoCompleteRequest
Definition: irp.c:1240
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define IOCTL_KEYBOARD_QUERY_INDICATORS
Definition: ntddkbd.h:35
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DRIVER_DISPATCH ForwardIrpAndWait
Definition: i8042prt.h:343
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
Definition: typedefs.h:117
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IOCTL_KEYBOARD_QUERY_ATTRIBUTES
Definition: ntddkbd.h:32
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define IOCTL_KEYBOARD_SET_INDICATORS
Definition: ntddkbd.h:47
PDEVICE_OBJECT DeviceObject
Definition: kbdclass.h:45
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define WARN_(ch,...)
Definition: debug.h:157
base of all file and directory entries
Definition: entries.h:82

◆ ClassPnp()

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

Definition at line 834 of file kbdclass.c.

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 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IRP_MN_REMOVE_DEVICE
_In_ PIRP Irp
Definition: csq.h:116
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_READ_DATA
Definition: nt_native.h:628
UNICODE_STRING InterfaceName
Definition: kbdclass.h:50
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
#define IRP_MN_STOP_DEVICE
return Iosb
Definition: create.c:4426
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PDEVICE_OBJECT LowerDevice
Definition: kbdclass.h:47
#define IRP_MN_START_DEVICE
DRIVER_DISPATCH ForwardIrpAndWait
Definition: i8042prt.h:343
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
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)
Status
Definition: gdiplustypes.h:24
static VOID DestroyPortDriver(IN PDEVICE_OBJECT PortDO)
Definition: kbdclass.c:577
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231

Referenced by DriverEntry().

◆ ClassRead()

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

Definition at line 91 of file kbdclass.c.

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 }
_In_ PIRP Irp
Definition: csq.h:116
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:66
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IO_NO_INCREMENT
Definition: iotypes.h:566

◆ ClassStartIo()

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

Definition at line 910 of file kbdclass.c.

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 }
#define TRUE
Definition: types.h:120
_In_ PIRP Irp
Definition: csq.h:116
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define TRACE_(x)
Definition: compat.h:66
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627

◆ ConnectPortDriver()

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

Definition at line 523 of file kbdclass.c.

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 }
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
_In_ PIRP Irp
Definition: csq.h:116
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
LONG NTSTATUS
Definition: precomp.h:26
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
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
smooth NULL
Definition: ftsmooth.c:416
#define TRACE_(x)
Definition: compat.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
PVOID ClassService
Definition: kbdmou.h:82
#define IOCTL_INTERNAL_KEYBOARD_CONNECT
Definition: kbdmou.h:56
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
Status
Definition: gdiplustypes.h:24
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
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
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 ObReferenceObject
Definition: obfuncs.h:204
PDEVICE_OBJECT ClassDeviceObject
Definition: kbdmou.h:81

Referenced by ClassAddDevice().

◆ CreateClassDeviceObject()

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

Definition at line 313 of file kbdclass.c.

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 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define CLASS_TAG
Definition: kbdclass.h:11
#define DO_POWER_PAGABLE
#define TRUE
Definition: types.h:120
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
struct _CLASS_DEVICE_EXTENSION * PCLASS_DEVICE_EXTENSION
#define UNICODE_NULL
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define TRACE_(x)
Definition: compat.h:66
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
static const WCHAR L[]
Definition: oid.c:1250
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
Status
Definition: gdiplustypes.h:24
unsigned short USHORT
Definition: pedump.c:61
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
unsigned int ULONG
Definition: retypes.h:1
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
char * cleanup(char *str)
Definition: wpickclick.c:99
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define STATUS_TOO_MANY_NAMES
Definition: ntstatus.h:427
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define WARN_(ch,...)
Definition: debug.h:157
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define FILE_DEVICE_KEYBOARD
Definition: winioctl.h:116
#define REG_SZ
Definition: layer.c:22

Referenced by ClassAddDevice(), and DriverEntry().

◆ DestroyPortDriver()

static VOID DestroyPortDriver ( IN PDEVICE_OBJECT  PortDO)
static

Definition at line 577 of file kbdclass.c.

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 }
#define CLASS_TAG
Definition: kbdclass.h:11
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
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
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
PDEVICE_OBJECT ClassDO
Definition: kbdclass.h:48
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define TRACE_(x)
Definition: compat.h:66
#define IOCTL_INTERNAL_KEYBOARD_DISCONNECT
Definition: kbdmou.h:59
#define STATUS_PENDING
Definition: ntstatus.h:82
PDEVICE_OBJECT LowerDevice
Definition: kbdclass.h:47
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
struct _PORT_DEVICE_EXTENSION * PPORT_DEVICE_EXTENSION
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
Status
Definition: gdiplustypes.h:24
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
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 ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165

Referenced by ClassAddDevice(), and ClassPnp().

◆ DriverEntry()

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

Definition at line 1045 of file kbdclass.c.

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 IRP_MJ_CREATE
Definition: rdpdr.c:44
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1764
static DRIVER_DISPATCH ClassRead
Definition: kbdclass.c:21
static DRIVER_DISPATCH ClassCleanup
Definition: kbdclass.c:20
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
static DRIVER_ADD_DEVICE ClassAddDevice
Definition: kbdclass.c:24
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
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
static DRIVER_DISPATCH ClassClose
Definition: kbdclass.c:19
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
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 NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS DuplicateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString)
Definition: misc.c:72
static DRIVER_STARTIO ClassStartIo
Definition: kbdclass.c:25
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
static DRIVER_DISPATCH IrpStub
Definition: kbdclass.c:23
Status
Definition: gdiplustypes.h:24
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2112
static DRIVER_UNLOAD DriverUnload
Definition: kbdclass.c:17
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_CLEANUP
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
PDRIVER_STARTIO DriverStartIo
Definition: iotypes.h:2179
static NTSTATUS CreateClassDeviceObject(IN PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
Definition: kbdclass.c:313
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define WARN_(ch,...)
Definition: debug.h:157
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
static DRIVER_DISPATCH ClassCreate
Definition: kbdclass.c:18
static DRIVER_DISPATCH ClassDeviceControl
Definition: kbdclass.c:22

◆ 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 420 of file kbdclass.c.

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 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
return STATUS_SUCCESS
Definition: btrfs.c:2966

Referenced by HandleReadIrp().

◆ HandleReadIrp()

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

Definition at line 764 of file kbdclass.c.

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 }
_In_ PIRP Irp
Definition: csq.h:116
#define IO_KEYBOARD_INCREMENT
Definition: iotypes.h:569
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
IoSetCancelRoutine(Irp, CancelRoutine)
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
T MIN(T a, T b)
Definition: polytest.cpp:79
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
struct _KEYBOARD_INPUT_DATA KEYBOARD_INPUT_DATA
#define TRACE_(x)
Definition: compat.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
static NTSTATUS FillEntries(IN PDEVICE_OBJECT ClassDeviceObject, IN PIRP Irp, IN PKEYBOARD_INPUT_DATA DataStart, IN SIZE_T NumberOfEntries)
Definition: kbdclass.c:420
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define VOID
Definition: acefi.h:82
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
ULONG_PTR SIZE_T
Definition: typedefs.h:78
static DRIVER_CANCEL ClassCancelRoutine
Definition: kbdclass.c:26
IoMarkIrpPending(Irp)

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

◆ IrpStub()

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

Definition at line 191 of file kbdclass.c.

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 }
NTSTATUS NTAPI PoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: power.c:485
_In_ PIRP Irp
Definition: csq.h:116
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42
#define ERR_(ch,...)
Definition: debug.h:156
LONG NTSTATUS
Definition: precomp.h:26
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IoCompleteRequest
Definition: irp.c:1240
PDEVICE_OBJECT LowerDevice
Definition: kbdclass.h:47
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define IRP_MJ_POWER
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
#define IO_NO_INCREMENT
Definition: iotypes.h:566

◆ ReadRegistryEntries()

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

Definition at line 229 of file kbdclass.c.

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 }
#define CLASS_TAG
Definition: kbdclass.h:11
const uint16_t * PCWSTR
Definition: typedefs.h:55
USHORT MaximumLength
Definition: env_spec_w32.h:370
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
void * PVOID
Definition: retypes.h:9
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
static const WCHAR L[]
Definition: oid.c:1250
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define REG_DWORD
Definition: sdbapi.c:596
#define WARN_(ch,...)
Definition: debug.h:157
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define REG_SZ
Definition: layer.c:22

Referenced by DriverEntry().

◆ SearchForLegacyDrivers()

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

Definition at line 927 of file kbdclass.c.

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 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define CLASS_TAG
Definition: kbdclass.h:11
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
struct _KEY_VALUE_BASIC_INFORMATION KEY_VALUE_BASIC_INFORMATION
#define INFO_(ch,...)
Definition: debug.h:159
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
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
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define TRACE_(x)
Definition: compat.h:66
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS DuplicateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString)
Definition: misc.c:72
#define MAX_PATH
Definition: compat.h:26
static const UCHAR Index[8]
Definition: usbohci.c:18
PVOID HANDLE
Definition: typedefs.h:71
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
* PFILE_OBJECT
Definition: iotypes.h:1955
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
struct _CLASS_DRIVER_EXTENSION * PCLASS_DRIVER_EXTENSION
unsigned short USHORT
Definition: pedump.c:61
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
char * cleanup(char *str)
Definition: wpickclick.c:99
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define WARN_(ch,...)
Definition: debug.h:157
IN PUNICODE_STRING PortName
Definition: conport.c:35
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by DriverEntry().

Variable Documentation

◆ ClassAddDevice

DRIVER_ADD_DEVICE ClassAddDevice
static

Definition at line 24 of file kbdclass.c.

Referenced by 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

◆ 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().

◆ IrpStub

DRIVER_DISPATCH IrpStub
static

Definition at line 23 of file kbdclass.c.

Referenced by DriverEntry().