ReactOS 0.4.15-dev-7788-g1ad9096
statesup.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/statesup.c
5 * PURPOSE: Pipes State 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_STATESUP)
15
16/* FUNCTIONS ******************************************************************/
17
18VOID
21 IN PIRP Irp)
22{
23 IoReleaseCancelSpinLock(Irp->CancelIrql);
24
27
28 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
29
32
33 Irp->IoStatus.Status = STATUS_CANCELLED;
35}
36
42{
43 PLIST_ENTRY NextEntry;
44 PIRP Irp;
45
46 ASSERT(Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE);
47
50 Ccb->NamedPipeState = FILE_PIPE_CONNECTED_STATE;
52
53 NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, FALSE);
54
55 while (!IsListEmpty(&Ccb->IrpList))
56 {
57 NextEntry = RemoveHeadList(&Ccb->IrpList);
58
59 Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
60
62 {
63 Irp->IoStatus.Status = STATUS_SUCCESS;
64 InsertTailList(List, NextEntry);
65 }
66 else
67 {
68 InitializeListHead(NextEntry);
69 }
70 }
71
72 return STATUS_SUCCESS;
73}
74
79{
80 PIRP Irp;
81 PNP_NONPAGED_CCB NonPagedCcb;
83 PLIST_ENTRY NextEntry;
84 PNP_EVENT_BUFFER EventBuffer;
85
86 NonPagedCcb = Ccb->NonPagedCcb;
87
88 switch (Ccb->NamedPipeState)
89 {
92 break;
93
95 while (!IsListEmpty(&Ccb->IrpList))
96 {
97 NextEntry = RemoveHeadList(&Ccb->IrpList);
98
99 Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
100
102 {
103 Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
104 InsertTailList(List, NextEntry);
105 }
106 else
107 {
108 InitializeListHead(NextEntry);
109 }
110 }
111
113 break;
114
116
117 EventBuffer = NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END];
118
119 while (Ccb->DataQueue[FILE_PIPE_INBOUND].QueueState != Empty)
120 {
122 if (Irp)
123 {
124 Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
125 InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
126 }
127 }
128
129 while (Ccb->DataQueue[FILE_PIPE_OUTBOUND].QueueState != Empty)
130 {
132 if (Irp)
133 {
134 Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
135 InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
136 }
137 }
138
139 if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
140
141 // drop down on purpose... queue will be empty so flush code is nop
142 ASSERT(Ccb->DataQueue[FILE_PIPE_OUTBOUND].QueueState == Empty);
143
145
146 EventBuffer = NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END];
147
148 while (Ccb->DataQueue[FILE_PIPE_INBOUND].QueueState != Empty)
149 {
151 if (Irp)
152 {
153 Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
154 InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
155 }
156 }
157
158 ASSERT(Ccb->DataQueue[FILE_PIPE_OUTBOUND].QueueState == Empty);
159
161 NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END] = NULL;
162
165
167
168 if (Ccb->ClientSession)
169 {
170 ExFreePool(Ccb->ClientSession);
171 Ccb->ClientSession = NULL;
172 }
173
175 break;
176
177 default:
178 NpBugCheck(Ccb->NamedPipeState, 0, 0);
179 break;
180 }
181
182 Ccb->NamedPipeState = FILE_PIPE_DISCONNECTED_STATE;
183 return Status;
184}
185
187NTAPI
189 IN PIRP Irp,
191{
193
194 switch (Ccb->NamedPipeState)
195 {
197
199 &Ccb->Fcb->FullName,
201 List);
202 if (!NT_SUCCESS(Status)) return Status;
203
204 //
205 // Drop down on purpose
206 //
207
209
211 {
212 Ccb->NamedPipeState = FILE_PIPE_LISTENING_STATE;
214 }
215
217 if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
218 {
219 return STATUS_CANCELLED;
220 }
221
222 Ccb->NamedPipeState = FILE_PIPE_LISTENING_STATE;
224 InsertTailList(&Ccb->IrpList, &Irp->Tail.Overlay.ListEntry);
225 return STATUS_PENDING;
226
229 break;
230
233 break;
234
235 default:
236 NpBugCheck(Ccb->NamedPipeState, 0, 0);
237 break;
238 }
239
240 return Status;
241}
242
244NTAPI
246 IN PIRP Irp,
247 IN ULONG NamedPipeEnd,
249{
250 PNP_NONPAGED_CCB NonPagedCcb;
251 PNP_FCB Fcb;
252 PLIST_ENTRY NextEntry;
253 PNP_DATA_QUEUE ReadQueue, WriteQueue, DataQueue;
254 PNP_EVENT_BUFFER EventBuffer;
255 PIRP ListIrp;
256
257 NonPagedCcb = Ccb->NonPagedCcb;
258 Fcb = Ccb->Fcb;
259
260 switch (Ccb->NamedPipeState)
261 {
263
264 ASSERT(NamedPipeEnd == FILE_PIPE_SERVER_END);
265
266 while (!IsListEmpty(&Ccb->IrpList))
267 {
268 NextEntry = RemoveHeadList(&Ccb->IrpList);
269
270 ListIrp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
271
272 if (IoSetCancelRoutine(ListIrp, NULL))
273 {
275 InsertTailList(List, NextEntry);
276 }
277 else
278 {
279 InitializeListHead(NextEntry);
280 }
281 }
282
283 // Drop on purpose
284
286
287 ASSERT(NamedPipeEnd == FILE_PIPE_SERVER_END);
288
291
294
296 if (!Fcb->CurrentInstances) NpDeleteFcb(Fcb, List);
297 break;
298
300
301 if (NamedPipeEnd == FILE_PIPE_SERVER_END)
302 {
303 DataQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
304 }
305 else
306 {
307 DataQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
308 }
309
312
315
316 while (DataQueue->QueueState != Empty)
317 {
318 ListIrp = NpRemoveDataQueueEntry(DataQueue, FALSE, List);
319 if (ListIrp)
320 {
322 InsertTailList(List, &ListIrp->Tail.Overlay.ListEntry);
323 }
324 }
325
327
328 if (Ccb->ClientSession)
329 {
330 ExFreePool(Ccb->ClientSession);
331 Ccb->ClientSession = NULL;
332 }
333
335 if (!Fcb->CurrentInstances) NpDeleteFcb(Fcb, List);
336 break;
337
339
340 if (NamedPipeEnd == FILE_PIPE_SERVER_END)
341 {
342 ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
343 WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
344
347 }
348 else
349 {
350 ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
351 WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
352
355 }
356
357 EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
358
359 Ccb->NamedPipeState = FILE_PIPE_CLOSING_STATE;
360
361 while (ReadQueue->QueueState != Empty)
362 {
363 ListIrp = NpRemoveDataQueueEntry(ReadQueue, FALSE, List);
364 if (ListIrp)
365 {
367 InsertTailList(List, &ListIrp->Tail.Overlay.ListEntry);
368 }
369 }
370
371 while (WriteQueue->QueueState == ReadEntries)
372 {
373 ListIrp = NpRemoveDataQueueEntry(WriteQueue, FALSE, List);
374 if (ListIrp)
375 {
377 InsertTailList(List, &ListIrp->Tail.Overlay.ListEntry);
378 }
379 }
380
381 if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
382 break;
383
384 default:
385 NpBugCheck(Ccb->NamedPipeState, 0, 0);
386 break;
387 }
388 return STATUS_SUCCESS;
389}
390
391/* EOF */
LONG NTSTATUS
Definition: precomp.h:26
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
_In_ PIRP Irp
Definition: csq.h:116
PIRP NTAPI NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue, IN BOOLEAN Flag, IN PLIST_ENTRY List)
Definition: datasup.c:105
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FORCEINLINE VOID NpAcquireExclusiveVcb(VOID)
Definition: npfs.h:336
FORCEINLINE VOID NpReleaseVcb(VOID)
Definition: npfs.h:344
PNP_VCB NpVcb
Definition: strucsup.c:19
VOID NTAPI NpDeleteFcb(IN PNP_FCB Fcb, IN PLIST_ENTRY ListEntry)
Definition: strucsup.c:63
@ ReadEntries
Definition: npfs.h:123
@ Empty
Definition: npfs.h:125
#define NpBugCheck(p1, p2, p3)
Definition: npfs.h:106
NTSTATUS NTAPI NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue, IN PUNICODE_STRING PipeName, IN NTSTATUS Status, IN PLIST_ENTRY ListEntry)
Definition: waitsup.c:120
VOID NTAPI NpDeleteCcb(IN PNP_CCB Ccb, IN PLIST_ENTRY ListEntry)
Definition: strucsup.c:92
BOOLEAN NTAPI NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table, IN PVOID Buffer)
Definition: strucsup.c:52
VOID NTAPI NpUninitializeSecurity(IN PNP_CCB Ccb)
Definition: secursup.c:72
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VOID NTAPI NpSetFileObject(IN PFILE_OBJECT FileObject, IN PVOID PrimaryContext, IN PVOID Ccb, IN ULONG NamedPipeEnd)
Definition: fileobsup.c:62
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
#define FILE_PIPE_DISCONNECTED_STATE
Definition: winternl.h:790
#define FILE_PIPE_LISTENING_STATE
Definition: winternl.h:791
#define FILE_PIPE_CONNECTED_STATE
Definition: winternl.h:792
#define FILE_PIPE_CLOSING_STATE
Definition: winternl.h:793
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
#define ASSERT(a)
Definition: mode.c:44
#define FILE_PIPE_OUTBOUND
Definition: iotypes.h:82
#define FILE_PIPE_INBOUND
Definition: iotypes.h:81
#define FILE_PIPE_CLIENT_END
Definition: iotypes.h:84
#define FILE_PIPE_BYTE_STREAM_MODE
Definition: iotypes.h:77
#define FILE_PIPE_COMPLETE_OPERATION
Definition: iotypes.h:80
#define FILE_PIPE_SERVER_END
Definition: iotypes.h:85
#define FILE_PIPE_QUEUE_OPERATION
Definition: iotypes.h:79
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
#define STATUS_PIPE_DISCONNECTED
Definition: ntstatus.h:412
#define STATUS_PIPE_CONNECTED
Definition: ntstatus.h:414
#define STATUS_PIPE_LISTENING
Definition: ntstatus.h:415
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_PIPE_BROKEN
Definition: ntstatus.h:567
#define STATUS_PIPE_CLOSING
Definition: ntstatus.h:413
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI NpCancelListeningQueueIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: statesup.c:20
NTSTATUS NTAPI NpSetConnectedPipeState(IN PNP_CCB Ccb, IN PFILE_OBJECT FileObject, IN PLIST_ENTRY List)
Definition: statesup.c:39
NTSTATUS NTAPI NpSetDisconnectedPipeState(IN PNP_CCB Ccb, IN PLIST_ENTRY List)
Definition: statesup.c:77
NTSTATUS NTAPI NpSetClosingPipeState(IN PNP_CCB Ccb, IN PIRP Irp, IN ULONG NamedPipeEnd, IN PLIST_ENTRY List)
Definition: statesup.c:245
NTSTATUS NTAPI NpSetListeningPipeState(IN PNP_CCB Ccb, IN PIRP Irp, IN PLIST_ENTRY List)
Definition: statesup.c:188
struct _FCB::@719::@722 Fcb
PFILE_OBJECT FileObject
Definition: ntfs.h:520
IO_STATUS_BLOCK IoStatus
Definition: typedefs.h:120
Definition: npfs.h:259
ULONG QueueState
Definition: npfs.h:139
PKEVENT Event
Definition: npfs.h:179
Definition: npfs.h:229
PNP_EVENT_BUFFER EventBuffer[2]
Definition: npfs.h:253
NP_WAIT_QUEUE WaitQueue
Definition: npfs.h:285
RTL_GENERIC_TABLE EventTable
Definition: npfs.h:284
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IO_NAMED_PIPE_INCREMENT
Definition: iotypes.h:604
* PFILE_OBJECT
Definition: iotypes.h:1998