ReactOS 0.4.15-dev-7788-g1ad9096
waitsup.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Named Pipe FileSystem
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/filesystems/npfs/waitsup.c
5 * PURPOSE: Pipes Waiting Support
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "npfs.h"
12
13// File ID number for NPFS bugchecking support
14#define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_WAITSUP)
15
16/* FUNCTIONS ******************************************************************/
17
18VOID
21 IN PIRP Irp)
22{
24 PNP_WAIT_QUEUE_ENTRY WaitEntry;
25 PNP_WAIT_QUEUE WaitQueue;
26
27 IoReleaseCancelSpinLock(Irp->CancelIrql);
28
29 WaitQueue = Irp->Tail.Overlay.DriverContext[0];
30
31 KeAcquireSpinLock(&WaitQueue->WaitLock, &OldIrql);
32
33 WaitEntry = Irp->Tail.Overlay.DriverContext[1];
34 if (WaitEntry)
35 {
36 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
37 if (!KeCancelTimer(&WaitEntry->Timer))
38 {
39 WaitEntry->Irp = NULL;
40 WaitEntry = NULL;
41 }
42 }
43
45
46 if (WaitEntry)
47 {
49 ExFreePool(WaitEntry);
50 }
51
52 Irp->IoStatus.Information = 0;
53 Irp->IoStatus.Status = STATUS_CANCELLED;
55}
56
57VOID
63{
64 PIRP Irp;
66 PNP_WAIT_QUEUE_ENTRY WaitEntry = Context;
67
69
70 Irp = WaitEntry->Irp;
71 if (Irp)
72 {
73 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
74
76 {
77 Irp->Tail.Overlay.DriverContext[1] = NULL;
78 Irp = NULL;
79 }
80 }
81
83
84 if (Irp)
85 {
86 Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
88 }
89
91 ExFreePool(WaitEntry);
92}
93
94VOID
97{
98 InitializeListHead(&WaitQueue->WaitList);
99 KeInitializeSpinLock(&WaitQueue->WaitLock);
100}
101
102static
106{
107 SIZE_T EqualLength;
108
109 if (String1->Length != String2->Length)
110 return FALSE;
111
112 EqualLength = RtlCompareMemory(String1->Buffer,
113 String2->Buffer,
114 String1->Length);
115 return EqualLength == String1->Length;
116}
117
119NTAPI
121 IN PUNICODE_STRING PipePath,
124{
125 UNICODE_STRING PipePathUpper;
128 PLIST_ENTRY NextEntry;
129 PNP_WAIT_QUEUE_ENTRY WaitEntry, Linkage;
130 PIRP WaitIrp;
132 UNICODE_STRING WaitName, PipeName;
133
134 Linkage = NULL;
135
137 PipePath->Length,
140
141 RtlInitEmptyUnicodeString(&PipePathUpper, Buffer, PipePath->Length);
142 RtlUpcaseUnicodeString(&PipePathUpper, PipePath, FALSE);
143
144 KeAcquireSpinLock(&WaitQueue->WaitLock, &OldIrql);
145
146 NextEntry = WaitQueue->WaitList.Flink;
147 while (NextEntry != &WaitQueue->WaitList)
148 {
149 WaitIrp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
150 NextEntry = NextEntry->Flink;
151 WaitEntry = WaitIrp->Tail.Overlay.DriverContext[1];
152
153 if (WaitEntry->AliasName.Length)
154 {
155 ASSERT(FALSE);
156 /* We have an alias. Use that for comparison */
157 WaitName = WaitEntry->AliasName;
158 PipeName = PipePathUpper;
159 }
160 else
161 {
162 /* Use the name from the wait buffer to compare */
163 WaitBuffer = WaitIrp->AssociatedIrp.SystemBuffer;
164 WaitName.Buffer = WaitBuffer->Name;
165 WaitName.Length = WaitBuffer->NameLength;
166 WaitName.MaximumLength = WaitName.Length;
167
168 /* WaitName doesn't have a leading backslash,
169 * so skip the one in PipePathUpper for the comparison */
170 PipeName.Buffer = PipePathUpper.Buffer + 1;
171 PipeName.Length = PipePathUpper.Length - sizeof(WCHAR);
172 PipeName.MaximumLength = PipeName.Length;
173 }
174
175 /* Can't use RtlEqualUnicodeString with a spinlock held */
176 if (NpEqualUnicodeString(&WaitName, &PipeName))
177 {
178 /* Found a matching wait. Cancel it */
179 RemoveEntryList(&WaitIrp->Tail.Overlay.ListEntry);
180 if (KeCancelTimer(&WaitEntry->Timer))
181 {
182 WaitEntry->WaitQueue = (PNP_WAIT_QUEUE)Linkage;
183 Linkage = WaitEntry;
184 }
185 else
186 {
187 WaitEntry->Irp = NULL;
188 WaitIrp->Tail.Overlay.DriverContext[1] = NULL;
189 }
190
191 if (IoSetCancelRoutine(WaitIrp, NULL))
192 {
193 WaitIrp->IoStatus.Information = 0;
194 WaitIrp->IoStatus.Status = Status;
195 InsertTailList(List, &WaitIrp->Tail.Overlay.ListEntry);
196 }
197 else
198 {
199 WaitIrp->Tail.Overlay.DriverContext[1] = NULL;
200 }
201 }
202 }
203
204 KeReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
205
207
208 while (Linkage)
209 {
210 WaitEntry = Linkage;
211 Linkage = (PNP_WAIT_QUEUE_ENTRY)Linkage->WaitQueue;
213 ExFreePool(WaitEntry);
214 }
215
216 return STATUS_SUCCESS;
217}
218
220NTAPI
222 IN LARGE_INTEGER WaitTime,
223 IN PIRP Irp,
224 IN PUNICODE_STRING AliasName)
225{
226 PIO_STACK_LOCATION IoStack;
229 PNP_WAIT_QUEUE_ENTRY WaitEntry;
232 ULONG i;
233
235
237 sizeof(*WaitEntry),
239 if (!WaitEntry)
240 {
242 }
243
244 KeInitializeDpc(&WaitEntry->Dpc, NpTimerDispatch, WaitEntry);
245 KeInitializeTimer(&WaitEntry->Timer);
246
247 if (AliasName)
248 {
249 WaitEntry->AliasName = *AliasName;
250 }
251 else
252 {
253 WaitEntry->AliasName.Length = 0;
254 WaitEntry->AliasName.Buffer = NULL;
255 }
256
257 WaitEntry->WaitQueue = WaitQueue;
258 WaitEntry->Irp = Irp;
259
260 WaitBuffer = Irp->AssociatedIrp.SystemBuffer;
261 if (WaitBuffer->TimeoutSpecified)
262 {
263 DueTime = WaitBuffer->Timeout;
264 }
265 else
266 {
267 DueTime = WaitTime;
268 }
269
270 for (i = 0; i < WaitBuffer->NameLength / sizeof(WCHAR); i++)
271 {
272 WaitBuffer->Name[i] = RtlUpcaseUnicodeChar(WaitBuffer->Name[i]);
273 }
274
275 Irp->Tail.Overlay.DriverContext[0] = WaitQueue;
276 Irp->Tail.Overlay.DriverContext[1] = WaitEntry;
277
278 KeAcquireSpinLock(&WaitQueue->WaitLock, &OldIrql);
279
281
282 if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
283 {
285 }
286 else
287 {
288 InsertTailList(&WaitQueue->WaitList, &Irp->Tail.Overlay.ListEntry);
289
292
293 WaitEntry->FileObject = IoStack->FileObject;
294 ObReferenceObject(WaitEntry->FileObject);
295
296 KeSetTimer(&WaitEntry->Timer, DueTime, &WaitEntry->Dpc);
297 WaitEntry = NULL;
298 }
299
300 KeReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
301 if (WaitEntry) ExFreePool(WaitEntry);
302
303 return Status;
304}
305
306/* EOF */
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
_In_ PVOID Argument2
Definition: classpnp.h:721
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
#define NPFS_WAIT_BLOCK_TAG
Definition: npfs.h:63
struct _NP_WAIT_QUEUE_ENTRY * PNP_WAIT_QUEUE_ENTRY
struct _NP_WAIT_QUEUE * PNP_WAIT_QUEUE
#define NPFS_WRITE_BLOCK_TAG
Definition: npfs.h:64
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
Status
Definition: gdiplustypes.h:25
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
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
_In_ const STRING * String2
Definition: rtlfuncs.h:2357
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:176
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_SUCCESS
Definition: shellext.h:65
LARGE_INTEGER Timeout
Definition: winioctl.h:457
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
IO_STATUS_BLOCK IoStatus
Definition: ketypes.h:699
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: npfs.h:167
KDPC Dpc
Definition: npfs.h:169
PNP_WAIT_QUEUE WaitQueue
Definition: npfs.h:171
UNICODE_STRING AliasName
Definition: npfs.h:172
PIRP Irp
Definition: npfs.h:168
PFILE_OBJECT FileObject
Definition: npfs.h:173
KTIMER Timer
Definition: npfs.h:170
KSPIN_LOCK WaitLock
Definition: npfs.h:162
USHORT MaximumLength
Definition: env_spec_w32.h:370
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
VOID NTAPI NpCancelWaitQueueIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: waitsup.c:20
VOID NTAPI NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue)
Definition: waitsup.c:96
static BOOLEAN NpEqualUnicodeString(IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2)
Definition: waitsup.c:104
VOID NTAPI NpTimerDispatch(IN PKDPC Dpc, IN PVOID Context, IN PVOID Argument1, IN PVOID Argument2)
Definition: waitsup.c:59
NTSTATUS NTAPI NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue, IN LARGE_INTEGER WaitTime, IN PIRP Irp, IN PUNICODE_STRING AliasName)
Definition: waitsup.c:221
NTSTATUS NTAPI NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue, IN PUNICODE_STRING PipePath, IN NTSTATUS Status, IN PLIST_ENTRY List)
Definition: waitsup.c:120
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
_In_ WDFTIMER _In_ LONGLONG DueTime
Definition: wdftimer.h:190
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:696
#define ExAllocatePoolWithQuotaTag(a, b, c)
Definition: exfuncs.h:530
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IO_NAMED_PIPE_INCREMENT
Definition: iotypes.h:604
#define POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
__wchar_t WCHAR
Definition: xmlstorage.h:180