- Remove "zero-stream" from null, NT doesn't support this.

- 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
This commit is contained in:
Alex Ionescu 2007-04-03 16:22:44 +00:00
parent ca95775748
commit 0c5f9a2ec6
2 changed files with 178 additions and 198 deletions

View file

@ -1,205 +1,207 @@
/* $Id$ /*
* * PROJECT: ReactOS Kernel
* COPYRIGHT: See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* PROJECT: ReactOS kernel * FILE: drivers/base/null/null.c
* FILE: services/null/null.c * PURPOSE: Beep Device Driver
* PURPOSE: NULL device driver * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* PROGRAMMER: David Welch (welch@mcmail.com) * 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
*/ */
/* INCLUDES */ /* INCLUDES ******************************************************************/
#include <ntddk.h> #include <ntddk.h>
#include <pseh/pseh.h> /* FUNCTIONS *****************************************************************/
#include "null.h" NTSTATUS
NTAPI
/* OBJECTS */ NullQueryFileInformation(OUT PVOID Buffer,
static const NULL_EXTENSION nxNull = NullBitBucket; IN PULONG Length,
static const NULL_EXTENSION nxZero = NullZeroStream; IN FILE_INFORMATION_CLASS InformationClass)
/* FUNCTIONS */
static NTSTATUS STDCALL
NullDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{ {
PIO_STACK_LOCATION piosStack = IoGetCurrentIrpStackLocation(Irp); PFILE_STANDARD_INFORMATION StandardInfo = Buffer;
NTSTATUS nErrCode; PAGED_CODE();
nErrCode = STATUS_SUCCESS; /* We only support one class */
Irp->IoStatus.Information = 0; if (InformationClass != FileStandardInformation)
switch(piosStack->MajorFunction)
{ {
/* opening and closing handles to the device */ /* Fail */
case IRP_MJ_CREATE: return STATUS_INVALID_INFO_CLASS;
case IRP_MJ_CLOSE:
switch(NULL_DEVICE_TYPE(DeviceObject))
{
case NullBitBucket:
case NullZeroStream:
break;
default:
ASSERT(FALSE);
}
break;
/* write data */
case IRP_MJ_WRITE:
{
switch(NULL_DEVICE_TYPE(DeviceObject))
{
case NullBitBucket:
Irp->IoStatus.Information = piosStack->Parameters.Write.Length;
break;
case NullZeroStream:
nErrCode = STATUS_INVALID_DEVICE_REQUEST;
break;
default:
ASSERT(FALSE);
}
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_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;
}
break;
default:
Irp->IoStatus.Information = 0;
nErrCode = STATUS_NOT_IMPLEMENTED;
} }
Irp->IoStatus.Status = nErrCode; /* Fill out the information */
RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
StandardInfo->NumberOfLinks = 1;
/* 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)
{
PAGED_CODE();
/* Complete successfully */
IoStatus->Status = STATUS_END_OF_FILE;
IoStatus->Information = 0;
return TRUE;
}
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)
{
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
/* 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;
case IRP_MJ_READ:
/* Return as if we read the entire file */
Irp->IoStatus.Status = STATUS_END_OF_FILE;
Irp->IoStatus.Information = 0;
break;
case IRP_MJ_WRITE:
/* Return as if we wrote the entire request */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = IoStack->Parameters.Write.Length;
break;
case IRP_MJ_LOCK_CONTROL:
/* Dummy */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
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;
}
/* Complete the request */
Status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
return (nErrCode);
} }
static VOID STDCALL NTSTATUS
NullUnload(PDRIVER_OBJECT DriverObject) STDCALL
DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{ {
} PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Null");
NTSTATUS Status;
PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
/* TODO: \Device\Zero should be memory-mappable */ /* Page the driver */
NTSTATUS STDCALL MmPageEntireDriver(DriverEntry);
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 */ /* 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_CLOSE] = NullDispatch;
DriverObject->MajorFunction[IRP_MJ_CREATE] = NullDispatch; DriverObject->MajorFunction[IRP_MJ_CREATE] = NullDispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = NullDispatch; DriverObject->MajorFunction[IRP_MJ_WRITE] = NullDispatch;
DriverObject->MajorFunction[IRP_MJ_READ] = NullDispatch; DriverObject->MajorFunction[IRP_MJ_READ] = NullDispatch;
DriverObject->DriverUnload = NullUnload; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = NullDispatch;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = NullDispatch;
/* create null device */ /* Allocate the fast I/O dispatch table */
nErrCode = IoCreateDevice(DriverObject, FastIoDispatch = ExAllocatePool(NonPagedPool, sizeof(FAST_IO_DISPATCH));
sizeof(NULL_EXTENSION), if (!FastIoDispatch)
&wstrNullDeviceName,
FILE_DEVICE_NULL,
0,
FALSE,
&pdoNullDevice);
/* failure */
if(!NT_SUCCESS(nErrCode))
{ {
return (nErrCode); /* Failed, cleanup */
IoDeleteDevice(DeviceObject);
return STATUS_INSUFFICIENT_RESOURCES;
} }
pdoNullDevice->DeviceExtension = (PVOID)&nxNull; /* Initialize it */
RtlZeroMemory(FastIoDispatch, sizeof(FAST_IO_DISPATCH));
FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
/* create zero device */ /* Setup our pointers */
nErrCode = IoCreateDevice(DriverObject, FastIoDispatch->FastIoRead = NullRead;
sizeof(NULL_EXTENSION), FastIoDispatch->FastIoWrite = NullWrite;
&wstrZeroDeviceName, DriverObject->FastIoDispatch = FastIoDispatch;
FILE_DEVICE_NULL,
FILE_READ_ONLY_DEVICE, /* zero device is read-only */
FALSE,
&pdoZeroDevice);
/* failure */ /* Return success */
if(!NT_SUCCESS(nErrCode)) return STATUS_SUCCESS;
{
IoDeleteDevice(pdoNullDevice);
return (nErrCode);
}
pdoZeroDevice->DeviceExtension = (PVOID)&nxZero;
pdoZeroDevice->Flags |= DO_BUFFERED_IO;
return (nErrCode);
} }
/* EOF */ /* EOF */

View file

@ -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 */