Complete IRP_MJ_CREATE, IRP_MJ_CLOSE, IRP_MJ_CLEANUP
authorHervé Poussineau <hpoussin@reactos.org>
Tue, 25 Apr 2006 22:22:22 +0000 (22:22 +0000)
committerHervé Poussineau <hpoussin@reactos.org>
Tue, 25 Apr 2006 22:22:22 +0000 (22:22 +0000)
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

svn path=/trunk/; revision=21741

reactos/drivers/input/kbdclass/kbdclass.c
reactos/drivers/input/kbdclass/kbdclass.h
reactos/drivers/input/kbdclass/kbdclass.rbuild
reactos/drivers/input/mouclass/mouclass.c
reactos/drivers/input/mouclass/mouclass.h
reactos/drivers/input/mouclass/mouclass.rbuild

index 88944d6..6aff637 100644 (file)
@@ -35,6 +35,9 @@ ClassCreate(
                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 @@ ClassClose(
                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 @@ ClassCleanup(
                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 @@ cleanup:
        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 @@ cleanup:
        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 @@ ClassCallback(
         */
        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));
+               Status = FillOneEntry(
+                       ClassDeviceObject,
+                       Irp,
+                       DataStart);
 
-               /* 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);
+               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;
+                       ClassDeviceExtension->ReadIsPending = FALSE;
 
-               /* Skip the packet we just sent away */
-               DataStart++;
-               (*ConsumedCount)++;
-               InputCount--;
+                       /* 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 @@ ClassCallback(
                        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 @@ ClassAddDevice(
                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 @@ ClassAddDevice(
                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 @@ ClassStartIo(
        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));
+               Status = FillOneEntry(
+                       DeviceObject,
+                       Irp,
+                       DeviceExtension->PortData - DeviceExtension->InputCount);
 
-               if (DeviceExtension->InputCount > 1)
+               if (NT_SUCCESS(Status))
                {
-                       RtlMoveMemory(
-                               DeviceExtension->PortData - DeviceExtension->InputCount,
-                               DeviceExtension->PortData - DeviceExtension->InputCount + 1,
-                               (DeviceExtension->InputCount - 1) * 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;
+
+                       Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA);
+                       Stack->Parameters.Read.Length = 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);
+
+               /* Go to next packet and complete this request */
+               Irp->IoStatus.Status = Status;
                IoCompleteRequest(Irp, IO_KEYBOARD_INCREMENT);
 
                IoStartNextPacket(DeviceObject, FALSE);
index f6af437..1e129cf 100644 (file)
@@ -1,6 +1,7 @@
 #include <ntifs.h>
 #include <kbdmou.h>
 #include <ntddkbd.h>
+#include <pseh/pseh.h>
 #include <stdio.h>
 
 #define MAX_PATH 260
index 9c66104..672f152 100644 (file)
@@ -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>
index c38ddc9..c94fb3e 100644 (file)
@@ -35,6 +35,9 @@ ClassCreate(
                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 @@ ClassClose(
                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 @@ ClassCleanup(
                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 @@ ClassDeviceControl(
                        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 @@ cleanup:
        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 @@ ClassCallback(
         */
        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));
+               Status = FillOneEntry(
+                       ClassDeviceObject,
+                       Irp,
+                       DataStart);
 
-               /* 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);
+               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;
+                       ClassDeviceExtension->ReadIsPending = FALSE;
 
-               /* Skip the packet we just sent away */
-               DataStart++;
-               (*ConsumedCount)++;
-               InputCount--;
+                       /* 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 @@ ClassCallback(
                        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 @@ ClassAddDevice(
                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 @@ ClassAddDevice(
                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 @@ ClassStartIo(
        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));
+               Status = FillOneEntry(
+                       DeviceObject,
+                       Irp,
+                       DeviceExtension->PortData - DeviceExtension->InputCount);
 
-               if (DeviceExtension->InputCount > 1)
+               if (NT_SUCCESS(Status))
                {
-                       RtlMoveMemory(
-                               DeviceExtension->PortData - DeviceExtension->InputCount,
-                               DeviceExtension->PortData - DeviceExtension->InputCount + 1,
-                               (DeviceExtension->InputCount - 1) * 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;
+
+                       Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA);
+                       Stack->Parameters.Read.Length = 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);
+
+               /* Go to next packet and complete this request */
+               Irp->IoStatus.Status = Status;
                IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
 
                IoStartNextPacket(DeviceObject, FALSE);
index 897c3f5..2d1f7f4 100644 (file)
@@ -1,6 +1,7 @@
 #include <ntifs.h>
 #include <kbdmou.h>
 #include <ntddmou.h>
+#include <pseh/pseh.h>
 #include <stdio.h>
 
 #define MAX_PATH 260
index d69b085..f72316b 100644 (file)
@@ -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>