ReactOS  0.4.15-dev-1049-g1062a29
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 628 of file kbdclass.c.

631 {
633  PDEVICE_OBJECT Fdo = NULL;
634  PPORT_DEVICE_EXTENSION DeviceExtension = NULL;
636 
637  TRACE_(CLASS_NAME, "ClassAddDevice called. Pdo = 0x%p\n", Pdo);
638 
640 
641  if (Pdo == NULL)
642  /* We may get a NULL Pdo at the first call as we're a legacy driver. Ignore it */
643  return STATUS_SUCCESS;
644 
645  /* Create new device object */
647  DriverObject,
648  sizeof(PORT_DEVICE_EXTENSION),
649  NULL,
650  Pdo->DeviceType,
651  Pdo->Characteristics & FILE_DEVICE_SECURE_OPEN ? FILE_DEVICE_SECURE_OPEN : 0,
652  FALSE,
653  &Fdo);
654  if (!NT_SUCCESS(Status))
655  {
656  WARN_(CLASS_NAME, "IoCreateDevice() failed with status 0x%08lx\n", Status);
657  goto cleanup;
658  }
660 
661  DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension;
662  RtlZeroMemory(DeviceExtension, sizeof(PORT_DEVICE_EXTENSION));
663  DeviceExtension->Common.IsClassDO = FALSE;
664  DeviceExtension->DeviceObject = Fdo;
665  DeviceExtension->PnpState = dsStopped;
666  Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
667  if (!NT_SUCCESS(Status))
668  {
669  WARN_(CLASS_NAME, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
670  goto cleanup;
671  }
672  if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
673  Fdo->Flags |= DO_POWER_PAGABLE;
674  if (DeviceExtension->LowerDevice->Flags & DO_BUFFERED_IO)
675  Fdo->Flags |= DO_BUFFERED_IO;
676  if (DeviceExtension->LowerDevice->Flags & DO_DIRECT_IO)
677  Fdo->Flags |= DO_DIRECT_IO;
678 
679  if (DriverExtension->ConnectMultiplePorts)
680  DeviceExtension->ClassDO = DriverExtension->MainClassDeviceObject;
681  else
682  {
683  /* We need a new class device object for this Fdo */
685  DriverObject,
686  &DeviceExtension->ClassDO);
687  if (!NT_SUCCESS(Status))
688  {
689  WARN_(CLASS_NAME, "CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
690  goto cleanup;
691  }
692  }
693  Status = ConnectPortDriver(Fdo, DeviceExtension->ClassDO);
694  if (!NT_SUCCESS(Status))
695  {
696  WARN_(CLASS_NAME, "ConnectPortDriver() failed with status 0x%08lx\n", Status);
697  goto cleanup;
698  }
699  Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
700 
701  /* Register interface ; ignore the error (if any) as having
702  * a registered interface is not so important... */
704  Pdo,
705  &GUID_DEVINTERFACE_KEYBOARD,
706  NULL,
707  &DeviceExtension->InterfaceName);
708  if (!NT_SUCCESS(Status))
709  DeviceExtension->InterfaceName.Length = 0;
710 
711  return STATUS_SUCCESS;
712 
713 cleanup:
714  if (Fdo)
715  DestroyPortDriver(Fdo);
716  return Status;
717 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define DO_POWER_PAGABLE
_In_ PDEVICE_OBJECT Pdo
Definition: classpnp.h:318
#define TRUE
Definition: types.h:120
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
#define FALSE
Definition: types.h:117
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:76
static NTSTATUS ConnectPortDriver(IN PDEVICE_OBJECT PortDO, IN PDEVICE_OBJECT ClassDO)
Definition: kbdclass.c:515
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
Status
Definition: gdiplustypes.h:24
struct _PORT_DEVICE_EXTENSION * PPORT_DEVICE_EXTENSION
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1869
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
static VOID DestroyPortDriver(IN PDEVICE_OBJECT PortDO)
Definition: kbdclass.c:569
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:262
char * cleanup(char *str)
Definition: wpickclick.c:99
static NTSTATUS CreateClassDeviceObject(IN PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
Definition: kbdclass.c:305
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
PDEVICE_OBJECT DeviceObject
Definition: kbdclass.h:45
return STATUS_SUCCESS
Definition: btrfs.c:3014
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 460 of file kbdclass.c.

465 {
466  PCLASS_DEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
467  KIRQL OldIrql;
468  SIZE_T InputCount = DataEnd - DataStart;
469  SIZE_T ReadSize;
470 
471  TRACE_(CLASS_NAME, "ClassCallback()\n");
472 
473  ASSERT(ClassDeviceExtension->Common.IsClassDO);
474 
475  KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql);
476  if (InputCount > 0)
477  {
478  if (ClassDeviceExtension->InputCount + InputCount > ClassDeviceExtension->DriverExtension->DataQueueSize)
479  {
480  /*
481  * We're exceeding the buffer, and data will be thrown away...
482  * FIXME: What could we do, as we are at DISPATCH_LEVEL?
483  */
484  ReadSize = ClassDeviceExtension->DriverExtension->DataQueueSize - ClassDeviceExtension->InputCount;
485  }
486  else
487  ReadSize = InputCount;
488 
489  /*
490  * Move the input data from the port data queue to our class data
491  * queue.
492  */
494  &ClassDeviceExtension->PortData[ClassDeviceExtension->InputCount],
495  (PCHAR)DataStart,
496  sizeof(KEYBOARD_INPUT_DATA) * ReadSize);
497 
498  /* Move the counter up */
499  ClassDeviceExtension->InputCount += ReadSize;
500 
501  (*ConsumedCount) += (ULONG)ReadSize;
502 
503  /* Complete pending IRP (if any) */
504  if (ClassDeviceExtension->PendingIrp)
505  HandleReadIrp(ClassDeviceObject, ClassDeviceExtension->PendingIrp, FALSE);
506  }
507  KeReleaseSpinLock(&ClassDeviceExtension->SpinLock, OldIrql);
508 
509  TRACE_(CLASS_NAME, "Leaving ClassCallback()\n");
510  return TRUE;
511 }
signed char * PCHAR
Definition: retypes.h:7
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define TRUE
Definition: types.h:120
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define TRACE_(x)
Definition: compat.h:76
static NTSTATUS HandleReadIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, BOOLEAN IsInStartIo)
Definition: kbdclass.c:756
#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:790
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#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 720 of file kbdclass.c.

