ReactOS 0.4.15-dev-7712-gbbbcd8e
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
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
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
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
191 DriverObject->DriverUnload = Unload;
192
195
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
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
LONG NTSTATUS
Definition: precomp.h:26
_In_ PIRP Irp
Definition: csq.h:116
_In_ PIRP _In_ PVOID InsertContext
Definition: csq.h:258
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
_In_opt_ PIRP _In_opt_ PVOID PeekContext
Definition: csq.h:160
_Out_ PKIRQL Irql
Definition: csq.h:179
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
NTKERNELAPI PIRP NTAPI IoCsqRemoveNextIrp(_Inout_ PIO_CSQ Csq, _In_opt_ PVOID PeekContext)
IoCsqRemoveNextIrp - Removes the next IRP from the queue.
Definition: csq.c:398
#define KdPrint(x)
Definition: csqtest.c:15
VOID NTAPI CsqCompleteCancelledIrp(PIO_CSQ Csq, PIRP Irp)
Definition: csqtest.c:74
KSPIN_LOCK IrpQueueLock
Definition: csqtest.c:29
NTSTATUS NTAPI DispatchReadWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: csqtest.c:125
NTSTATUS NTAPI DispatchIoctl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: csqtest.c:135
#define DOS_DEVICE_NAME
Definition: csqtest.c:22
#define NT_DEVICE_NAME
Definition: csqtest.c:19
NTSTATUS NTAPI CsqInsertIrpEx(PIO_CSQ Csq, PIRP Irp, PVOID InsertContext)
Definition: csqtest.c:82
PDEVICE_OBJECT DeviceObject
Definition: csqtest.c:32
LIST_ENTRY IrpQueue
Definition: csqtest.c:28
NTSTATUS NTAPI DispatchCreateCloseCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: csqtest.c:97
VOID NTAPI Unload(PDRIVER_OBJECT DriverObject)
Definition: csqtest.c:160
IO_CSQ Csq
Definition: csqtest.c:25
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
Status
Definition: gdiplustypes.h:25
IoMarkIrpPending(Irp)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
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
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_PENDING
Definition: ntstatus.h:82
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:140
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: csq.h:222
IO_STATUS_BLOCK IoStatus
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NTAPI
Definition: typedefs.h:36
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_In_ PIO_CSQ_INSERT_IRP CsqInsertIrp
Definition: iofuncs.h:1888
_In_ PIO_CSQ_INSERT_IRP _In_ PIO_CSQ_REMOVE_IRP _In_ PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp
Definition: iofuncs.h:1890
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
_In_ PIO_CSQ_INSERT_IRP _In_ PIO_CSQ_REMOVE_IRP _In_ PIO_CSQ_PEEK_NEXT_IRP _In_ PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock
Definition: iofuncs.h:1891
_In_ PIO_CSQ_INSERT_IRP _In_ PIO_CSQ_REMOVE_IRP CsqRemoveIrp
Definition: iofuncs.h:1889
_In_ PIO_CSQ_INSERT_IRP _In_ PIO_CSQ_REMOVE_IRP _In_ PIO_CSQ_PEEK_NEXT_IRP _In_ PIO_CSQ_ACQUIRE_LOCK _In_ PIO_CSQ_RELEASE_LOCK CsqReleaseLock
Definition: iofuncs.h:1892
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MJ_CLEANUP
_Out_ PUNICODE_STRING DosName
Definition: rtlfuncs.h:1269