2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Null Device Driver
5 * COPYRIGHT: Copyright 1998-2018 David Welch (welch@mcmail.com)
6 * Copyright 2007-2018 Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
13 /* GLOBALS *******************************************************************/
15 FAST_IO_DISPATCH FastIoDispatch
;
17 /* FUNCTIONS *****************************************************************/
21 NullQueryFileInformation(OUT PVOID Buffer
,
23 IN FILE_INFORMATION_CLASS InformationClass
)
25 PFILE_STANDARD_INFORMATION StandardInfo
= Buffer
;
29 /* We only support one class */
30 if (InformationClass
!= FileStandardInformation
)
33 return STATUS_INVALID_INFO_CLASS
;
36 /* Fill out the information */
37 RtlZeroMemory(StandardInfo
, sizeof(FILE_STANDARD_INFORMATION
));
38 StandardInfo
->NumberOfLinks
= 1;
40 /* Return the length and success */
41 *Length
= sizeof(FILE_STANDARD_INFORMATION
);
42 return STATUS_SUCCESS
;
47 NullRead(IN PFILE_OBJECT FileObject
,
48 IN PLARGE_INTEGER FileOffset
,
53 OUT PIO_STATUS_BLOCK IoStatus
,
54 IN PDEVICE_OBJECT DeviceObject
)
58 /* Complete successfully */
59 IoStatus
->Status
= STATUS_END_OF_FILE
;
60 IoStatus
->Information
= 0;
66 NullWrite(IN PFILE_OBJECT FileObject
,
67 IN PLARGE_INTEGER FileOffset
,
72 OUT PIO_STATUS_BLOCK IoStatus
,
73 IN PDEVICE_OBJECT DeviceObject
)
77 /* Complete successfully */
78 IoStatus
->Status
= STATUS_SUCCESS
;
79 IoStatus
->Information
= Length
;
85 NullDispatch(IN PDEVICE_OBJECT DeviceObject
,
89 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
90 PFILE_OBJECT FileObject
;
95 /* Get the file object and check what kind of request this is */
96 FileObject
= IoStack
->FileObject
;
97 switch (IoStack
->MajorFunction
)
102 /* Check if this is synch I/O */
103 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
105 /* Set distinguished value for Cc */
106 FileObject
->PrivateCacheMap
= (PVOID
)1;
109 /* Complete successfully */
110 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
111 Irp
->IoStatus
.Information
= 0;
116 /* Return as if we read the entire file */
117 Irp
->IoStatus
.Status
= STATUS_END_OF_FILE
;
118 Irp
->IoStatus
.Information
= 0;
123 /* Return as if we wrote the entire request */
124 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
125 Irp
->IoStatus
.Information
= IoStack
->Parameters
.Write
.Length
;
128 case IRP_MJ_LOCK_CONTROL
:
131 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
132 Irp
->IoStatus
.Information
= 0;
135 case IRP_MJ_QUERY_INFORMATION
:
137 /* Get the length inputted and do the request */
138 Length
= IoStack
->Parameters
.QueryFile
.Length
;
139 Irp
->IoStatus
.Status
= NullQueryFileInformation(Irp
->AssociatedIrp
.
145 FileInformationClass
);
147 /* Return the actual length */
148 Irp
->IoStatus
.Information
= Length
;
152 /* Complete the request */
153 Status
= Irp
->IoStatus
.Status
;
154 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
160 NullUnload(IN PDRIVER_OBJECT DriverObject
)
162 PDEVICE_OBJECT DeviceObject
= DriverObject
->DeviceObject
;
164 /* Delete the Null device */
165 IoDeleteDevice(DeviceObject
);
170 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
171 IN PUNICODE_STRING RegistryPath
)
174 PDEVICE_OBJECT DeviceObject
;
175 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\Null");
179 UNREFERENCED_PARAMETER(RegistryPath
);
181 /* Page the driver */
182 MmPageEntireDriver(DriverEntry
);
184 /* Create the Null device */
185 Status
= IoCreateDevice(DriverObject
,
189 FILE_DEVICE_SECURE_OPEN
,
192 if (!NT_SUCCESS(Status
))
195 /* Register driver routines */
196 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = NullDispatch
;
197 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = NullDispatch
;
198 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = NullDispatch
;
199 DriverObject
->MajorFunction
[IRP_MJ_READ
] = NullDispatch
;
200 DriverObject
->MajorFunction
[IRP_MJ_LOCK_CONTROL
] = NullDispatch
;
201 DriverObject
->MajorFunction
[IRP_MJ_QUERY_INFORMATION
] = NullDispatch
;
202 DriverObject
->DriverUnload
= NullUnload
;
204 /* Initialize the fast I/O dispatch table */
205 RtlZeroMemory(&FastIoDispatch
, sizeof(FastIoDispatch
));
206 FastIoDispatch
.SizeOfFastIoDispatch
= sizeof(FastIoDispatch
);
208 /* Setup our pointers */
209 FastIoDispatch
.FastIoRead
= NullRead
;
210 FastIoDispatch
.FastIoWrite
= NullWrite
;
211 DriverObject
->FastIoDispatch
= &FastIoDispatch
;
214 return STATUS_SUCCESS
;