ReactOS  0.4.14-dev-49-gfb4591c
kmtest_standalone.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS kernel-mode tests
3  * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
4  * PURPOSE: Kernel-Mode Test Suite standalone driver routines
5  * COPYRIGHT: Copyright 2011-2018 Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include <ntddk.h>
9 #include <ntifs.h>
10 #include <ndk/ketypes.h>
11 
12 #define KMT_DEFINE_TEST_FUNCTIONS
13 #include <kmt_test.h>
14 
15 #define NDEBUG
16 #include <debug.h>
17 
18 #include <kmt_public.h>
19 
20 /* types */
21 typedef struct
22 {
25  PKMT_IRP_HANDLER IrpHandler;
27 
28 typedef struct
29 {
32  PKMT_MESSAGE_HANDLER MessageHandler;
34 
35 /* Prototypes */
36 DRIVER_INITIALIZE DriverEntry;
37 static DRIVER_UNLOAD DriverUnload;
39 static KMT_IRP_HANDLER DeviceControlHandler;
40 
41 /* Globals */
44 
45 #define KMT_MAX_IRP_HANDLERS 256
47 #define KMT_MAX_MESSAGE_HANDLERS 256
49 
63 NTAPI
67 {
69  WCHAR DeviceNameBuffer[128] = L"\\Device\\Kmtest-";
70  UNICODE_STRING KmtestDeviceName;
72  PKMT_DEVICE_EXTENSION KmtestDeviceExtension;
74  PCWSTR DeviceNameSuffix;
75  INT Flags = 0;
76  int i;
77  PKPRCB Prcb;
78 
79  PAGED_CODE();
80 
81  DPRINT("DriverEntry\n");
82 
83  Prcb = KeGetCurrentPrcb();
86 
87  /* get the Kmtest device, so that we get a ResultBuffer pointer */
90 
91  if (!NT_SUCCESS(Status))
92  {
93  DPRINT1("Failed to get Kmtest device object pointer\n");
94  goto cleanup;
95  }
96 
98 
99  if (!NT_SUCCESS(Status))
100  {
101  DPRINT1("Failed to reference Kmtest device object\n");
102  goto cleanup;
103  }
104 
107  KmtestDeviceExtension = KmtestDeviceObject->DeviceExtension;
108  ResultBuffer = KmtestDeviceExtension->ResultBuffer;
109  DPRINT("KmtestDeviceObject: %p\n", (PVOID)KmtestDeviceObject);
110  DPRINT("KmtestDeviceExtension: %p\n", (PVOID)KmtestDeviceExtension);
111  DPRINT("Setting ResultBuffer: %p\n", (PVOID)ResultBuffer);
112 
113  /* call TestEntry */
114  RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
115  DeviceName.MaximumLength = sizeof DeviceNameBuffer;
116  TestEntry(DriverObject, RegistryPath, &DeviceNameSuffix, &Flags);
117 
118  /* create test device */
119  if (!(Flags & TESTENTRY_NO_CREATE_DEVICE))
120  {
121  RtlAppendUnicodeToString(&DeviceName, DeviceNameSuffix);
125  (Flags & TESTENTRY_NO_READONLY_DEVICE ? 0 : FILE_READ_ONLY_DEVICE),
126  Flags & TESTENTRY_NO_EXCLUSIVE_DEVICE ? FALSE : TRUE,
128 
129  if (!NT_SUCCESS(Status))
130  {
131  DPRINT1("Could not create device object %wZ\n", &DeviceName);
132  goto cleanup;
133  }
134 
135  if (Flags & TESTENTRY_BUFFERED_IO_DEVICE)
137 
138  DPRINT("DriverEntry. Created DeviceObject %p\n",
140  }
141 
142  /* initialize dispatch functions */
143  if (!(Flags & TESTENTRY_NO_REGISTER_UNLOAD))
145  if (!(Flags & TESTENTRY_NO_REGISTER_DISPATCH))
146  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
148 
149 cleanup:
151  {
154  }
155 
157  {
160  if (KmtestFileObject)
162  }
163 
164  return Status;
165 }
166 
175 static
176 VOID
177 NTAPI
180 {
181  PAGED_CODE();
182 
184 
185  DPRINT("DriverUnload\n");
186 
188 
189  if (TestDeviceObject)
191 
192  if (KmtestDeviceObject)
194 }
195 
213 NTSTATUS
215  IN UCHAR MajorFunction,
217  IN PKMT_IRP_HANDLER IrpHandler)
218 {
220  int i;
221 
222  if (MajorFunction > IRP_MJ_MAXIMUM_FUNCTION)
223  {
225  goto cleanup;
226  }
227 
228  if (IrpHandler == NULL)
229  {
231  goto cleanup;
232  }
233 
234  for (i = 0; i < sizeof IrpHandlers / sizeof IrpHandlers[0]; ++i)
235  if (IrpHandlers[i].IrpHandler == NULL)
236  {
237  IrpHandlers[i].MajorFunction = MajorFunction;
239  IrpHandlers[i].IrpHandler = IrpHandler;
240  goto cleanup;
241  }
242 
244 
245 cleanup:
246  return Status;
247 }
248 
266 NTSTATUS
268  IN UCHAR MajorFunction,
270  IN PKMT_IRP_HANDLER IrpHandler)
271 {
273  int i;
274 
275  for (i = 0; i < sizeof IrpHandlers / sizeof IrpHandlers[0]; ++i)
276  if (IrpHandlers[i].MajorFunction == MajorFunction &&
278  IrpHandlers[i].IrpHandler == IrpHandler)
279  {
281  goto cleanup;
282  }
283 
285 
286 cleanup:
287  return Status;
288 }
289 
302 static
303 NTSTATUS
304 NTAPI
307  IN PIRP Irp)
308 {
310  PIO_STACK_LOCATION IoStackLocation;
311  int i;
312 
313  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
314 
315  DPRINT("DriverDispatch: Function=%s, Device=%p\n",
316  KmtMajorFunctionNames[IoStackLocation->MajorFunction],
317  DeviceObject);
318 
319  for (i = 0; i < sizeof IrpHandlers / sizeof IrpHandlers[0]; ++i)
320  {
321  if (IrpHandlers[i].MajorFunction == IoStackLocation->MajorFunction &&
324  return IrpHandlers[i].IrpHandler(DeviceObject, Irp, IoStackLocation);
325  }
326 
327  /* default handler for DeviceControl */
328  if (IoStackLocation->MajorFunction == IRP_MJ_DEVICE_CONTROL ||
329  IoStackLocation->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL)
330  return DeviceControlHandler(DeviceObject, Irp, IoStackLocation);
331 
332  /* Return success for create, close, and cleanup */
333  if (IoStackLocation->MajorFunction == IRP_MJ_CREATE ||
334  IoStackLocation->MajorFunction == IRP_MJ_CLOSE ||
335  IoStackLocation->MajorFunction == IRP_MJ_CLEANUP)
337 
338  /* default handler */
339  Irp->IoStatus.Status = Status;
340  Irp->IoStatus.Information = 0;
341 
343 
344  return Status;
345 }
346 
367 NTSTATUS
371  IN PKMT_MESSAGE_HANDLER MessageHandler)
372 {
374  int i;
375 
376  if (ControlCode >= 0x400)
377  {
379  goto cleanup;
380  }
381 
382  if (MessageHandler == NULL)
383  {
385  goto cleanup;
386  }
387 
388  for (i = 0; i < sizeof MessageHandlers / sizeof MessageHandlers[0]; ++i)
389  if (MessageHandlers[i].MessageHandler == NULL)
390  {
393  MessageHandlers[i].MessageHandler = MessageHandler;
394  goto cleanup;
395  }
396 
398 
399 cleanup:
400  return Status;
401 }
402 
420 NTSTATUS
424  IN PKMT_MESSAGE_HANDLER MessageHandler)
425 {
427  int i;
428 
429  for (i = 0; i < sizeof MessageHandlers / sizeof MessageHandlers[0]; ++i)
432  MessageHandlers[i].MessageHandler == MessageHandler)
433  {
435  goto cleanup;
436  }
437 
439 
440 cleanup:
441  return Status;
442 }
443 
465 static
466 NTSTATUS
469  IN PIRP Irp,
470  IN PIO_STACK_LOCATION IoStackLocation)
471 {
473  ULONG ControlCode = (IoStackLocation->Parameters.DeviceIoControl.IoControlCode & 0x00000FFC) >> 2;
474  SIZE_T OutLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
475  int i;
476 
477  for (i = 0; i < sizeof MessageHandlers / sizeof MessageHandlers[0]; ++i)
478  {
479  if ((MessageHandlers[i].ControlCode == 0 ||
482  MessageHandlers[i].MessageHandler != NULL)
483  {
484  Status = MessageHandlers[i].MessageHandler(DeviceObject, ControlCode, Irp->AssociatedIrp.SystemBuffer,
485  IoStackLocation->Parameters.DeviceIoControl.InputBufferLength,
486  &OutLength);
487  break;
488  }
489  }
490 
491  Irp->IoStatus.Status = Status;
492  Irp->IoStatus.Information = OutLength;
493 
495 
496  return Status;
497 }
DRIVER_INITIALIZE DriverEntry
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
static PDEVICE_OBJECT KmtestDeviceObject
PCSTR KmtMajorFunctionNames[]
#define TRUE
Definition: types.h:120
static KMT_MESSAGE_HANDLER_ENTRY MessageHandlers[KMT_MAX_MESSAGE_HANDLERS]
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
NTSTATUS KmtUnregisterMessageHandler(IN ULONG ControlCode OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_MESSAGE_HANDLER MessageHandler)
static KMT_IRP_HANDLER DeviceControlHandler
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
#define KMT_MAX_IRP_HANDLERS
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define KMTEST_DEVICE_DRIVER_PATH
Definition: kmt_public.h:34
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define PRCB_BUILD_DEBUG
Definition: ketypes.h:242
int32_t INT
Definition: typedefs.h:56
#define PAGED_CODE()
Definition: video.h:57
NTSTATUS KmtUnregisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler)
static void TestEntry(const ENTRY *pEntry)
BOOLEAN KmtIsCheckedBuild
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:463
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:462
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
BOOLEAN KmtIsMultiProcessorBuild
void DPRINT(...)
Definition: polytest.cpp:61
_IRQL_requires_same_ typedef _In_ ULONG ControlCode
Definition: wmitypes.h:55
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:383
NTSTATUS KmtRegisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler)
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define STATUS_NOT_FOUND
Definition: shellext.h:67
static DRIVER_UNLOAD DriverUnload
NTSTATUS KmtRegisterMessageHandler(IN ULONG ControlCode OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_MESSAGE_HANDLER MessageHandler)
#define STATUS_ALLOTTED_SPACE_EXCEEDED
Definition: ntstatus.h:375
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
* PFILE_OBJECT
Definition: iotypes.h:1955
unsigned char UCHAR
Definition: xmlstorage.h:181
struct KMT_MESSAGE_HANDLER_ENTRY * PKMT_MESSAGE_HANDLER_ENTRY
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
static const WCHAR L[]
Definition: oid.c:1250
PDEVICE_OBJECT DeviceObject
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
UCHAR BuildType
Definition: ketypes.h:599
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:461
#define KMT_MAX_MESSAGE_HANDLERS
DRIVER_DISPATCH(nfs41_FsdDispatch)
Status
Definition: gdiplustypes.h:24
static KMT_IRP_HANDLER_ENTRY IrpHandlers[KMT_MAX_IRP_HANDLERS]
PDEVICE_OBJECT DeviceObject
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
ULONG_PTR SIZE_T
Definition: typedefs.h:78
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
VOID TestUnload(IN PDRIVER_OBJECT DriverObject)
Definition: Example_drv.c:93
#define PRCB_BUILD_UNIPROCESSOR
Definition: ketypes.h:243
PKMT_MESSAGE_HANDLER MessageHandler
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:139
UCHAR MajorFunction
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_CLEANUP
static PDEVICE_OBJECT TestDeviceObject
static OBJECT_ATTRIBUTES KmtestFileObject
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
PKMT_IRP_HANDLER IrpHandler
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
char * cleanup(char *str)
Definition: wpickclick.c:99
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
struct KMT_IRP_HANDLER_ENTRY * PKMT_IRP_HANDLER_ENTRY
return STATUS_SUCCESS
Definition: btrfs.c:2966
PKMT_RESULTBUFFER ResultBuffer
#define FILE_READ_ONLY_DEVICE
Definition: nt_native.h:808
static DRIVER_DISPATCH DriverDispatch
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
ULONG ControlCode
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68