ReactOS  0.4.14-dev-583-g2a1ba2c
csqtest.c
Go to the documentation of this file.
1 /*
2  * CSQ Test Driver
3  * Copyright (c) 2004, Vizzini (vizzini@plasmic.com)
4  * Released under the GNU GPL for the ReactOS project
5  *
6  * This driver is designed to exercise the cancel-safe IRP queue logic.
7  * Please refer to reactos/include/ddk/csq.h and reactos/drivers/lib/csq.
8  */
9 #include <ntddk.h>
10 #include <csq.h>
11 
12 /* XXX shortcomings in our headers... */
13 #define assert(x)
14 #ifndef KdPrint
15 #define KdPrint(x) DbgPrint x
16 #endif
17 
18 /* Device name */
19 #define NT_DEVICE_NAME L"\\Device\\csqtest"
20 
21 /* DosDevices name */
22 #define DOS_DEVICE_NAME L"\\??\\csqtest"
23 
24 /* Global CSQ struct that the CSQ functions init */
26 
27 /* List and lock for the actual IRP queue */
30 
31 /* Device object */
33 
34 /*
35  * CSQ Callbacks
36  */
38 {
39  KdPrint(("Inserting IRP 0x%x into CSQ\n", Irp));
40  InsertTailList(&IrpQueue, &Irp->Tail.Overlay.ListEntry);
41 }
42 
44 {
45  KdPrint(("Removing IRP 0x%x from CSQ\n", Irp));
46  RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
47 }
48 
50 {
51  KdPrint(("Peeking for next IRP\n"));
52 
53  if(Irp)
54  return CONTAINING_RECORD(&Irp->Tail.Overlay.ListEntry.Flink, IRP, Tail.Overlay.ListEntry);
55 
56  if(IsListEmpty(&IrpQueue))
57  return NULL;
58 
59  return CONTAINING_RECORD(IrpQueue.Flink, IRP, Tail.Overlay.ListEntry);
60 }
61 
63 {
64  KdPrint(("Acquiring spin lock\n"));
66 }
67 
69 {
70  KdPrint(("Releasing spin lock\n"));
72 }
73 
75 {
76  KdPrint(("cancelling irp 0x%x\n", Irp));
77  Irp->IoStatus.Status = STATUS_CANCELLED;
78  Irp->IoStatus.Information = 0;
80 }
81 
83 /*
84  * FUNCTION: Insert into IRP queue, with extra context
85  *
86  * NOTE: Switch call in DriverEntry to IoCsqInitializeEx to use this
87  */
88 {
90  return STATUS_PENDING;
91 }
92 
93 /*
94  * DISPATCH ROUTINES
95  */
96 
98 {
100 
101  if(StackLocation->MajorFunction == IRP_MJ_CLEANUP)
102  {
103  /* flush the irp queue */
104  PIRP CurrentIrp;
105 
106  KdPrint(("csqtest: Cleanup received; flushing the IRP queue with cancel\n"));
107 
108  while((CurrentIrp = IoCsqRemoveNextIrp(&Csq, 0)))
109  {
110  CurrentIrp->IoStatus.Status = STATUS_CANCELLED;
111  CurrentIrp->IoStatus.Information = 0;
112 
113  IoCompleteRequest(CurrentIrp, IO_NO_INCREMENT);
114  }
115  }
116 
117  Irp->IoStatus.Status = STATUS_SUCCESS;
118  Irp->IoStatus.Information = 0;
119 
121 
122  return STATUS_SUCCESS;
123 }
124 
126 {
127  /* According to the cancel sample in the DDK, IoCsqInsertIrp() marks the irp pending */
128  /* However, I think it's wrong. */
130  IoCsqInsertIrp(&Csq, Irp, 0);
131 
132  return STATUS_PENDING;
133 }
134 
136 /*
137  * all IOCTL requests flush the irp queue
138  */
139 {
140  PIRP CurrentIrp;
141 
142  KdPrint(("csqtest: Ioctl received; flushing the IRP queue with success\n"));
143 
144  while((CurrentIrp = IoCsqRemoveNextIrp(&Csq, 0)))
145  {
146  CurrentIrp->IoStatus.Status = STATUS_SUCCESS;
147  CurrentIrp->IoStatus.Information = 0;
148 
149  IoCompleteRequest(CurrentIrp, IO_NO_INCREMENT);
150  }
151 
152  Irp->IoStatus.Status = STATUS_SUCCESS;
153  Irp->IoStatus.Information = 0;
154 
156 
157  return STATUS_SUCCESS;
158 }
159 
161 /*
162  * Function: called by the OS to release resources before unload
163  */
164 {
165  UNICODE_STRING LinkName;
166 
168 
169  IoDeleteSymbolicLink(&LinkName);
170 
171  if(DeviceObject)
173 }
174 
175 /*
176  * DriverEntry
177  */
178 
180 {
182  UNICODE_STRING NtName;
184 
192 
195 
196  if(Status != STATUS_SUCCESS)
197  KdPrint(("csqtest: IoCsqInitialize failed: 0x%x\n", Status));
198  else
199  KdPrint(("csqtest: IoCsqInitialize succeeded\n"));
200 
203 
204  /* Set up a device */
207 
208  if(!NT_SUCCESS(Status))
209  {
210  KdPrint(("csqtest: Unable to create device: 0x%x\n", Status));
211  return Status;
212  }
213 
215  Status = IoCreateSymbolicLink(&DosName, &NtName);
216 
217  if(!NT_SUCCESS(Status))
218  {
219  KdPrint(("csqtest: Unable to create link: 0x%x\n", Status));
220  return Status;
221  }
222 
224 
225  return STATUS_SUCCESS;
226 }
227 
VOID NTAPI CsqAcquireLock(PIO_CSQ Csq, PKIRQL Irql)
Definition: csqtest.c:62
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
LIST_ENTRY IrpQueue
Definition: csqtest.c:28
PDEVICE_OBJECT DeviceObject
Definition: csqtest.c:32
NTKERNELAPI PIRP NTAPI IoCsqRemoveNextIrp(_Inout_ PIO_CSQ Csq, _In_opt_ PVOID PeekContext)
IoCsqRemoveNextIrp - Removes the next IRP from the queue.
Definition: csq.c:398
NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: csqtest.c:179
VOID NTAPI Unload(PDRIVER_OBJECT DriverObject)
Definition: csqtest.c:160
_In_ PIRP Irp
Definition: csq.h:116
NTKERNELAPI VOID NTAPI IoCsqInsertIrp(_Inout_ PIO_CSQ Csq, _Inout_ PIRP Irp, _Out_opt_ PIO_CSQ_IRP_CONTEXT Context)
Insert an IRP into the CSQ.
Definition: csq.c:177
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI CsqInsertIrp(PIO_CSQ Csq, PIRP Irp)
Definition: csqtest.c:37
IRP
Definition: iotypes.h:2463
#define InsertTailList(ListHead, Entry)
_Out_ PKIRQL Irql
Definition: csq.h:179
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define KdPrint(x)
Definition: csqtest.c:15
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI CsqRemoveIrp(PIO_CSQ Csq, PIRP Irp)
Definition: csqtest.c:43
NTSTATUS NTAPI DispatchIoctl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: csqtest.c:135
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
VOID NTAPI CsqCompleteCancelledIrp(PIO_CSQ Csq, PIRP Irp)
Definition: csqtest.c:74
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
IO_CSQ Csq
Definition: csqtest.c:25
NTSTATUS NTAPI CsqInsertIrpEx(PIO_CSQ Csq, PIRP Irp, PVOID InsertContext)
Definition: csqtest.c:82
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_In_ PIRP _In_ PVOID InsertContext
Definition: csq.h:257
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
NTSTATUS NTAPI DispatchCreateCloseCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: csqtest.c:97
NTSTATUS NTAPI DispatchReadWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: csqtest.c:125
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define NT_DEVICE_NAME
Definition: csqtest.c:19
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
VOID NTAPI CsqReleaseLock(PIO_CSQ Csq, KIRQL Irql)
Definition: csqtest.c:68
KSPIN_LOCK IrpQueueLock
Definition: csqtest.c:29
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
Definition: typedefs.h:117
Status
Definition: gdiplustypes.h:24
Definition: csq.h:222
__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
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
_Out_ PUNICODE_STRING DosName
Definition: rtlfuncs.h:1270
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:139
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
_In_opt_ PIRP _In_opt_ PVOID PeekContext
Definition: csq.h:159
#define IRP_MJ_READ
Definition: rdpdr.c:46
PIRP NTAPI CsqPeekNextIrp(PIO_CSQ Csq, PIRP Irp, PVOID PeekContext)
Definition: csqtest.c:49
#define IRP_MJ_CLEANUP
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
#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)
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
NTKERNELAPI NTSTATUS NTAPI IoCsqInitialize(_Out_ PIO_CSQ Csq, _In_ PIO_CSQ_INSERT_IRP CsqInsertIrp, _In_ PIO_CSQ_REMOVE_IRP CsqRemoveIrp, _In_ PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp, _In_ PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock, _In_ PIO_CSQ_RELEASE_LOCK CsqReleaseLock, _In_ PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp)
Set up a CSQ struct to initialize the queue.
Definition: csq.c:103
return STATUS_SUCCESS
Definition: btrfs.c:2938
IoMarkIrpPending(Irp)
#define DOS_DEVICE_NAME
Definition: csqtest.c:22
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52