723 {
724  PCLASS_DEVICE_EXTENSION ClassDeviceExtension = DeviceObject->DeviceExtension;
725  KIRQL OldIrql;
726  BOOLEAN wasQueued = FALSE;
727 
728  TRACE_(CLASS_NAME, "ClassCancelRoutine(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
729 
730  ASSERT(ClassDeviceExtension->Common.IsClassDO);
731 
732  IoReleaseCancelSpinLock(Irp->CancelIrql);
733 
734  KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql);
735 
736  if (ClassDeviceExtension->PendingIrp == Irp)
737  {
738  ClassDeviceExtension->PendingIrp = NULL;
739  wasQueued = TRUE;
740  }
741  KeReleaseSpinLock(&ClassDeviceExtension->SpinLock, OldIrql);
742 
743  if (wasQueued)
744  {
745  Irp->IoStatus.Status = STATUS_CANCELLED;
746  Irp->IoStatus.Information = 0;
748  }
749  else
750  {
751  DPRINT1("Cancelled IRP is not pending. Race condition?\n");
752  }
753 }
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:76
#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:790
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define DPRINT1
Definition: precomp.h:8
#define IO_NO_INCREMENT
Definition: iotypes.h:581

◆ 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 }
_In_ PIRP Irp
Definition: csq.h:116
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:76
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define IO_NO_INCREMENT
Definition: iotypes.h:581
return STATUS_SUCCESS
Definition: btrfs.c:3014

◆ 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 }
_In_ PIRP Irp
Definition: csq.h:116
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:76
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define IO_NO_INCREMENT
Definition: iotypes.h:581
return STATUS_SUCCESS
Definition: btrfs.c:3014

◆ 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 }
_In_ PIRP Irp
Definition: csq.h:116
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:76
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define IO_NO_INCREMENT
Definition: iotypes.h:581
return STATUS_SUCCESS
Definition: btrfs.c:3014

◆ 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 
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 */
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  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 FALSE
Definition: types.h:117
#define IOCTL_KEYBOARD_SET_TYPEMATIC
Definition: ntddkbd.h:44
#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:76
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#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)
Status
Definition: gdiplustypes.h:24
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:887
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
Definition: typedefs.h:119
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
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:423
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define IOCTL_KEYBOARD_SET_INDICATORS
Definition: ntddkbd.h:47
PDEVICE_OBJECT DeviceObject
Definition: kbdclass.h:45
return STATUS_SUCCESS
Definition: btrfs.c:3014
#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 826 of file kbdclass.c.

