ReactOS  0.4.14-dev-50-g13bb5e2
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 
18 VOID
19 NTAPI
21  IN PIRP Irp)
22 {
23  IoReleaseCancelSpinLock(Irp->CancelIrql);
24 
27 
28  RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
29 
30  NpReleaseVcb();
32 
33  Irp->IoStatus.Status = STATUS_CANCELLED;
35 }
36 
38 NTAPI
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 
76 NTAPI
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 
160  NpDeleteEventTableEntry(&NpVcb->EventTable, EventBuffer);
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 
186 NTSTATUS
187 NTAPI
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 
210  if (Ccb->CompletionMode[FILE_PIPE_SERVER_END] == FILE_PIPE_COMPLETE_OPERATION)
211  {
212  Ccb->NamedPipeState = FILE_PIPE_LISTENING_STATE;
213  return STATUS_PIPE_LISTENING;
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 
243 NTSTATUS
244 NTAPI
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  {
274  ListIrp->IoStatus.Status = STATUS_PIPE_BROKEN;
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 
295  NpDeleteCcb(Ccb, List);
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  {
321  ListIrp->IoStatus.Status = STATUS_PIPE_BROKEN;
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 
334  NpDeleteCcb(Ccb, List);
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  {
366  ListIrp->IoStatus.Status = STATUS_PIPE_BROKEN;
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  {
376  ListIrp->IoStatus.Status = STATUS_PIPE_BROKEN;
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 */
VOID NTAPI NpDeleteFcb(IN PNP_FCB Fcb, IN PLIST_ENTRY ListEntry)
Definition: strucsup.c:63
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define FsRtlEnterFileSystem
#define FILE_PIPE_QUEUE_OPERATION
Definition: iotypes.h:79
#define STATUS_PIPE_DISCONNECTED
Definition: ntstatus.h:398
NP_WAIT_QUEUE WaitQueue
Definition: npfs.h:285
PNP_EVENT_BUFFER EventBuffer[2]
Definition: npfs.h:253
#define FsRtlExitFileSystem
PFILE_OBJECT FileObject
Definition: ntfs.h:516
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI NpSetConnectedPipeState(IN PNP_CCB Ccb, IN PFILE_OBJECT FileObject, IN PLIST_ENTRY List)
Definition: statesup.c:39
#define FILE_PIPE_CLIENT_END
Definition: iotypes.h:84
#define FILE_PIPE_CONNECTED_STATE
Definition: winternl.h:792
IRP
Definition: iotypes.h:2463
#define InsertTailList(ListHead, Entry)
IoSetCancelRoutine(Irp, CancelRoutine)
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define STATUS_PIPE_CLOSING
Definition: ntstatus.h:399
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
VOID NTAPI NpCancelListeningQueueIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: statesup.c:20
Definition: npfs.h:228
Definition: npfs.h:258
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS NTAPI NpSetDisconnectedPipeState(IN PNP_CCB Ccb, IN PLIST_ENTRY List)
Definition: statesup.c:77
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
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
#define FILE_PIPE_LISTENING_STATE
Definition: winternl.h:791
ULONG QueueState
Definition: npfs.h:139
BOOLEAN NTAPI NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table, IN PVOID Buffer)
Definition: strucsup.c:52
NTSTATUS NTAPI NpSetListeningPipeState(IN PNP_CCB Ccb, IN PIRP Irp, IN PLIST_ENTRY List)
Definition: statesup.c:188
#define NpBugCheck(p1, p2, p3)
Definition: npfs.h:106
PIRP NTAPI NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue, IN BOOLEAN Flag, IN PLIST_ENTRY List)
Definition: datasup.c:105
LIST_ENTRY List
Definition: psmgr.c:57
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_PIPE_LISTENING
Definition: ntstatus.h:401
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
* PFILE_OBJECT
Definition: iotypes.h:1955
#define FILE_PIPE_SERVER_END
Definition: iotypes.h:85
PNP_VCB NpVcb
Definition: strucsup.c:19
#define IO_NAMED_PIPE_INCREMENT
Definition: iotypes.h:572
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_PIPE_BROKEN
Definition: ntstatus.h:553
#define FILE_PIPE_COMPLETE_OPERATION
Definition: iotypes.h:80
#define STATUS_PIPE_CONNECTED
Definition: ntstatus.h:400
RTL_GENERIC_TABLE EventTable
Definition: npfs.h:284
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
Definition: typedefs.h:117
VOID NTAPI NpUninitializeSecurity(IN PNP_CCB Ccb)
Definition: secursup.c:72
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
Status
Definition: gdiplustypes.h:24
VOID NTAPI NpSetFileObject(IN PFILE_OBJECT FileObject, IN PVOID PrimaryContext, IN PVOID Ccb, IN ULONG NamedPipeEnd)
Definition: fileobsup.c:62
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define FILE_PIPE_DISCONNECTED_STATE
Definition: winternl.h:790
PKEVENT Event
Definition: npfs.h:179
VOID NTAPI NpDeleteCcb(IN PNP_CCB Ccb, IN PLIST_ENTRY ListEntry)
Definition: strucsup.c:92
FORCEINLINE VOID NpReleaseVcb(VOID)
Definition: npfs.h:344
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define FILE_PIPE_OUTBOUND
Definition: iotypes.h:82
struct _FCB::@693::@696 Fcb
#define FILE_PIPE_BYTE_STREAM_MODE
Definition: iotypes.h:77
NTSTATUS NTAPI NpSetClosingPipeState(IN PNP_CCB Ccb, IN PIRP Irp, IN ULONG NamedPipeEnd, IN PLIST_ENTRY List)
Definition: statesup.c:245
#define FILE_PIPE_CLOSING_STATE
Definition: winternl.h:793
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSTATUS NTAPI NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue, IN PUNICODE_STRING PipeName, IN NTSTATUS Status, IN PLIST_ENTRY ListEntry)
Definition: waitsup.c:120
#define FILE_PIPE_INBOUND
Definition: iotypes.h:81
FORCEINLINE VOID NpAcquireExclusiveVcb(VOID)
Definition: npfs.h:336
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2966
IoMarkIrpPending(Irp)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: npfs.h:125