1 /* 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) 7 */ 8 9 /* INCLUDES ******************************************************************/ 10 11 #include <wdm.h> 12 13 /* GLOBALS *******************************************************************/ 14 15 FAST_IO_DISPATCH FastIoDispatch; 16 17 /* FUNCTIONS *****************************************************************/ 18 19 NTSTATUS 20 NTAPI 21 NullQueryFileInformation(OUT PVOID Buffer, 22 IN PULONG Length, 23 IN FILE_INFORMATION_CLASS InformationClass) 24 { 25 PFILE_STANDARD_INFORMATION StandardInfo = Buffer; 26 27 PAGED_CODE(); 28 29 /* We only support one class */ 30 if (InformationClass != FileStandardInformation) 31 { 32 /* Fail */ 33 return STATUS_INVALID_INFO_CLASS; 34 } 35 36 /* Fill out the information */ 37 RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION)); 38 StandardInfo->NumberOfLinks = 1; 39 40 /* Return the length and success */ 41 *Length = sizeof(FILE_STANDARD_INFORMATION); 42 return STATUS_SUCCESS; 43 } 44 45 BOOLEAN 46 NTAPI 47 NullRead(IN PFILE_OBJECT FileObject, 48 IN PLARGE_INTEGER FileOffset, 49 IN ULONG Length, 50 IN BOOLEAN Wait, 51 IN ULONG LockKey, 52 OUT PVOID Buffer, 53 OUT PIO_STATUS_BLOCK IoStatus, 54 IN PDEVICE_OBJECT DeviceObject) 55 { 56 PAGED_CODE(); 57 58 /* Complete successfully */ 59 IoStatus->Status = STATUS_END_OF_FILE; 60 IoStatus->Information = 0; 61 return TRUE; 62 } 63 64 BOOLEAN 65 NTAPI 66 NullWrite(IN PFILE_OBJECT FileObject, 67 IN PLARGE_INTEGER FileOffset, 68 IN ULONG Length, 69 IN BOOLEAN Wait, 70 IN ULONG LockKey, 71 IN PVOID Buffer, 72 OUT PIO_STATUS_BLOCK IoStatus, 73 IN PDEVICE_OBJECT DeviceObject) 74 { 75 PAGED_CODE(); 76 77 /* Complete successfully */ 78 IoStatus->Status = STATUS_SUCCESS; 79 IoStatus->Information = Length; 80 return TRUE; 81 } 82 83 NTSTATUS 84 NTAPI 85 NullDispatch(IN PDEVICE_OBJECT DeviceObject, 86 IN PIRP Irp) 87 { 88 NTSTATUS Status; 89 PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); 90 PFILE_OBJECT FileObject; 91 ULONG Length; 92 93 PAGED_CODE(); 94 95 /* Get the file object and check what kind of request this is */ 96 FileObject = IoStack->FileObject; 97 switch (IoStack->MajorFunction) 98 { 99 case IRP_MJ_CREATE: 100 case IRP_MJ_CLOSE: 101 102 /* Check if this is synch I/O */ 103 if (FileObject->Flags & FO_SYNCHRONOUS_IO) 104 { 105 /* Set distinguished value for Cc */ 106 FileObject->PrivateCacheMap = (PVOID)1; 107 } 108 109 /* Complete successfully */ 110 Irp->IoStatus.Status = STATUS_SUCCESS; 111 Irp->IoStatus.Information = 0; 112 break; 113 114 case IRP_MJ_READ: 115 116 /* Return as if we read the entire file */ 117 Irp->IoStatus.Status = STATUS_END_OF_FILE; 118 Irp->IoStatus.Information = 0; 119 break; 120 121 case IRP_MJ_WRITE: 122 123 /* Return as if we wrote the entire request */ 124 Irp->IoStatus.Status = STATUS_SUCCESS; 125 Irp->IoStatus.Information = IoStack->Parameters.Write.Length; 126 break; 127 128 case IRP_MJ_LOCK_CONTROL: 129 130 /* Dummy */ 131 Irp->IoStatus.Status = STATUS_SUCCESS; 132 Irp->IoStatus.Information = 0; 133 break; 134 135 case IRP_MJ_QUERY_INFORMATION: 136 137 /* Get the length inputted and do the request */ 138 Length = IoStack->Parameters.QueryFile.Length; 139 Irp->IoStatus.Status = NullQueryFileInformation(Irp->AssociatedIrp. 140 SystemBuffer, 141 &Length, 142 IoStack-> 143 Parameters. 144 QueryFile. 145 FileInformationClass); 146 147 /* Return the actual length */ 148 Irp->IoStatus.Information = Length; 149 break; 150 } 151 152 /* Complete the request */ 153 Status = Irp->IoStatus.Status; 154 IoCompleteRequest(Irp, IO_NO_INCREMENT); 155 return Status; 156 } 157 158 VOID 159 NTAPI 160 NullUnload(IN PDRIVER_OBJECT DriverObject) 161 { 162 PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject; 163 164 /* Delete the Null device */ 165 IoDeleteDevice(DeviceObject); 166 } 167 168 NTSTATUS 169 NTAPI 170 DriverEntry(IN PDRIVER_OBJECT DriverObject, 171 IN PUNICODE_STRING RegistryPath) 172 { 173 NTSTATUS Status; 174 PDEVICE_OBJECT DeviceObject; 175 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Null"); 176 177 PAGED_CODE(); 178 179 UNREFERENCED_PARAMETER(RegistryPath); 180 181 /* Page the driver */ 182 MmPageEntireDriver(DriverEntry); 183 184 /* Create the Null device */ 185 Status = IoCreateDevice(DriverObject, 186 0, 187 &DeviceName, 188 FILE_DEVICE_NULL, 189 FILE_DEVICE_SECURE_OPEN, 190 FALSE, 191 &DeviceObject); 192 if (!NT_SUCCESS(Status)) 193 return Status; 194 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; 203 204 /* Initialize the fast I/O dispatch table */ 205 RtlZeroMemory(&FastIoDispatch, sizeof(FastIoDispatch)); 206 FastIoDispatch.SizeOfFastIoDispatch = sizeof(FastIoDispatch); 207 208 /* Setup our pointers */ 209 FastIoDispatch.FastIoRead = NullRead; 210 FastIoDispatch.FastIoWrite = NullWrite; 211 DriverObject->FastIoDispatch = &FastIoDispatch; 212 213 /* Return success */ 214 return STATUS_SUCCESS; 215 } 216 217 /* EOF */ 218