829 {
830  PPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
835 
836  switch (IrpSp->MinorFunction)
837  {
838  case IRP_MN_START_DEVICE:
840  if (NT_SUCCESS(Status))
841  {
843  &DeviceExtension->InterfaceName,
845  NULL,
846  NULL);
847 
848  Status = ZwOpenFile(&DeviceExtension->FileHandle,
851  &Iosb,
852  0,
853  0);
854  if (!NT_SUCCESS(Status))
855  DeviceExtension->FileHandle = NULL;
856  }
857  else
858  DeviceExtension->FileHandle = NULL;
859  Irp->IoStatus.Status = Status;
861  return Status;
862 
863  case IRP_MN_STOP_DEVICE:
864  if (DeviceExtension->FileHandle)
865  {
866  ZwClose(DeviceExtension->FileHandle);
867  DeviceExtension->FileHandle = NULL;
868  }
870  break;
871 
873  if (DeviceExtension->FileHandle)
874  {
875  ZwClose(DeviceExtension->FileHandle);
876  DeviceExtension->FileHandle = NULL;
877  }
879  Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
881  return Status;
882 
883  default:
884  Status = Irp->IoStatus.Status;
885  break;
886  }
887 
888  Irp->IoStatus.Status = Status;
890  {
892  return IoCallDriver(DeviceExtension->LowerDevice, Irp);
893  }
894  else
895  {
897  return Status;
898  }
899 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IRP_MN_REMOVE_DEVICE
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_In_ PIRP Irp
Definition: csq.h:116
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define FILE_READ_DATA
Definition: nt_native.h:628
UNICODE_STRING InterfaceName
Definition: kbdclass.h:50
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
#define IRP_MN_STOP_DEVICE
return Iosb
Definition: create.c:4402
#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
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:569
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
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:423
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by DriverEntry().

◆ ClassPower()

static NTSTATUS NTAPI ClassPower ( 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 port DO IRPs to lower device */
204  return PoCallDriver(DeviceExtension->LowerDevice, Irp);
205  }
206 
208  {
209  case IRP_MN_SET_POWER:
210  case IRP_MN_QUERY_POWER:
211  Irp->IoStatus.Status = STATUS_SUCCESS;
212  break;
213  }
214  Status = Irp->IoStatus.Status;
217  return Status;
218 }
#define IRP_MN_QUERY_POWER
_In_ PIRP Irp
Definition: csq.h:116
COMMON_DEVICE_EXTENSION Common
Definition: kbdclass.h:42
LONG NTSTATUS
Definition: precomp.h:26
#define IoCompleteRequest
Definition: irp.c:1240
PDEVICE_OBJECT LowerDevice
Definition: kbdclass.h:47
Status
Definition: gdiplustypes.h:24
#define IRP_MN_SET_POWER
_In_ UCHAR MinorFunction
Definition: pofuncs.h:42
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:737
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IO_NO_INCREMENT
Definition: iotypes.h:581
return STATUS_SUCCESS
Definition: btrfs.c:3014

◆ 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;
96  KIRQL OldIrql;
98 
99  TRACE_(CLASS_NAME, "IRP_MJ_READ\n");
100 
101  ASSERT(DeviceExtension->Common.IsClassDO);
102 
103  if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
105 
107  {
108  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
109  Irp->IoStatus.Information = 0;
111 
113  }
114 
115  KeAcquireSpinLock(&DeviceExtension->SpinLock, &OldIrql);
117  KeReleaseSpinLock(&DeviceExtension->SpinLock, OldIrql);
118  return Status;
119 }
_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:69
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define IoCompleteRequest
Definition: irp.c:1240
#define TRACE_(x)
Definition: compat.h:76
static NTSTATUS HandleReadIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, BOOLEAN IsInStartIo)
Definition: kbdclass.c:756
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:887
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IO_NO_INCREMENT
Definition: iotypes.h:581

◆ ClassStartIo()

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

Definition at line 902 of file kbdclass.c.

905 {
906  PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
907  KIRQL OldIrql;
908 
909  TRACE_(CLASS_NAME, "ClassStartIo(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
910 
911  ASSERT(DeviceExtension->Common.IsClassDO);
912 
913  KeAcquireSpinLock(&DeviceExtension->SpinLock, &OldIrql);
915  KeReleaseSpinLock(&DeviceExtension->SpinLock, OldIrql);
916 }
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define TRACE_(x)
Definition: compat.h:76
static NTSTATUS HandleReadIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, BOOLEAN IsInStartIo)
Definition: kbdclass.c:756
#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:790
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#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 515 of file kbdclass.c.

