- Remove "zero-stream" from null, NT doesn't support this.
authorAlex Ionescu <aionescu@gmail.com>
Tue, 3 Apr 2007 16:22:44 +0000 (16:22 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Tue, 3 Apr 2007 16:22:44 +0000 (16:22 +0000)
- Implement Fast I/O Dispatch entrypoints for null.
- Support query file information and lock IRPs, just like NT.
- Remove query volume information IRP, not supported by NT.
- Page the entire driver.

svn path=/trunk/; revision=26256

reactos/drivers/base/null/null.c
reactos/drivers/base/null/null.h [deleted file]

index 21c1f0f..e9c38ed 100644 (file)
-/* $Id$
- *
- * COPYRIGHT:        See COPYING in the top level directory
- * PROJECT:          ReactOS kernel
- * FILE:             services/null/null.c
- * PURPOSE:          NULL device driver
- * PROGRAMMER:       David Welch (welch@mcmail.com)
- * UPDATE HISTORY:
- *              13/08/1998: Created
- *              29/04/2002: Fixed bugs, added zero-stream device
- *              28/06/2004: Compile against the DDK, use PSEH where necessary
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            drivers/base/null/null.c
+ * PURPOSE:         Beep Device Driver
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
+ *                  David Welch (welch@mcmail.com)
  */
 
-/* INCLUDES */
+/* INCLUDES ******************************************************************/
+
 #include <ntddk.h>
 
-#include <pseh/pseh.h>
+/* FUNCTIONS *****************************************************************/
+
+NTSTATUS
+NTAPI
+NullQueryFileInformation(OUT PVOID Buffer,
+                         IN PULONG Length,
+                         IN FILE_INFORMATION_CLASS InformationClass)
+{
+    PFILE_STANDARD_INFORMATION StandardInfo = Buffer;
+    PAGED_CODE();
 
-#include "null.h"
+    /* We only support one class */
+    if (InformationClass != FileStandardInformation)
+    {
+        /* Fail */
+        return STATUS_INVALID_INFO_CLASS;
+    }
 
-/* OBJECTS */
-static const NULL_EXTENSION nxNull = NullBitBucket;
-static const NULL_EXTENSION nxZero = NullZeroStream;
+    /* Fill out the information */
+    RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
+    StandardInfo->NumberOfLinks = 1;
 
-/* FUNCTIONS */
-static NTSTATUS STDCALL
-NullDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+    /* Return the length and success */
+    *Length = sizeof(FILE_STANDARD_INFORMATION);
+    return STATUS_SUCCESS;
+}
+
+BOOLEAN
+NTAPI
+NullRead(IN PFILE_OBJECT FileObject,
+         IN PLARGE_INTEGER FileOffset,
+         IN ULONG Length,
+         IN BOOLEAN Wait,
+         IN ULONG LockKey,
+         OUT PVOID Buffer,
+         OUT PIO_STATUS_BLOCK IoStatus,
+         IN PDEVICE_OBJECT DeviceObject)
 {
-    PIO_STACK_LOCATION piosStack = IoGetCurrentIrpStackLocation(Irp);
-    NTSTATUS nErrCode;
+    PAGED_CODE();
 
-    nErrCode = STATUS_SUCCESS;
-    Irp->IoStatus.Information = 0;
+    /* Complete successfully */
+    IoStatus->Status = STATUS_END_OF_FILE;
+    IoStatus->Information = 0;
+    return TRUE;
+}
 
-    switch(piosStack->MajorFunction)
+BOOLEAN
+NTAPI
+NullWrite(IN PFILE_OBJECT FileObject,
+          IN PLARGE_INTEGER FileOffset,
+          IN ULONG Length,
+          IN BOOLEAN Wait,
+          IN ULONG LockKey,
+          IN PVOID Buffer,
+          OUT PIO_STATUS_BLOCK IoStatus,
+          IN PDEVICE_OBJECT DeviceObject)
+{
+    PAGED_CODE();
+
+    /* Complete successfully */
+    IoStatus->Status = STATUS_SUCCESS;
+    IoStatus->Information = Length;
+    return TRUE;
+}
+
+NTSTATUS
+STDCALL
+NullDispatch(IN PDEVICE_OBJECT DeviceObject,
+             IN PIRP Irp)
+{
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+    NTSTATUS Status;
+    PFILE_OBJECT FileObject;
+    ULONG Length;
+    PAGED_CODE();
+
+    /* Get the file object and check what kind of request this is */
+    FileObject = IoStack->FileObject;
+    switch (IoStack->MajorFunction)
     {
-        /* opening and closing handles to the device */
         case IRP_MJ_CREATE:
         case IRP_MJ_CLOSE:
-            switch(NULL_DEVICE_TYPE(DeviceObject))
-            {
-                case NullBitBucket:
-                case NullZeroStream:
-                    break;
 
-                default:
-                    ASSERT(FALSE);
+            /* Check if this is synch I/O */
+            if (FileObject->Flags & FO_SYNCHRONOUS_IO)
+            {
+                /* Set distinguished value for Cc */
+                FileObject->PrivateCacheMap = (PVOID)1;
             }
 
+            /* Complete successfully */
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            Irp->IoStatus.Information = 0;
             break;
 
-        /* write data */
-        case IRP_MJ_WRITE:
-            {
-                switch(NULL_DEVICE_TYPE(DeviceObject))
-                {
-                    case NullBitBucket:
-                        Irp->IoStatus.Information = piosStack->Parameters.Write.Length;
-                        break;
+         case IRP_MJ_READ:
 
-                    case NullZeroStream:
-                        nErrCode = STATUS_INVALID_DEVICE_REQUEST;
-                        break;
+            /* Return as if we read the entire file */
+            Irp->IoStatus.Status = STATUS_END_OF_FILE;
+            Irp->IoStatus.Information = 0;
+            break;
 
-                    default:
-                        ASSERT(FALSE);
-                }
+        case IRP_MJ_WRITE:
 
-                break;
-            }
+            /* Return as if we wrote the entire request */
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            Irp->IoStatus.Information = IoStack->Parameters.Write.Length;
+            break;
 
-        /* read data */
-        case IRP_MJ_READ:
-            {
-                switch(NULL_DEVICE_TYPE(DeviceObject))
-                {
-                    case NullBitBucket:
-                        nErrCode = STATUS_END_OF_FILE;
-                        break;
-
-                    case NullZeroStream:
-                        _SEH_TRY
-                        {
-                            RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, piosStack->Parameters.Read.Length);
-                            Irp->IoStatus.Information = piosStack->Parameters.Read.Length;
-                        }
-                        _SEH_HANDLE
-                        {
-                            nErrCode = _SEH_GetExceptionCode();
-                        }
-                        _SEH_END;
-
-                        break;
-
-                    default:
-                        ASSERT(FALSE);
-
-                }
-
-                break;
-            }
+        case IRP_MJ_LOCK_CONTROL:
 
-        case IRP_MJ_QUERY_VOLUME_INFORMATION:
-            switch(piosStack->Parameters.QueryVolume.FsInformationClass)
-            {
-                case FileFsDeviceInformation:
-                    {
-                        ULONG BufferLength = piosStack->Parameters.QueryVolume.Length;
-                        PFILE_FS_DEVICE_INFORMATION FsDeviceInfo = (PFILE_FS_DEVICE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
-
-                        if (BufferLength >= sizeof(FILE_FS_DEVICE_INFORMATION))
-                        {
-                            FsDeviceInfo->DeviceType = FILE_DEVICE_NULL;
-                            FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
-                            Irp->IoStatus.Information = sizeof(FILE_FS_DEVICE_INFORMATION);
-                            nErrCode = STATUS_SUCCESS;
-                        }
-                        else
-                        {   
-                            Irp->IoStatus.Information  = 0;
-                            nErrCode = STATUS_BUFFER_OVERFLOW;
-                        }
-                    }
-                    break;
-
-                default:
-                    Irp->IoStatus.Information = 0;
-                    nErrCode = STATUS_NOT_IMPLEMENTED;
-            }
+            /* Dummy */
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            Irp->IoStatus.Information = 0;
             break;
 
-        default:
-            Irp->IoStatus.Information = 0;
-            nErrCode = STATUS_NOT_IMPLEMENTED;
+        case IRP_MJ_QUERY_INFORMATION:
 
+            /* Get the length inputted and do the request */
+            Length = IoStack->Parameters.QueryFile.Length;
+            Irp->IoStatus.Status = NullQueryFileInformation(Irp->AssociatedIrp.
+                                                            SystemBuffer,
+                                                            &Length,
+                                                            IoStack->
+                                                            Parameters.
+                                                            QueryFile.
+                                                            FileInformationClass);
+
+            /* Return the actual length */
+            Irp->IoStatus.Information = Length;
+            break;
     }
 
-    Irp->IoStatus.Status = nErrCode;
+    /* Complete the request */
+    Status = Irp->IoStatus.Status;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return (nErrCode);
+    return Status;
 }
 
-static VOID STDCALL
-NullUnload(PDRIVER_OBJECT DriverObject)
+NTSTATUS
+STDCALL
+DriverEntry(IN PDRIVER_OBJECT DriverObject,
+            IN PUNICODE_STRING RegistryPath)
 {
-}
-
-/* TODO: \Device\Zero should be memory-mappable */
-NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
-{
-    PDEVICE_OBJECT pdoNullDevice;
-    PDEVICE_OBJECT pdoZeroDevice;
-    UNICODE_STRING wstrNullDeviceName = RTL_CONSTANT_STRING(L"\\Device\\Null");
-    UNICODE_STRING wstrZeroDeviceName = RTL_CONSTANT_STRING(L"\\Device\\Zero");
-    NTSTATUS nErrCode;
-
-    /* register driver routines */
+    PDEVICE_OBJECT DeviceObject;
+    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Null");
+    NTSTATUS Status;
+    PFAST_IO_DISPATCH FastIoDispatch;
+    PAGED_CODE();
+
+    /* Page the driver */
+    MmPageEntireDriver(DriverEntry);
+
+    /* Create null device */
+    Status = IoCreateDevice(DriverObject,
+                            0,
+                            &DeviceName,
+                            FILE_DEVICE_NULL,
+                            0,
+                            FALSE,
+                            &DeviceObject);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Register driver routines */
     DriverObject->MajorFunction[IRP_MJ_CLOSE] = NullDispatch;
     DriverObject->MajorFunction[IRP_MJ_CREATE] = NullDispatch;
     DriverObject->MajorFunction[IRP_MJ_WRITE] = NullDispatch;
     DriverObject->MajorFunction[IRP_MJ_READ] = NullDispatch;
-    DriverObject->DriverUnload = NullUnload;
-
-    /* create null device */
-    nErrCode = IoCreateDevice(DriverObject,
-                              sizeof(NULL_EXTENSION),
-                              &wstrNullDeviceName,
-                              FILE_DEVICE_NULL,
-                              0,
-                              FALSE,
-                              &pdoNullDevice);
-
-    /* failure */
-    if(!NT_SUCCESS(nErrCode))
-    {
-        return (nErrCode);
-    }
-
-    pdoNullDevice->DeviceExtension = (PVOID)&nxNull;
+    DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = NullDispatch;
+    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = NullDispatch;
 
-    /* create zero device */
-    nErrCode = IoCreateDevice(DriverObject,
-                              sizeof(NULL_EXTENSION),   
-                              &wstrZeroDeviceName,
-                              FILE_DEVICE_NULL,
-                              FILE_READ_ONLY_DEVICE, /* zero device is read-only */
-                              FALSE,
-                              &pdoZeroDevice);
-
-    /* failure */
-    if(!NT_SUCCESS(nErrCode))
+    /* Allocate the fast I/O dispatch table */
+    FastIoDispatch = ExAllocatePool(NonPagedPool, sizeof(FAST_IO_DISPATCH));
+    if (!FastIoDispatch)
     {
-        IoDeleteDevice(pdoNullDevice);
-        return (nErrCode);
+        /* Failed, cleanup */
+        IoDeleteDevice(DeviceObject);
+        return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-    pdoZeroDevice->DeviceExtension = (PVOID)&nxZero;
-    pdoZeroDevice->Flags |= DO_BUFFERED_IO;
+    /* Initialize it */
+    RtlZeroMemory(FastIoDispatch, sizeof(FAST_IO_DISPATCH));
+    FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
+
+    /* Setup our pointers */
+    FastIoDispatch->FastIoRead = NullRead;
+    FastIoDispatch->FastIoWrite = NullWrite;
+    DriverObject->FastIoDispatch = FastIoDispatch;
 
-    return (nErrCode);
+    /* Return success */
+    return STATUS_SUCCESS;
 }
 
 /* EOF */
diff --git a/reactos/drivers/base/null/null.h b/reactos/drivers/base/null/null.h
deleted file mode 100644 (file)
index 4119c84..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:        See COPYING in the top level directory
- * PROJECT:          ReactOS kernel
- * FILE:             services/dd/null/null.h
- * PURPOSE:          NULL device driver internal definitions
- * PROGRAMMER:       KJK::Hyperion <noog@libero.it>
- * UPDATE HISTORY:
- *              29/04/2002: Created
- */
-
-typedef enum __tagNULL_EXTENSION{
- NullBitBucket,
- NullZeroStream,
-} NULL_EXTENSION, *PNULL_EXTENSION;
-
-#define NULL_DEVICE_TYPE(__DEVICE__) (*((PNULL_EXTENSION)((__DEVICE__)->DeviceExtension)))
-
-NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
-
-/* EOF */