Revert Kdb and Keyboard strings in name to share more code with mouclass

Fix PORT_DEVICE_EXTENSION and CLASS_DEVICE_EXTENSION structures and use them correctly (PORT_DEVICE_EXTENSION was not used...)
ObDereference DOs when an error occurs, instead of ObReferencing them

svn path=/trunk/; revision=19010
This commit is contained in:
Hervé Poussineau 2005-11-05 08:21:59 +00:00
parent e595cd5c9d
commit cfd5a15157
3 changed files with 136 additions and 116 deletions

View file

@ -20,7 +20,7 @@ DriverUnload(IN PDRIVER_OBJECT DriverObject)
} }
static NTSTATUS NTAPI static NTSTATUS NTAPI
KbdclassCreate( ClassCreate(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
@ -34,7 +34,7 @@ KbdclassCreate(
} }
static NTSTATUS NTAPI static NTSTATUS NTAPI
KbdclassClose( ClassClose(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
@ -48,7 +48,7 @@ KbdclassClose(
} }
static NTSTATUS NTAPI static NTSTATUS NTAPI
KbdclassCleanup( ClassCleanup(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
@ -57,12 +57,12 @@ KbdclassCleanup(
if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO) if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
return ForwardIrpAndForget(DeviceObject, Irp); return ForwardIrpAndForget(DeviceObject, Irp);
/* FIXME: close all associated Port devices */ /* FIXME: cleanup all associated Port devices */
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS NTAPI static NTSTATUS NTAPI
KbdclassRead( ClassRead(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
@ -86,10 +86,11 @@ KbdclassRead(
} }
static NTSTATUS NTAPI static NTSTATUS NTAPI
KbdclassDeviceControl( ClassDeviceControl(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
PCLASS_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status; NTSTATUS Status;
DPRINT("IRP_MJ_DEVICE_CONTROL\n"); DPRINT("IRP_MJ_DEVICE_CONTROL\n");
@ -97,6 +98,8 @@ KbdclassDeviceControl(
if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO) if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO)
return ForwardIrpAndForget(DeviceObject, Irp); return ForwardIrpAndForget(DeviceObject, Irp);
DeviceExtension = (PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
switch (IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode) switch (IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode)
{ {
case IOCTL_KEYBOARD_QUERY_ATTRIBUTES: case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
@ -160,15 +163,15 @@ IrpStub(
static NTSTATUS static NTSTATUS
ReadRegistryEntries( ReadRegistryEntries(
IN PUNICODE_STRING RegistryPath, IN PUNICODE_STRING RegistryPath,
IN PKBDCLASS_DRIVER_EXTENSION DriverExtension) IN PCLASS_DRIVER_EXTENSION DriverExtension)
{ {
UNICODE_STRING ParametersRegistryKey; UNICODE_STRING ParametersRegistryKey;
RTL_QUERY_REGISTRY_TABLE Parameters[4]; RTL_QUERY_REGISTRY_TABLE Parameters[4];
NTSTATUS Status; NTSTATUS Status;
ULONG DefaultConnectMultiplePorts = 1; ULONG DefaultConnectMultiplePorts = 0;
ULONG DefaultKeyboardDataQueueSize = 0x64; ULONG DefaultDataQueueSize = 0x64;
UNICODE_STRING DefaultKeyboardDeviceBaseName = RTL_CONSTANT_STRING(L"KeyboardClass"); UNICODE_STRING DefaultDeviceBaseName = RTL_CONSTANT_STRING(L"KeyboardClass");
ParametersRegistryKey.Length = 0; ParametersRegistryKey.Length = 0;
ParametersRegistryKey.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(UNICODE_NULL); ParametersRegistryKey.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(UNICODE_NULL);
@ -193,16 +196,16 @@ ReadRegistryEntries(
Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[1].Name = L"KeyboardDataQueueSize"; Parameters[1].Name = L"KeyboardDataQueueSize";
Parameters[1].EntryContext = &DriverExtension->KeyboardDataQueueSize; Parameters[1].EntryContext = &DriverExtension->DataQueueSize;
Parameters[1].DefaultType = REG_DWORD; Parameters[1].DefaultType = REG_DWORD;
Parameters[1].DefaultData = &DefaultKeyboardDataQueueSize; Parameters[1].DefaultData = &DefaultDataQueueSize;
Parameters[1].DefaultLength = sizeof(ULONG); Parameters[1].DefaultLength = sizeof(ULONG);
Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[2].Name = L"KeyboardDeviceBaseName"; Parameters[2].Name = L"KeyboardDeviceBaseName";
Parameters[2].EntryContext = &DriverExtension->KeyboardDeviceBaseName; Parameters[2].EntryContext = &DriverExtension->DeviceBaseName;
Parameters[2].DefaultType = REG_SZ; Parameters[2].DefaultType = REG_SZ;
Parameters[2].DefaultData = &DefaultKeyboardDeviceBaseName; Parameters[2].DefaultData = &DefaultDeviceBaseName;
Parameters[2].DefaultLength = sizeof(ULONG); Parameters[2].DefaultLength = sizeof(ULONG);
Status = RtlQueryRegistryValues( Status = RtlQueryRegistryValues(
@ -220,50 +223,50 @@ ReadRegistryEntries(
{ {
DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts; DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts;
} }
if (DriverExtension->KeyboardDataQueueSize == 0) if (DriverExtension->DataQueueSize == 0)
{ {
DriverExtension->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; DriverExtension->DataQueueSize = DefaultDataQueueSize;
} }
} }
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{ {
/* Registry path doesn't exist. Set defaults */ /* Registry path doesn't exist. Set defaults */
DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts; DriverExtension->ConnectMultiplePorts = DefaultConnectMultiplePorts;
DriverExtension->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; DriverExtension->DataQueueSize = DefaultDataQueueSize;
Status = RtlDuplicateUnicodeString( Status = RtlDuplicateUnicodeString(
RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
&DefaultKeyboardDeviceBaseName, &DefaultDeviceBaseName,
&DriverExtension->KeyboardDeviceBaseName); &DriverExtension->DeviceBaseName);
} }
return Status; return Status;
} }
static NTSTATUS static NTSTATUS
CreateKeyboardClassDeviceObject( CreateClassDeviceObject(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
OUT PDEVICE_OBJECT *ClassDO OPTIONAL) OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
{ {
PKBDCLASS_DRIVER_EXTENSION DriverExtension; PCLASS_DRIVER_EXTENSION DriverExtension;
UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\Keyboard"); UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\Keyboard");
ULONG DeviceId = 0; ULONG DeviceId = 0;
ULONG PrefixLength; ULONG PrefixLength;
UNICODE_STRING DeviceNameU; UNICODE_STRING DeviceNameU;
PWSTR DeviceIdW = NULL; /* Pointer into DeviceNameU.Buffer */ PWSTR DeviceIdW = NULL; /* Pointer into DeviceNameU.Buffer */
PDEVICE_OBJECT Fdo; PDEVICE_OBJECT Fdo;
PKBDCLASS_DEVICE_EXTENSION DeviceExtension; PCLASS_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status; NTSTATUS Status;
DPRINT("CreateKeyboardClassDeviceObject(0x%p)\n", DriverObject); DPRINT("CreateClassDeviceObject(0x%p)\n", DriverObject);
/* Create new device object */ /* Create new device object */
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject); DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
DeviceNameU.Length = 0; DeviceNameU.Length = 0;
DeviceNameU.MaximumLength = DeviceNameU.MaximumLength =
wcslen(L"\\Device\\") * sizeof(WCHAR) /* "\Device\" */ wcslen(L"\\Device\\") * sizeof(WCHAR) /* "\Device\" */
+ DriverExtension->KeyboardDeviceBaseName.Length/* "KeyboardClass" */ + DriverExtension->DeviceBaseName.Length /* "KeyboardClass" */
+ 4 * sizeof(WCHAR) /* Id between 0 and 9999 */ + 4 * sizeof(WCHAR) /* Id between 0 and 9999 */
+ sizeof(UNICODE_NULL); /* Final NULL char */ + sizeof(UNICODE_NULL); /* Final NULL char */
DeviceNameU.Buffer = ExAllocatePool(PagedPool, DeviceNameU.MaximumLength); DeviceNameU.Buffer = ExAllocatePool(PagedPool, DeviceNameU.MaximumLength);
if (!DeviceNameU.Buffer) if (!DeviceNameU.Buffer)
{ {
@ -276,7 +279,7 @@ CreateKeyboardClassDeviceObject(
DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status); DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
} }
Status = RtlAppendUnicodeStringToString(&DeviceNameU, &DriverExtension->KeyboardDeviceBaseName); Status = RtlAppendUnicodeStringToString(&DeviceNameU, &DriverExtension->DeviceBaseName);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status); DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
@ -289,7 +292,7 @@ CreateKeyboardClassDeviceObject(
DeviceNameU.Length = PrefixLength + swprintf(DeviceIdW, L"%lu", DeviceId) * sizeof(WCHAR); DeviceNameU.Length = PrefixLength + swprintf(DeviceIdW, L"%lu", DeviceId) * sizeof(WCHAR);
Status = IoCreateDevice( Status = IoCreateDevice(
DriverObject, DriverObject,
sizeof(KBDCLASS_DEVICE_EXTENSION), sizeof(CLASS_DEVICE_EXTENSION),
&DeviceNameU, &DeviceNameU,
FILE_DEVICE_KEYBOARD, FILE_DEVICE_KEYBOARD,
FILE_DEVICE_SECURE_OPEN, FILE_DEVICE_SECURE_OPEN,
@ -304,7 +307,7 @@ CreateKeyboardClassDeviceObject(
} }
DeviceId++; DeviceId++;
} }
DPRINT("Too much devices starting with '\\Device\\%wZ'\n", &DriverExtension->KeyboardDeviceBaseName); DPRINT("Too much devices starting with '\\Device\\%wZ'\n", &DriverExtension->DeviceBaseName);
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
cleanup: cleanup:
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -313,15 +316,14 @@ cleanup:
return Status; return Status;
} }
DeviceExtension = (PKBDCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension; DeviceExtension = (PCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(KBDCLASS_DEVICE_EXTENSION)); RtlZeroMemory(DeviceExtension, sizeof(CLASS_DEVICE_EXTENSION));
DeviceExtension->Common.IsClassDO = TRUE; DeviceExtension->Common.IsClassDO = TRUE;
DeviceExtension->DriverExtension = DriverExtension; DeviceExtension->DriverExtension = DriverExtension;
DeviceExtension->PnpState = dsStopped;
KeInitializeSpinLock(&(DeviceExtension->SpinLock)); KeInitializeSpinLock(&(DeviceExtension->SpinLock));
DeviceExtension->ReadIsPending = FALSE; DeviceExtension->ReadIsPending = FALSE;
DeviceExtension->InputCount = 0; DeviceExtension->InputCount = 0;
DeviceExtension->PortData = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->KeyboardDataQueueSize * sizeof(KEYBOARD_INPUT_DATA)); DeviceExtension->PortData = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->DataQueueSize * sizeof(KEYBOARD_INPUT_DATA));
Fdo->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO; Fdo->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO;
Fdo->Flags &= ~DO_DEVICE_INITIALIZING; Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
@ -340,22 +342,22 @@ cleanup:
} }
static BOOLEAN static BOOLEAN
KbdclassCallback( ClassCallback(
IN PDEVICE_OBJECT ClassDeviceObject, IN PDEVICE_OBJECT ClassDeviceObject,
IN OUT PKEYBOARD_INPUT_DATA KeyboardDataStart, IN OUT PKEYBOARD_INPUT_DATA DataStart,
IN PKEYBOARD_INPUT_DATA KeyboardDataEnd, IN PKEYBOARD_INPUT_DATA DataEnd,
IN OUT PULONG ConsumedCount) IN OUT PULONG ConsumedCount)
{ {
PKBDCLASS_DEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension; PCLASS_DEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
PIRP Irp = NULL; PIRP Irp = NULL;
KIRQL OldIrql; KIRQL OldIrql;
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
ULONG InputCount = KeyboardDataEnd - KeyboardDataStart; ULONG InputCount = DataEnd - DataStart;
ULONG ReadSize; ULONG ReadSize;
ASSERT(ClassDeviceExtension->Common.IsClassDO); ASSERT(ClassDeviceExtension->Common.IsClassDO);
DPRINT("KbdclassCallback()\n"); DPRINT("ClassCallback()\n");
/* A filter driver might have consumed all the data already; I'm /* A filter driver might have consumed all the data already; I'm
* not sure if they are supposed to move the packets when they * not sure if they are supposed to move the packets when they
* consume them though. * consume them though.
@ -370,7 +372,7 @@ KbdclassCallback(
/* FIXME: use SEH */ /* FIXME: use SEH */
RtlCopyMemory( RtlCopyMemory(
Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->AssociatedIrp.SystemBuffer, Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->AssociatedIrp.SystemBuffer,
KeyboardDataStart, DataStart,
sizeof(KEYBOARD_INPUT_DATA)); sizeof(KEYBOARD_INPUT_DATA));
/* Go to next packet and complete this request with STATUS_SUCCESS */ /* Go to next packet and complete this request with STATUS_SUCCESS */
@ -381,7 +383,7 @@ KbdclassCallback(
ClassDeviceExtension->ReadIsPending = FALSE; ClassDeviceExtension->ReadIsPending = FALSE;
/* Skip the packet we just sent away */ /* Skip the packet we just sent away */
KeyboardDataStart++; DataStart++;
(*ConsumedCount)++; (*ConsumedCount)++;
InputCount--; InputCount--;
} }
@ -391,23 +393,23 @@ KbdclassCallback(
{ {
KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql); KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql);
if (ClassDeviceExtension->InputCount + InputCount > ClassDeviceExtension->DriverExtension->KeyboardDataQueueSize) if (ClassDeviceExtension->InputCount + InputCount > ClassDeviceExtension->DriverExtension->DataQueueSize)
ReadSize = ClassDeviceExtension->DriverExtension->KeyboardDataQueueSize - ClassDeviceExtension->InputCount; ReadSize = ClassDeviceExtension->DriverExtension->DataQueueSize - ClassDeviceExtension->InputCount;
else else
ReadSize = InputCount; ReadSize = InputCount;
/* /*
* FIXME: If we exceed the buffer, keyboard data gets thrown away.. better * FIXME: If we exceed the buffer, data gets thrown away.. better
* solution? * solution?
*/ */
/* /*
* Move the keyboard input data from the port data queue to our class data * Move the input data from the port data queue to our class data
* queue. * queue.
*/ */
RtlMoveMemory( RtlMoveMemory(
ClassDeviceExtension->PortData, ClassDeviceExtension->PortData,
(PCHAR)KeyboardDataStart, (PCHAR)DataStart,
sizeof(KEYBOARD_INPUT_DATA) * ReadSize); sizeof(KEYBOARD_INPUT_DATA) * ReadSize);
/* Move the pointer and counter up */ /* Move the pointer and counter up */
@ -419,7 +421,7 @@ KbdclassCallback(
} }
else else
{ {
DPRINT("KbdclassCallBack() entered, InputCount = %lu - DOING NOTHING\n", InputCount); DPRINT("ClassCallBack() entered, InputCount = %lu - DOING NOTHING\n", InputCount);
} }
if (Irp != NULL) if (Irp != NULL)
@ -428,15 +430,15 @@ KbdclassCallback(
IoCompleteRequest(Irp, IO_KEYBOARD_INCREMENT); IoCompleteRequest(Irp, IO_KEYBOARD_INCREMENT);
} }
DPRINT("Leaving KbdclassCallback()\n"); DPRINT("Leaving ClassCallback()\n");
return TRUE; return TRUE;
} }
/* Send IOCTL_INTERNAL_KEYBOARD_CONNECT to keyboard port */ /* Send IOCTL_INTERNAL_*_CONNECT to port */
static NTSTATUS static NTSTATUS
ConnectKeyboardPortDriver( ConnectPortDriver(
IN PDEVICE_OBJECT KeyboardPortDO, IN PDEVICE_OBJECT PortDO,
IN PDEVICE_OBJECT KeyboardClassDO) IN PDEVICE_OBJECT ClassDO)
{ {
KEVENT Event; KEVENT Event;
PIRP Irp; PIRP Irp;
@ -446,16 +448,16 @@ ConnectKeyboardPortDriver(
KeInitializeEvent(&Event, NotificationEvent, FALSE); KeInitializeEvent(&Event, NotificationEvent, FALSE);
ConnectData.ClassDeviceObject = KeyboardClassDO; ConnectData.ClassDeviceObject = ClassDO;
ConnectData.ClassService = KbdclassCallback; ConnectData.ClassService = ClassCallback;
Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_KEYBOARD_CONNECT, Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_KEYBOARD_CONNECT,
KeyboardPortDO, PortDO,
&ConnectData, sizeof(CONNECT_DATA), &ConnectData, sizeof(CONNECT_DATA),
NULL, 0, NULL, 0,
TRUE, &Event, &IoStatus); TRUE, &Event, &IoStatus);
Status = IoCallDriver(KeyboardPortDO, Irp); Status = IoCallDriver(PortDO, Irp);
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
@ -463,29 +465,29 @@ ConnectKeyboardPortDriver(
IoStatus.Status = Status; IoStatus.Status = Status;
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
ObReferenceObject(KeyboardPortDO); ObReferenceObject(PortDO);
return IoStatus.Status; return IoStatus.Status;
} }
static NTSTATUS NTAPI static NTSTATUS NTAPI
KbdclassAddDevice( ClassAddDevice(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo) IN PDEVICE_OBJECT Pdo)
{ {
PKBDCLASS_DRIVER_EXTENSION DriverExtension; PCLASS_DRIVER_EXTENSION DriverExtension;
PDEVICE_OBJECT Fdo; PDEVICE_OBJECT Fdo;
PKBDCLASS_DEVICE_EXTENSION DeviceExtension; PPORT_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status; NTSTATUS Status;
DPRINT("KbdclassAddDevice called. Pdo = 0x%p\n", Pdo); DPRINT("ClassAddDevice called. Pdo = 0x%p\n", Pdo);
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject); DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
/* Create new device object */ /* Create new device object */
Status = IoCreateDevice( Status = IoCreateDevice(
DriverObject, DriverObject,
sizeof(KBDCLASS_DEVICE_EXTENSION), sizeof(PORT_DEVICE_EXTENSION),
NULL, NULL,
Pdo->DeviceType, Pdo->DeviceType,
FILE_DEVICE_SECURE_OPEN, FILE_DEVICE_SECURE_OPEN,
@ -497,8 +499,8 @@ KbdclassAddDevice(
return Status; return Status;
} }
DeviceExtension = (PKBDCLASS_DEVICE_EXTENSION)Fdo->DeviceExtension; DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(KBDCLASS_DEVICE_EXTENSION)); RtlZeroMemory(DeviceExtension, sizeof(CLASS_DEVICE_EXTENSION));
DeviceExtension->Common.IsClassDO = FALSE; DeviceExtension->Common.IsClassDO = FALSE;
DeviceExtension->PnpState = dsStopped; DeviceExtension->PnpState = dsStopped;
Fdo->Flags |= DO_POWER_PAGABLE; Fdo->Flags |= DO_POWER_PAGABLE;
@ -512,12 +514,12 @@ KbdclassAddDevice(
Fdo->Flags |= DO_BUFFERED_IO; Fdo->Flags |= DO_BUFFERED_IO;
if (DriverExtension->ConnectMultiplePorts) if (DriverExtension->ConnectMultiplePorts)
Status = ConnectKeyboardPortDriver(Fdo, DriverExtension->MainKbdclassDeviceObject); Status = ConnectPortDriver(Fdo, DriverExtension->MainClassDeviceObject);
else else
Status = ConnectKeyboardPortDriver(Fdo, Fdo); Status = ConnectPortDriver(Fdo, Fdo);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("ConnectKeyboardPortDriver() failed with status 0x%08lx\n", Status); DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
IoDetachDevice(DeviceExtension->LowerDevice); IoDetachDevice(DeviceExtension->LowerDevice);
/* FIXME: why can't I cleanup without error? */ /* FIXME: why can't I cleanup without error? */
//IoDeleteDevice(Fdo); //IoDeleteDevice(Fdo);
@ -525,12 +527,12 @@ KbdclassAddDevice(
} }
Fdo->Flags &= ~DO_DEVICE_INITIALIZING; Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
/* Register GUID_DEVINTERFACE_KEYBOARD interface */ /* Register interface */
Status = IoRegisterDeviceInterface( Status = IoRegisterDeviceInterface(
Pdo, Pdo,
&GUID_DEVINTERFACE_KEYBOARD, &GUID_DEVINTERFACE_KEYBOARD,
NULL, NULL,
&DeviceExtension->KeyboardInterfaceName); &DeviceExtension->InterfaceName);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status); DPRINT("IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
@ -541,11 +543,11 @@ KbdclassAddDevice(
} }
static VOID NTAPI static VOID NTAPI
KbdclassStartIo( ClassStartIo(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
PKBDCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; PCLASS_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
ASSERT(DeviceExtension->Common.IsClassDO); ASSERT(DeviceExtension->Common.IsClassDO);
@ -591,7 +593,7 @@ KbdclassStartIo(
static NTSTATUS static NTSTATUS
SearchForLegacyDrivers( SearchForLegacyDrivers(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
IN PKBDCLASS_DRIVER_EXTENSION DriverExtension) IN PCLASS_DRIVER_EXTENSION DriverExtension)
{ {
UNICODE_STRING DeviceMapKeyU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP"); UNICODE_STRING DeviceMapKeyU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
UNICODE_STRING PortBaseName = {0, }; UNICODE_STRING PortBaseName = {0, };
@ -606,7 +608,7 @@ SearchForLegacyDrivers(
/* Create port base name, by replacing Class by Port at the end of the class base name */ /* Create port base name, by replacing Class by Port at the end of the class base name */
Status = RtlDuplicateUnicodeString( Status = RtlDuplicateUnicodeString(
RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
&DriverExtension->KeyboardDeviceBaseName, &DriverExtension->DeviceBaseName,
&PortBaseName); &PortBaseName);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -629,7 +631,13 @@ SearchForLegacyDrivers(
/* Open HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */ /* Open HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP */
InitializeObjectAttributes(&ObjectAttributes, &DeviceMapKeyU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); InitializeObjectAttributes(&ObjectAttributes, &DeviceMapKeyU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes); Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
if (!NT_SUCCESS(Status)) if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{
DPRINT("HKLM\\HARDWARE\\DEVICEMAP is non-existent\n");
Status = STATUS_SUCCESS;
goto cleanup;
}
else if (!NT_SUCCESS(Status))
{ {
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
@ -638,10 +646,15 @@ SearchForLegacyDrivers(
/* Open sub key */ /* Open sub key */
InitializeObjectAttributes(&ObjectAttributes, &PortBaseName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hDeviceMapKey, NULL); InitializeObjectAttributes(&ObjectAttributes, &PortBaseName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hDeviceMapKey, NULL);
Status = ZwOpenKey(&hPortKey, KEY_QUERY_VALUE, &ObjectAttributes); Status = ZwOpenKey(&hPortKey, KEY_QUERY_VALUE, &ObjectAttributes);
if (!NT_SUCCESS(Status)) if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{
DPRINT("HKLM\\HARDWARE\\DEVICEMAP\\%wZ is non-existent\n", &PortBaseName);
Status = STATUS_SUCCESS;
goto cleanup;
}
else if (!NT_SUCCESS(Status))
{ {
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status); DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
} }
@ -665,31 +678,31 @@ SearchForLegacyDrivers(
/* Connect the port device object */ /* Connect the port device object */
if (DriverExtension->ConnectMultiplePorts) if (DriverExtension->ConnectMultiplePorts)
{ {
Status = ConnectKeyboardPortDriver(PortDeviceObject, DriverExtension->MainKbdclassDeviceObject); Status = ConnectPortDriver(PortDeviceObject, DriverExtension->MainClassDeviceObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* FIXME: Log the error */ /* FIXME: Log the error */
DPRINT("ConnectKeyboardPortDriver() failed with status 0x%08lx\n", Status); DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
ObReferenceObject(PortDeviceObject); ObDereferenceObject(PortDeviceObject);
} }
} }
else else
{ {
PDEVICE_OBJECT ClassDO; PDEVICE_OBJECT ClassDO;
Status = CreateKeyboardClassDeviceObject(DriverObject, &ClassDO); Status = CreateClassDeviceObject(DriverObject, &ClassDO);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* FIXME: Log the error */ /* FIXME: Log the error */
DPRINT("CreatePointerClassDeviceObject() failed with status 0x%08lx\n", Status); DPRINT("CreatePointerClassDeviceObject() failed with status 0x%08lx\n", Status);
ObReferenceObject(PortDeviceObject); ObDereferenceObject(PortDeviceObject);
continue; continue;
} }
Status = ConnectKeyboardPortDriver(PortDeviceObject, ClassDO); Status = ConnectPortDriver(PortDeviceObject, ClassDO);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* FIXME: Log the error */ /* FIXME: Log the error */
DPRINT("ConnectKeyboardPortDriver() failed with status 0x%08lx\n", Status); DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
ObReferenceObject(PortDeviceObject); ObDereferenceObject(PortDeviceObject);
IoDeleteDevice(ClassDO); IoDeleteDevice(ClassDO);
} }
} }
@ -715,21 +728,21 @@ DriverEntry(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath) IN PUNICODE_STRING RegistryPath)
{ {
PKBDCLASS_DRIVER_EXTENSION DriverExtension; PCLASS_DRIVER_EXTENSION DriverExtension;
ULONG i; ULONG i;
NTSTATUS Status; NTSTATUS Status;
Status = IoAllocateDriverObjectExtension( Status = IoAllocateDriverObjectExtension(
DriverObject, DriverObject,
DriverObject, DriverObject,
sizeof(KBDCLASS_DRIVER_EXTENSION), sizeof(CLASS_DRIVER_EXTENSION),
(PVOID*)&DriverExtension); (PVOID*)&DriverExtension);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status); DPRINT("IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status);
return Status; return Status;
} }
RtlZeroMemory(DriverExtension, sizeof(KBDCLASS_DRIVER_EXTENSION)); RtlZeroMemory(DriverExtension, sizeof(CLASS_DRIVER_EXTENSION));
Status = ReadRegistryEntries(RegistryPath, DriverExtension); Status = ReadRegistryEntries(RegistryPath, DriverExtension);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -740,28 +753,28 @@ DriverEntry(
if (DriverExtension->ConnectMultiplePorts == 1) if (DriverExtension->ConnectMultiplePorts == 1)
{ {
Status = CreateKeyboardClassDeviceObject( Status = CreateClassDeviceObject(
DriverObject, DriverObject,
&DriverExtension->MainKbdclassDeviceObject); &DriverExtension->MainClassDeviceObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("CreateKeyboardClassDeviceObject() failed with status 0x%08lx\n", Status); DPRINT("CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
return Status; return Status;
} }
} }
DriverObject->DriverExtension->AddDevice = KbdclassAddDevice; DriverObject->DriverExtension->AddDevice = ClassAddDevice;
DriverObject->DriverUnload = DriverUnload; DriverObject->DriverUnload = DriverUnload;
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction[i] = IrpStub; DriverObject->MajorFunction[i] = IrpStub;
DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdclassCreate; DriverObject->MajorFunction[IRP_MJ_CREATE] = ClassCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdclassClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = ClassClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = KbdclassCleanup; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = ClassCleanup;
DriverObject->MajorFunction[IRP_MJ_READ] = KbdclassRead; DriverObject->MajorFunction[IRP_MJ_READ] = ClassRead;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KbdclassDeviceControl; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ClassDeviceControl;
DriverObject->DriverStartIo = KbdclassStartIo; DriverObject->DriverStartIo = ClassStartIo;
Status = SearchForLegacyDrivers(DriverObject, DriverExtension); Status = SearchForLegacyDrivers(DriverObject, DriverExtension);

View file

@ -20,42 +20,43 @@ typedef enum
dsPaused, dsPaused,
dsRemoved, dsRemoved,
dsSurpriseRemoved dsSurpriseRemoved
} KBDCLASS_DEVICE_STATE; } PORT_DEVICE_STATE;
typedef struct _KBDCLASS_DRIVER_EXTENSION typedef struct _CLASS_DRIVER_EXTENSION
{ {
/* Registry settings */ /* Registry settings */
ULONG ConnectMultiplePorts; ULONG ConnectMultiplePorts;
ULONG KeyboardDataQueueSize; ULONG DataQueueSize;
UNICODE_STRING KeyboardDeviceBaseName; UNICODE_STRING DeviceBaseName;
PDEVICE_OBJECT MainKbdclassDeviceObject; PDEVICE_OBJECT MainClassDeviceObject;
} KBDCLASS_DRIVER_EXTENSION, *PKBDCLASS_DRIVER_EXTENSION; } CLASS_DRIVER_EXTENSION, *PCLASS_DRIVER_EXTENSION;
typedef struct _COMMON_DEVICE_EXTENSION typedef struct _COMMON_DEVICE_EXTENSION
{ {
BOOLEAN IsClassDO; BOOLEAN IsClassDO;
} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION; } COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
typedef struct _KBDPORT_DEVICE_EXTENSION typedef struct _PORT_DEVICE_EXTENSION
{
COMMON_DEVICE_EXTENSION Common;
} KBDPORT_DEVICE_EXTENSION, *PKBDPORT_DEVICE_EXTENSION;
typedef struct _KBDCLASS_DEVICE_EXTENSION
{ {
COMMON_DEVICE_EXTENSION Common; COMMON_DEVICE_EXTENSION Common;
KBDCLASS_DEVICE_STATE PnpState; PORT_DEVICE_STATE PnpState;
PKBDCLASS_DRIVER_EXTENSION DriverExtension;
PDEVICE_OBJECT LowerDevice; PDEVICE_OBJECT LowerDevice;
UNICODE_STRING KeyboardInterfaceName; UNICODE_STRING InterfaceName;
} PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION;
typedef struct _CLASS_DEVICE_EXTENSION
{
COMMON_DEVICE_EXTENSION Common;
PCLASS_DRIVER_EXTENSION DriverExtension;
KSPIN_LOCK SpinLock; KSPIN_LOCK SpinLock;
BOOLEAN ReadIsPending; BOOLEAN ReadIsPending;
ULONG InputCount; ULONG InputCount;
PKEYBOARD_INPUT_DATA PortData; PKEYBOARD_INPUT_DATA PortData;
} KBDCLASS_DEVICE_EXTENSION, *PKBDCLASS_DEVICE_EXTENSION; } CLASS_DEVICE_EXTENSION, *PCLASS_DEVICE_EXTENSION;
/* misc.c */ /* misc.c */

View file

@ -28,10 +28,13 @@ ForwardIrpAndWait(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
PDEVICE_OBJECT LowerDevice = ((PKBDCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; PDEVICE_OBJECT LowerDevice;
KEVENT Event; KEVENT Event;
NTSTATUS Status; NTSTATUS Status;
ASSERT(!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO);
LowerDevice = ((PPORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
KeInitializeEvent(&Event, NotificationEvent, FALSE); KeInitializeEvent(&Event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp); IoCopyCurrentIrpStackLocationToNext(Irp);
@ -54,7 +57,10 @@ ForwardIrpAndForget(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
PDEVICE_OBJECT LowerDevice = ((PKBDCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; PDEVICE_OBJECT LowerDevice;
ASSERT(!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO);
LowerDevice = ((PPORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
IoSkipCurrentIrpStackLocation(Irp); IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(LowerDevice, Irp); return IoCallDriver(LowerDevice, Irp);