518 {
519  KEVENT Event;
520  PIRP Irp;
522  CONNECT_DATA ConnectData;
524 
525  TRACE_(CLASS_NAME, "Connecting PortDO %p to ClassDO %p\n", PortDO, ClassDO);
526 
528 
529  ConnectData.ClassDeviceObject = ClassDO;
530  ConnectData.ClassService = ClassCallback;
531 
534  PortDO,
535  &ConnectData, sizeof(CONNECT_DATA),
536  NULL, 0,
537  TRUE, &Event, &IoStatus);
538  if (!Irp)
540 
541  Status = IoCallDriver(PortDO, Irp);
542 
543  if (Status == STATUS_PENDING)
545  else
546  IoStatus.Status = Status;
547 
548  if (NT_SUCCESS(IoStatus.Status))
549  {
550  ObReferenceObject(PortDO);
552  &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListHead,
553  &((PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension)->ListEntry,
554  &((PCLASS_DEVICE_EXTENSION)ClassDO->DeviceExtension)->ListSpinLock);
555  if (ClassDO->StackSize <= PortDO->StackSize)
556  {
557  /* Increase the stack size, in case we have to
558  * forward some IRPs to the port device object
559  */
560  ClassDO->StackSize = PortDO->StackSize + 1;
561  }
562  }
563 
564  return IoStatus.Status;
565 }
#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:2659
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
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
#define FALSE
Definition: types.h:117
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
smooth NULL
Definition: ftsmooth.c:416
#define TRACE_(x)
Definition: compat.h:76
#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
Status
Definition: gdiplustypes.h:24
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
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:460
#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 305 of file kbdclass.c.

