Author: hpoussin Date: Wed Apr 26 02:22:22 2006 New Revision: 21741
URL: http://svn.reactos.ru/svn/reactos?rev=21741&view=rev Log: Complete IRP_MJ_CREATE, IRP_MJ_CLOSE, IRP_MJ_CLEANUP Use correct buffer when filling read request. Use SEH when needed Correctly propagate DO_BUFFERED_IO, DO_DIRECT_IO and FILE_DEVICE_SECURE_OPEN flags
Modified: trunk/reactos/drivers/input/kbdclass/kbdclass.c trunk/reactos/drivers/input/kbdclass/kbdclass.h trunk/reactos/drivers/input/kbdclass/kbdclass.rbuild trunk/reactos/drivers/input/mouclass/mouclass.c trunk/reactos/drivers/input/mouclass/mouclass.h trunk/reactos/drivers/input/mouclass/mouclass.rbuild
Modified: trunk/reactos/drivers/input/kbdclass/kbdclass.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/drivers/input/kbdclass/kbdcl... ============================================================================== --- trunk/reactos/drivers/input/kbdclass/kbdclass.c (original) +++ trunk/reactos/drivers/input/kbdclass/kbdclass.c Wed Apr 26 02:22:22 2006 @@ -35,6 +35,9 @@ return ForwardIrpAndForget(DeviceObject, Irp);
/* FIXME: open all associated Port devices */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
@@ -49,6 +52,9 @@ return ForwardIrpAndForget(DeviceObject, Irp);
/* FIXME: close all associated Port devices */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
@@ -63,6 +69,9 @@ return ForwardIrpAndForget(DeviceObject, Irp);
/* FIXME: cleanup all associated Port devices */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
@@ -361,7 +370,8 @@ DeviceExtension->ReadIsPending = FALSE; DeviceExtension->InputCount = 0; DeviceExtension->PortData = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->DataQueueSize * sizeof(KEYBOARD_INPUT_DATA)); - Fdo->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO; + Fdo->Flags |= DO_POWER_PAGABLE; + Fdo->Flags |= DO_BUFFERED_IO; /* FIXME: Why is it needed for 1st stage setup? */ Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
/* Add entry entry to HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP[DeviceBaseName] */ @@ -381,6 +391,53 @@ return STATUS_SUCCESS; }
+static NTSTATUS +FillOneEntry( + IN PDEVICE_OBJECT ClassDeviceObject, + IN PIRP Irp, + IN PKEYBOARD_INPUT_DATA DataStart) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (ClassDeviceObject->Flags & DO_BUFFERED_IO) + { + RtlCopyMemory( + Irp->AssociatedIrp.SystemBuffer, + DataStart, + sizeof(KEYBOARD_INPUT_DATA)); + } + else if (ClassDeviceObject->Flags & DO_DIRECT_IO) + { + PVOID DestAddress = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); + if (DestAddress) + { + RtlCopyMemory( + DestAddress, + DataStart, + sizeof(KEYBOARD_INPUT_DATA)); + } + else + Status = STATUS_UNSUCCESSFUL; + } + else + { + _SEH_TRY + { + RtlCopyMemory( + Irp->UserBuffer, + DataStart, + sizeof(KEYBOARD_INPUT_DATA)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + + return Status; +} + static BOOLEAN ClassCallback( IN PDEVICE_OBJECT ClassDeviceObject, @@ -406,28 +463,32 @@ */ if (ClassDeviceExtension->ReadIsPending == TRUE && InputCount) { + NTSTATUS Status; + Irp = ClassDeviceObject->CurrentIrp; ClassDeviceObject->CurrentIrp = NULL; Stack = IoGetCurrentIrpStackLocation(Irp);
/* A read request is waiting for input, so go straight to it */ - /* FIXME: use SEH */ - RtlCopyMemory( - Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->AssociatedIrp.SystemBuffer, - DataStart, - sizeof(KEYBOARD_INPUT_DATA)); - - /* Go to next packet and complete this request with STATUS_SUCCESS */ - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA); - Stack->Parameters.Read.Length = sizeof(KEYBOARD_INPUT_DATA); - - ClassDeviceExtension->ReadIsPending = FALSE; - - /* Skip the packet we just sent away */ - DataStart++; - (*ConsumedCount)++; - InputCount--; + Status = FillOneEntry( + ClassDeviceObject, + Irp, + DataStart); + + if (NT_SUCCESS(Status)) + { + /* Go to next packet and complete this request with STATUS_SUCCESS */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA); + Stack->Parameters.Read.Length = sizeof(KEYBOARD_INPUT_DATA); + + ClassDeviceExtension->ReadIsPending = FALSE; + + /* Skip the packet we just sent away */ + DataStart++; + (*ConsumedCount)++; + InputCount--; + } }
/* If we have data from the port driver and a higher service to send the data to */ @@ -439,9 +500,11 @@ ReadSize = InputCount;
/* - * FIXME: If we exceed the buffer, data gets thrown away.. better - * solution? - */ + * If we exceed the buffer, data gets thrown away... + * Try at least to display a dialog + */ + if (Irp != NULL) + IoRaiseHardError(Irp, NULL, ClassDeviceObject);
/* * Move the input data from the port data queue to our class data @@ -549,7 +612,7 @@ sizeof(PORT_DEVICE_EXTENSION), NULL, Pdo->DeviceType, - FILE_DEVICE_SECURE_OPEN, + Pdo->Characteristics & FILE_DEVICE_SECURE_OPEN ? FILE_DEVICE_SECURE_OPEN : 0, TRUE, &Fdo); if (!NT_SUCCESS(Status)) @@ -573,6 +636,8 @@ Fdo->Flags |= DO_POWER_PAGABLE; if (DeviceExtension->LowerDevice->Flags & DO_BUFFERED_IO) Fdo->Flags |= DO_BUFFERED_IO; + if (DeviceExtension->LowerDevice->Flags & DO_DIRECT_IO) + Fdo->Flags |= DO_DIRECT_IO;
if (DriverExtension->ConnectMultiplePorts) DeviceExtension->ClassDO = DriverExtension->MainClassDeviceObject; @@ -646,35 +711,35 @@ if (DeviceExtension->InputCount > 0) { KIRQL oldIrql; + NTSTATUS Status;
KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql);
- DPRINT("Mdl: %p, UserBuffer: %p, InputCount: %lu\n", - Irp->MdlAddress, - Irp->UserBuffer, - DeviceExtension->InputCount); - - /* FIXME: use SEH */ - RtlCopyMemory( - Irp->AssociatedIrp.SystemBuffer, - DeviceExtension->PortData - DeviceExtension->InputCount, - sizeof(KEYBOARD_INPUT_DATA)); - - if (DeviceExtension->InputCount > 1) - { - RtlMoveMemory( - DeviceExtension->PortData - DeviceExtension->InputCount, - DeviceExtension->PortData - DeviceExtension->InputCount + 1, - (DeviceExtension->InputCount - 1) * sizeof(KEYBOARD_INPUT_DATA)); - } - DeviceExtension->PortData--; - DeviceExtension->InputCount--; - DeviceExtension->ReadIsPending = FALSE; - - /* Go to next packet and complete this request with STATUS_SUCCESS */ - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA); - Stack->Parameters.Read.Length = sizeof(KEYBOARD_INPUT_DATA); + Status = FillOneEntry( + DeviceObject, + Irp, + DeviceExtension->PortData - DeviceExtension->InputCount); + + if (NT_SUCCESS(Status)) + { + if (DeviceExtension->InputCount > 1) + { + RtlMoveMemory( + DeviceExtension->PortData - DeviceExtension->InputCount, + DeviceExtension->PortData - DeviceExtension->InputCount + 1, + (DeviceExtension->InputCount - 1) * sizeof(KEYBOARD_INPUT_DATA)); + } + + DeviceExtension->PortData--; + DeviceExtension->InputCount--; + DeviceExtension->ReadIsPending = FALSE; + + Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA); + Stack->Parameters.Read.Length = sizeof(KEYBOARD_INPUT_DATA); + } + + /* Go to next packet and complete this request */ + Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_KEYBOARD_INCREMENT);
IoStartNextPacket(DeviceObject, FALSE);
Modified: trunk/reactos/drivers/input/kbdclass/kbdclass.h URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/drivers/input/kbdclass/kbdcl... ============================================================================== --- trunk/reactos/drivers/input/kbdclass/kbdclass.h (original) +++ trunk/reactos/drivers/input/kbdclass/kbdclass.h Wed Apr 26 02:22:22 2006 @@ -1,6 +1,7 @@ #include <ntifs.h> #include <kbdmou.h> #include <ntddkbd.h> +#include <pseh/pseh.h> #include <stdio.h>
#define MAX_PATH 260
Modified: trunk/reactos/drivers/input/kbdclass/kbdclass.rbuild URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/drivers/input/kbdclass/kbdcl... ============================================================================== --- trunk/reactos/drivers/input/kbdclass/kbdclass.rbuild (original) +++ trunk/reactos/drivers/input/kbdclass/kbdclass.rbuild Wed Apr 26 02:22:22 2006 @@ -1,6 +1,7 @@ <module name="kbdclass" type="kernelmodedriver" installbase="system32/drivers" installname="kbdclass.sys"> <bootstrap base="reactos" /> <define name="__USE_W32API" /> + <library>pseh</library> <library>ntoskrnl</library> <library>hal</library> <file>kbdclass.c</file>
Modified: trunk/reactos/drivers/input/mouclass/mouclass.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/drivers/input/mouclass/moucl... ============================================================================== --- trunk/reactos/drivers/input/mouclass/mouclass.c (original) +++ trunk/reactos/drivers/input/mouclass/mouclass.c Wed Apr 26 02:22:22 2006 @@ -35,6 +35,9 @@ return ForwardIrpAndForget(DeviceObject, Irp);
/* FIXME: open all associated Port devices */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
@@ -49,6 +52,9 @@ return ForwardIrpAndForget(DeviceObject, Irp);
/* FIXME: close all associated Port devices */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
@@ -63,6 +69,9 @@ return ForwardIrpAndForget(DeviceObject, Irp);
/* FIXME: cleanup all associated Port devices */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
@@ -114,7 +123,7 @@ PLIST_ENTRY Head = &((PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ListHead; if (Head->Flink != Head) { - /* We have at least one keyboard */ + /* We have at least one mouse */ PPORT_DEVICE_EXTENSION DevExt = CONTAINING_RECORD(Head->Flink, PORT_DEVICE_EXTENSION, ListEntry); IoGetCurrentIrpStackLocation(Irp)->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; IoSkipCurrentIrpStackLocation(Irp); @@ -358,6 +367,53 @@ return STATUS_SUCCESS; }
+static NTSTATUS +FillOneEntry( + IN PDEVICE_OBJECT ClassDeviceObject, + IN PIRP Irp, + IN PMOUSE_INPUT_DATA DataStart) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (ClassDeviceObject->Flags & DO_BUFFERED_IO) + { + RtlCopyMemory( + Irp->AssociatedIrp.SystemBuffer, + DataStart, + sizeof(MOUSE_INPUT_DATA)); + } + else if (ClassDeviceObject->Flags & DO_DIRECT_IO) + { + PVOID DestAddress = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); + if (DestAddress) + { + RtlCopyMemory( + DestAddress, + DataStart, + sizeof(MOUSE_INPUT_DATA)); + } + else + Status = STATUS_UNSUCCESSFUL; + } + else + { + _SEH_TRY + { + RtlCopyMemory( + Irp->UserBuffer, + DataStart, + sizeof(MOUSE_INPUT_DATA)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + + return Status; +} + static BOOLEAN ClassCallback( IN PDEVICE_OBJECT ClassDeviceObject, @@ -383,28 +439,32 @@ */ if (ClassDeviceExtension->ReadIsPending == TRUE && InputCount) { + NTSTATUS Status; + Irp = ClassDeviceObject->CurrentIrp; ClassDeviceObject->CurrentIrp = NULL; Stack = IoGetCurrentIrpStackLocation(Irp);
/* A read request is waiting for input, so go straight to it */ - /* FIXME: use SEH */ - RtlCopyMemory( - Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->UserBuffer, - DataStart, - sizeof(MOUSE_INPUT_DATA)); - - /* Go to next packet and complete this request with STATUS_SUCCESS */ - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA); - Stack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA); - - ClassDeviceExtension->ReadIsPending = FALSE; - - /* Skip the packet we just sent away */ - DataStart++; - (*ConsumedCount)++; - InputCount--; + Status = FillOneEntry( + ClassDeviceObject, + Irp, + DataStart); + + if (NT_SUCCESS(Status)) + { + /* Go to next packet and complete this request with STATUS_SUCCESS */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA); + Stack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA); + + ClassDeviceExtension->ReadIsPending = FALSE; + + /* Skip the packet we just sent away */ + DataStart++; + (*ConsumedCount)++; + InputCount--; + } }
/* If we have data from the port driver and a higher service to send the data to */ @@ -416,9 +476,11 @@ ReadSize = InputCount;
/* - * FIXME: If we exceed the buffer, data gets thrown away.. better - * solution? - */ + * If we exceed the buffer, data gets thrown away... + * Try at least to display a dialog + */ + if (Irp != NULL) + IoRaiseHardError(Irp, NULL, ClassDeviceObject);
/* * Move the input data from the port data queue to our class data @@ -526,7 +588,7 @@ sizeof(PORT_DEVICE_EXTENSION), NULL, Pdo->DeviceType, - FILE_DEVICE_SECURE_OPEN, + Pdo->Characteristics & FILE_DEVICE_SECURE_OPEN ? FILE_DEVICE_SECURE_OPEN : 0, TRUE, &Fdo); if (!NT_SUCCESS(Status)) @@ -550,6 +612,8 @@ Fdo->Flags |= DO_POWER_PAGABLE; if (DeviceExtension->LowerDevice->Flags & DO_BUFFERED_IO) Fdo->Flags |= DO_BUFFERED_IO; + if (DeviceExtension->LowerDevice->Flags & DO_DIRECT_IO) + Fdo->Flags |= DO_DIRECT_IO;
if (DriverExtension->ConnectMultiplePorts) DeviceExtension->ClassDO = DriverExtension->MainClassDeviceObject; @@ -623,35 +687,35 @@ if (DeviceExtension->InputCount > 0) { KIRQL oldIrql; + NTSTATUS Status;
KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql);
- DPRINT("Mdl: %p, UserBuffer: %p, InputCount: %lu\n", - Irp->MdlAddress, - Irp->UserBuffer, - DeviceExtension->InputCount); - - /* FIXME: use SEH */ - RtlCopyMemory( - Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->UserBuffer, - DeviceExtension->PortData - DeviceExtension->InputCount, - sizeof(MOUSE_INPUT_DATA)); - - if (DeviceExtension->InputCount > 1) - { - RtlMoveMemory( - DeviceExtension->PortData - DeviceExtension->InputCount, - DeviceExtension->PortData - DeviceExtension->InputCount + 1, - (DeviceExtension->InputCount - 1) * sizeof(MOUSE_INPUT_DATA)); - } - DeviceExtension->PortData--; - DeviceExtension->InputCount--; - DeviceExtension->ReadIsPending = FALSE; - - /* Go to next packet and complete this request with STATUS_SUCCESS */ - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA); - Stack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA); + Status = FillOneEntry( + DeviceObject, + Irp, + DeviceExtension->PortData - DeviceExtension->InputCount); + + if (NT_SUCCESS(Status)) + { + if (DeviceExtension->InputCount > 1) + { + RtlMoveMemory( + DeviceExtension->PortData - DeviceExtension->InputCount, + DeviceExtension->PortData - DeviceExtension->InputCount + 1, + (DeviceExtension->InputCount - 1) * sizeof(MOUSE_INPUT_DATA)); + } + + DeviceExtension->PortData--; + DeviceExtension->InputCount--; + DeviceExtension->ReadIsPending = FALSE; + + Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA); + Stack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA); + } + + /* Go to next packet and complete this request */ + Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
IoStartNextPacket(DeviceObject, FALSE);
Modified: trunk/reactos/drivers/input/mouclass/mouclass.h URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/drivers/input/mouclass/moucl... ============================================================================== --- trunk/reactos/drivers/input/mouclass/mouclass.h (original) +++ trunk/reactos/drivers/input/mouclass/mouclass.h Wed Apr 26 02:22:22 2006 @@ -1,6 +1,7 @@ #include <ntifs.h> #include <kbdmou.h> #include <ntddmou.h> +#include <pseh/pseh.h> #include <stdio.h>
#define MAX_PATH 260
Modified: trunk/reactos/drivers/input/mouclass/mouclass.rbuild URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/drivers/input/mouclass/moucl... ============================================================================== --- trunk/reactos/drivers/input/mouclass/mouclass.rbuild (original) +++ trunk/reactos/drivers/input/mouclass/mouclass.rbuild Wed Apr 26 02:22:22 2006 @@ -1,6 +1,7 @@ <module name="mouclass" type="kernelmodedriver" installbase="system32/drivers" installname="mouclass.sys"> <include base="mouclass">.</include> <define name="__USE_W32API" /> + <library>pseh</library> <library>ntoskrnl</library> <library>hal</library> <file>misc.c</file>