308 {
310  ULONG DeviceId = 0;
311  ULONG PrefixLength;
312  UNICODE_STRING DeviceNameU;
313  PWSTR DeviceIdW = NULL; /* Pointer into DeviceNameU.Buffer */
314  PDEVICE_OBJECT Fdo;
315  PCLASS_DEVICE_EXTENSION DeviceExtension;
317 
318  TRACE_(CLASS_NAME, "CreateClassDeviceObject(0x%p)\n", DriverObject);
319 
320  /* Create new device object */
322  DeviceNameU.Length = 0;
323  DeviceNameU.MaximumLength =
324  wcslen(L"\\Device\\") * sizeof(WCHAR) /* "\Device\" */
325  + DriverExtension->DeviceBaseName.Length /* "KeyboardClass" */
326  + 4 * sizeof(WCHAR) /* Id between 0 and 9999 */
327  + sizeof(UNICODE_NULL); /* Final NULL char */
328  DeviceNameU.Buffer = ExAllocatePoolWithTag(PagedPool, DeviceNameU.MaximumLength, CLASS_TAG);
329  if (!DeviceNameU.Buffer)
330  {
331  WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
332  return STATUS_NO_MEMORY;
333  }
334  Status = RtlAppendUnicodeToString(&DeviceNameU, L"\\Device\\");
335  if (!NT_SUCCESS(Status))
336  {
337  WARN_(CLASS_NAME, "RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
338  goto cleanup;
339  }
340  Status = RtlAppendUnicodeStringToString(&DeviceNameU, &DriverExtension->DeviceBaseName);
341  if (!NT_SUCCESS(Status))
342  {
343  WARN_(CLASS_NAME, "RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
344  goto cleanup;
345  }
346  PrefixLength = DeviceNameU.MaximumLength - 4 * sizeof(WCHAR) - sizeof(UNICODE_NULL);
347  DeviceIdW = &DeviceNameU.Buffer[PrefixLength / sizeof(WCHAR)];
348  while (DeviceId < 9999)
349  {
350  DeviceNameU.Length = (USHORT)(PrefixLength + swprintf(DeviceIdW, L"%lu", DeviceId) * sizeof(WCHAR));
352  DriverObject,
353  sizeof(CLASS_DEVICE_EXTENSION),
354  &DeviceNameU,
357  FALSE,
358  &Fdo);
359  if (NT_SUCCESS(Status))
360  goto cleanup;
362  {
363  WARN_(CLASS_NAME, "IoCreateDevice() failed with status 0x%08lx\n", Status);
364  goto cleanup;
365  }
366  DeviceId++;
367  }
368  WARN_(CLASS_NAME, "Too many devices starting with '\\Device\\%wZ'\n", &DriverExtension->DeviceBaseName);
370 cleanup:
371  if (!NT_SUCCESS(Status))
372  {
373  ExFreePoolWithTag(DeviceNameU.Buffer, CLASS_TAG);
374  return Status;
375  }
376 
377  DeviceExtension = (PCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension;
378  RtlZeroMemory(DeviceExtension, sizeof(CLASS_DEVICE_EXTENSION));
379  DeviceExtension->Common.IsClassDO = TRUE;
380  DeviceExtension->DriverExtension = DriverExtension;
381  InitializeListHead(&DeviceExtension->ListHead);
382  KeInitializeSpinLock(&DeviceExtension->ListSpinLock);
383  KeInitializeSpinLock(&DeviceExtension->SpinLock);
384  DeviceExtension->InputCount = 0;
385  DeviceExtension->PortData = ExAllocatePoolWithTag(NonPagedPool, DeviceExtension->DriverExtension->DataQueueSize * sizeof(KEYBOARD_INPUT_DATA), CLASS_TAG);
386  if (!DeviceExtension->PortData)
387  {
388  ExFreePoolWithTag(DeviceNameU.Buffer, CLASS_TAG);
389  return STATUS_NO_MEMORY;
390  }
391  DeviceExtension->DeviceName = DeviceNameU.Buffer;
392  Fdo->Flags |= DO_POWER_PAGABLE;
393  Fdo->Flags |= DO_BUFFERED_IO; /* FIXME: Why is it needed for 1st stage setup? */
394  Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
395 
396  /* Add entry entry to HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
399  DriverExtension->DeviceBaseName.Buffer,
400  DeviceExtension->DeviceName,
401  REG_SZ,
402  DriverExtension->RegistryPath.Buffer,
403  DriverExtension->RegistryPath.MaximumLength);
404 
405  if (ClassDO)
406  *ClassDO = Fdo;
407 
408  return STATUS_SUCCESS;
409 }
#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
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
struct _CLASS_DEVICE_EXTENSION * PCLASS_DEVICE_EXTENSION
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
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:76
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
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1869
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
unsigned short USHORT
Definition: pedump.c:61
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
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:262
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:441
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165
return STATUS_SUCCESS
Definition: btrfs.c:3014
#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 569 of file kbdclass.c.

571 {
572  PPORT_DEVICE_EXTENSION DeviceExtension;
573  PCLASS_DEVICE_EXTENSION ClassDeviceExtension;
575  KEVENT Event;
576  PIRP Irp;
578  KIRQL OldIrql;
580 
581  TRACE_(CLASS_NAME, "Destroying PortDO %p\n", PortDO);
582 
583  DeviceExtension = (PPORT_DEVICE_EXTENSION)PortDO->DeviceExtension;
584  ClassDeviceExtension = DeviceExtension->ClassDO->DeviceExtension;
585  DriverExtension = IoGetDriverObjectExtension(PortDO->DriverObject, PortDO->DriverObject);
586 
587  /* Send IOCTL_INTERNAL_*_DISCONNECT */
591  PortDO,
592  NULL, 0,
593  NULL, 0,
594  TRUE, &Event, &IoStatus);
595  if (Irp)
596  {
597  Status = IoCallDriver(PortDO, Irp);
598  if (Status == STATUS_PENDING)
600  }
601 
602  /* Remove from ClassDeviceExtension->ListHead list */
603  KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql);
604  RemoveEntryList(&DeviceExtension->ListEntry);
605  KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql);
606 
607  /* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
610  DriverExtension->DeviceBaseName.Buffer,
611  ClassDeviceExtension->DeviceName);
612 
613  if (DeviceExtension->LowerDevice)
614  IoDetachDevice(DeviceExtension->LowerDevice);
615  ObDereferenceObject(PortDO);
616 
617  if (!DriverExtension->ConnectMultiplePorts && DeviceExtension->ClassDO)
618  {
619  ExFreePoolWithTag(ClassDeviceExtension->PortData, CLASS_TAG);
620  ExFreePoolWithTag((PVOID)ClassDeviceExtension->DeviceName, CLASS_TAG);
621  IoDeleteDevice(DeviceExtension->ClassDO);
622  }
623 
624  IoDeleteDevice(PortDO);
625 }
#define CLASS_TAG
Definition: kbdclass.h:11
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2659
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
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
#define FALSE
Definition: types.h:117
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define TRACE_(x)
Definition: compat.h:76
#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
Status
Definition: gdiplustypes.h:24
struct _PORT_DEVICE_EXTENSION * PPORT_DEVICE_EXTENSION
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1869
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
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 1037 of file kbdclass.c.

1040 {
1042  NTSTATUS Status;
1043 
1045  DriverObject,
1046  DriverObject,
1047  sizeof(CLASS_DRIVER_EXTENSION),
1048  (PVOID*)&DriverExtension);
1049  if (!NT_SUCCESS(Status))
1050  {
1051  WARN_(CLASS_NAME, "IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status);
1052  return Status;
1053  }
1055 
1058  RegistryPath,
1059  &DriverExtension->RegistryPath);
1060  if (!NT_SUCCESS(Status))
1061  {
1062  WARN_(CLASS_NAME, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status);
1063  return Status;
1064  }
1065 
1067  if (!NT_SUCCESS(Status))
1068  {
1069  WARN_(CLASS_NAME, "ReadRegistryEntries() failed with status 0x%08lx\n", Status);
1070  return Status;
1071  }
1072 
1073  if (DriverExtension->ConnectMultiplePorts == 1)
1074  {
1076  DriverObject,
1077  &DriverExtension->MainClassDeviceObject);
1078  if (!NT_SUCCESS(Status))
1079  {
1080  WARN_(CLASS_NAME, "CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
1081  return Status;
1082  }
1083  }
1084 
1087 
1097 
1098  /* We will detect the legacy devices later */
1100  DriverObject,
1102  DriverExtension);
1103 
1104  return STATUS_SUCCESS;
1105 }
#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:1791
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
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:1762
static NTSTATUS NTAPI ClassPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: kbdclass.c:826
static DRIVER_DISPATCH ClassClose
Definition: kbdclass.c:19
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2262
static VOID NTAPI SearchForLegacyDrivers(IN PDRIVER_OBJECT DriverObject, IN PVOID Context, IN ULONG Count)
Definition: kbdclass.c:919
static NTSTATUS ReadRegistryEntries(IN PUNICODE_STRING RegistryPath, IN PCLASS_DRIVER_EXTENSION DriverExtension)
Definition: kbdclass.c:221
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
static DRIVER_DISPATCH ClassPower
Definition: kbdclass.c:23
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: isapnp.h:82
_In_z_ PWSTR RegistryPath
Definition: classp.h:1930
#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 IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
Status
Definition: gdiplustypes.h:24
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2268
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2200
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:2269
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
PDRIVER_STARTIO DriverStartIo
Definition: iotypes.h:2267
static NTSTATUS CreateClassDeviceObject(IN PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
Definition: kbdclass.c:305
return STATUS_SUCCESS
Definition: btrfs.c:3014
#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 412 of file kbdclass.c.

417 {
419 
420  if (ClassDeviceObject->Flags & DO_BUFFERED_IO)
421  {
423  Irp->AssociatedIrp.SystemBuffer,
424  DataStart,
425  NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
426  }
427  else if (ClassDeviceObject->Flags & DO_DIRECT_IO)
428  {
429  PVOID DestAddress = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
430  if (DestAddress)
431  {
433  DestAddress,
434  DataStart,
435  NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
436  }
437  else
439  }
440  else
441  {
442  _SEH2_TRY
443  {
445  Irp->UserBuffer,
446  DataStart,
447  NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA));
448  }
450  {
452  }
453  _SEH2_END;
454  }
455 
456  return Status;
457 }
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:4226
#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:4400
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by HandleReadIrp().

◆ HandleReadIrp()

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

Definition at line 756 of file kbdclass.c.

760 {
761  PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
763  KIRQL OldIrql;
764 
765  TRACE_(CLASS_NAME, "HandleReadIrp(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
766 
767  ASSERT(DeviceExtension->Common.IsClassDO);
768 
769  if (DeviceExtension->InputCount > 0)
770  {
771  SIZE_T NumberOfEntries;
772 
773  NumberOfEntries = MIN(
774  DeviceExtension->InputCount,
776 
778  DeviceObject,
779  Irp,
780  DeviceExtension->PortData,
781  NumberOfEntries);
782 
783  if (NT_SUCCESS(Status))
784  {
785  if (DeviceExtension->InputCount > NumberOfEntries)
786  {
788  &DeviceExtension->PortData[0],
789  &DeviceExtension->PortData[NumberOfEntries],
790  (DeviceExtension->InputCount - NumberOfEntries) * sizeof(KEYBOARD_INPUT_DATA));
791  }
792 
793  DeviceExtension->InputCount -= NumberOfEntries;
794 
795  Irp->IoStatus.Information = NumberOfEntries * sizeof(KEYBOARD_INPUT_DATA);
796  }
797 
798  /* Go to next packet and complete this request */
799  Irp->IoStatus.Status = Status;
800 
803  DeviceExtension->PendingIrp = NULL;
804  }
805  else
806  {
808  if (Irp->Cancel)
809  {
810  DeviceExtension->PendingIrp = NULL;
812  }
813  else
814  {
816  DeviceExtension->PendingIrp = Irp;
819  }
821  }
822  return Status;
823 }
_In_ PIRP Irp
Definition: csq.h:116
#define IO_KEYBOARD_INCREMENT
Definition: iotypes.h:584
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:264
T MIN(T a, T b)
Definition: polytest.cpp:79
UCHAR KIRQL
Definition: env_spec_w32.h:591
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:76
#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:412
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:887
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define VOID
Definition: acefi.h:82
const TCHAR * CLASS_NAME
Definition: enumwnd.c:16
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
ULONG_PTR SIZE_T
Definition: typedefs.h:80
static DRIVER_CANCEL ClassCancelRoutine
Definition: kbdclass.c:26
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
IoMarkIrpPending(Irp)

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

◆ ReadRegistryEntries()

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

Definition at line 221 of file kbdclass.c.

224 {
225  UNICODE_STRING ParametersRegistryKey;
228 
229  /* HACK: We don't support multiple devices with this disabled */
230  ULONG DefaultConnectMultiplePorts = 1;
231  ULONG DefaultDataQueueSize = 0x64;
232  PCWSTR DefaultDeviceBaseName = L"KeyboardClass";
233 
234  ParametersRegistryKey.Length = 0;
235  ParametersRegistryKey.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(UNICODE_NULL);
236  ParametersRegistryKey.Buffer = ExAllocatePoolWithTag(PagedPool, ParametersRegistryKey.MaximumLength, CLASS_TAG);
237  if (!ParametersRegistryKey.Buffer)
238  {
239  WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
240  return STATUS_NO_MEMORY;
241  }
242  RtlCopyUnicodeString(&ParametersRegistryKey, RegistryPath);
243  RtlAppendUnicodeToString(&ParametersRegistryKey, L"\\Parameters");
244  ParametersRegistryKey.Buffer[ParametersRegistryKey.Length / sizeof(WCHAR)] = UNICODE_NULL;
245 
247 
249  Parameters[0].Name = L"ConnectMultiplePorts";
250  Parameters[0].EntryContext = &DriverExtension->ConnectMultiplePorts;
251  Parameters[0].DefaultType = REG_DWORD;
252  Parameters[0].DefaultData = &DefaultConnectMultiplePorts;
253  Parameters[0].DefaultLength = sizeof(ULONG);
254 
256  Parameters[1].Name = L"KeyboardDataQueueSize";
257  Parameters[1].EntryContext = &DriverExtension->DataQueueSize;
258  Parameters[1].DefaultType = REG_DWORD;
259  Parameters[1].DefaultData = &DefaultDataQueueSize;
260  Parameters[1].DefaultLength = sizeof(ULONG);
261 
263  Parameters[2].Name = L"KeyboardDeviceBaseName";
264  Parameters[2].EntryContext = &DriverExtension->DeviceBaseName;
265  Parameters[2].DefaultType = REG_SZ;
266  Parameters[2].DefaultData = (PVOID)DefaultDeviceBaseName;
267  Parameters[2].DefaultLength = 0;
268 
271  ParametersRegistryKey.Buffer,
272  Parameters,
273  NULL,
274  NULL);
275 
276  if (NT_SUCCESS(Status))
277  {
278  /* Check values */
279  if (DriverExtension->ConnectMultiplePorts != 0
280  && DriverExtension->ConnectMultiplePorts != 1)
281  {
282  DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts;
283  }
284  if (DriverExtension->DataQueueSize == 0)
285  {
286  DriverExtension->DataQueueSize = DefaultDataQueueSize;
287  }
288  }
290  {
291  /* Registry path doesn't exist. Set defaults */
292  DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts;
293  DriverExtension->DataQueueSize = DefaultDataQueueSize;
294  if (RtlCreateUnicodeString(&DriverExtension->DeviceBaseName, DefaultDeviceBaseName))
296  else
298  }
299 
300  ExFreePoolWithTag(ParametersRegistryKey.Buffer, CLASS_TAG);
301  return Status;
302 }
#define CLASS_TAG
Definition: kbdclass.h:11
const uint16_t * PCWSTR
Definition: typedefs.h:57
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
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
_In_z_ PWSTR RegistryPath
Definition: classp.h:1930
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
Status
Definition: gdiplustypes.h:24
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:887
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
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:3014
#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 919 of file kbdclass.c.

923 {
924  UNICODE_STRING DeviceMapKeyU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
926  UNICODE_STRING PortBaseName = { 0, 0, NULL };
927  PKEY_VALUE_BASIC_INFORMATION KeyValueInformation = NULL;
929  HANDLE hDeviceMapKey = (HANDLE)-1;
930  HANDLE hPortKey = (HANDLE)-1;
931  ULONG Index = 0;
934 
935  TRACE_(CLASS_NAME, "SearchForLegacyDrivers(%p %p %lu)\n",
937 
938  if (Count != 1)
939  return;
941 
942  /* Create port base name, by replacing Class by Port at the end of the class base name */
945  &DriverExtension->DeviceBaseName,
946  &PortBaseName);
947  if (!NT_SUCCESS(Status))
948  {
949  WARN_(CLASS_NAME, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status);
950  goto cleanup;
951  }
952  PortBaseName.Length -= (sizeof(L"Class") - sizeof(UNICODE_NULL));
953  RtlAppendUnicodeToString(&PortBaseName, L"Port");
954 
955  /* Allocate memory */
957  KeyValueInformation = ExAllocatePoolWithTag(PagedPool, Size, CLASS_TAG);
958  if (!KeyValueInformation)
959  {
960  WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
962  goto cleanup;
963  }
964 
965  /* Open HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
967  Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
969  {
970  INFO_(CLASS_NAME, "HKLM\\HARDWARE\\DEVICEMAP is non-existent\n");
972  goto cleanup;
973  }
974  else if (!NT_SUCCESS(Status))
975  {
976  WARN_(CLASS_NAME, "ZwOpenKey() failed with status 0x%08lx\n", Status);
977  goto cleanup;
978  }
979 
980  /* Open sub key */
982  Status = ZwOpenKey(&hPortKey, KEY_QUERY_VALUE, &ObjectAttributes);
984  {
985  INFO_(CLASS_NAME, "HKLM\\HARDWARE\\DEVICEMAP\\%wZ is non-existent\n", &PortBaseName);
987  goto cleanup;
988  }
989  else if (!NT_SUCCESS(Status))
990  {
991  WARN_(CLASS_NAME, "ZwOpenKey() failed with status 0x%08lx\n", Status);
992  goto cleanup;
993  }
994 
995  /* Read each value name */
996  while (ZwEnumerateValueKey(hPortKey, Index++, KeyValueBasicInformation, KeyValueInformation, Size, &ResultLength) == STATUS_SUCCESS)
997  {
999  PDEVICE_OBJECT PortDeviceObject = NULL;
1001 
1002  PortName.Length = PortName.MaximumLength = (USHORT)KeyValueInformation->NameLength;
1003  PortName.Buffer = KeyValueInformation->Name;
1004 
1005  /* Open the device object pointer */
1007  if (!NT_SUCCESS(Status))
1008  {
1009  WARN_(CLASS_NAME, "IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", &PortName, Status);
1010  continue;
1011  }
1012  INFO_(CLASS_NAME, "Legacy driver found\n");
1013 
1014  Status = ClassAddDevice(DriverObject, PortDeviceObject);
1015  if (!NT_SUCCESS(Status))
1016  {
1017  /* FIXME: Log the error */
1018  WARN_(CLASS_NAME, "ClassAddDevice() failed with status 0x%08lx\n", Status);
1019  }
1020 
1022  }
1023 
1024 cleanup:
1025  if (KeyValueInformation != NULL)
1026  ExFreePoolWithTag(KeyValueInformation, CLASS_TAG);
1027  if (hDeviceMapKey != (HANDLE)-1)
1028  ZwClose(hDeviceMapKey);
1029  if (hPortKey != (HANDLE)-1)
1030  ZwClose(hPortKey);
1031 }
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
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
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:1223
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 OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
#define TRACE_(x)
Definition: compat.h:76
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: isapnp.h:82
#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:34
static const UCHAR Index[8]
Definition: usbohci.c:18
PVOID HANDLE
Definition: typedefs.h:73
* PFILE_OBJECT
Definition: iotypes.h:1978
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Status
Definition: gdiplustypes.h:24
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:361
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
#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:260
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:3014
#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

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