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
9 /* INCLUDES *******************************************************************/
13 /* FUNCTIONS ******************************************************************/
17 NpCancelListeningQueueIrp(IN PDEVICE_OBJECT DeviceObject
,
20 FsRtlEnterFileSystem();
21 NpAcquireExclusiveVcb();
23 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
25 FsRtlExitFileSystem();
28 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
29 IoCompleteRequest(Irp
, IO_NAMED_PIPE_INCREMENT
);
34 NpSetConnectedPipeState(IN PNP_CCB Ccb
,
35 IN PFILE_OBJECT FileObject
,
38 PLIST_ENTRY NextEntry
;
41 ASSERT(Ccb
->NamedPipeState
== FILE_PIPE_LISTENING_STATE
);
43 Ccb
->ReadMode
[FILE_PIPE_CLIENT_END
] = FILE_PIPE_BYTE_STREAM_MODE
;
44 Ccb
->CompletionMode
[FILE_PIPE_CLIENT_END
] = FILE_PIPE_QUEUE_OPERATION
;
45 Ccb
->NamedPipeState
= FILE_PIPE_CONNECTED_STATE
;
46 Ccb
->FileObject
[FILE_PIPE_CLIENT_END
] = FileObject
;
48 NpSetFileObject(FileObject
, Ccb
, Ccb
->NonPagedCcb
, FALSE
);
50 while (!IsListEmpty(&Ccb
->IrpList
))
52 NextEntry
= RemoveHeadList(&Ccb
->IrpList
);
54 Irp
= CONTAINING_RECORD(NextEntry
, IRP
, Tail
.Overlay
.ListEntry
);
56 if (IoSetCancelRoutine(Irp
, NULL
))
58 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
59 InsertTailList(List
, NextEntry
);
63 InitializeListHead(NextEntry
);
67 return STATUS_SUCCESS
;
72 NpSetDisconnectedPipeState(IN PNP_CCB Ccb
,
76 PNP_NONPAGED_CCB NonPagedCcb
;
78 PLIST_ENTRY NextEntry
;
79 PNP_EVENT_BUFFER EventBuffer
;
81 NonPagedCcb
= Ccb
->NonPagedCcb
;
83 switch (Ccb
->NamedPipeState
)
85 case FILE_PIPE_DISCONNECTED_STATE
:
86 Status
= STATUS_PIPE_DISCONNECTED
;
89 case FILE_PIPE_LISTENING_STATE
:
90 while (!IsListEmpty(&Ccb
->IrpList
))
92 NextEntry
= RemoveHeadList(&Ccb
->IrpList
);
94 Irp
= CONTAINING_RECORD(NextEntry
, IRP
, Tail
.Overlay
.ListEntry
);
96 if (IoSetCancelRoutine(Irp
, NULL
))
98 Irp
->IoStatus
.Status
= STATUS_PIPE_DISCONNECTED
;
99 InsertTailList(List
, NextEntry
);
103 InitializeListHead(NextEntry
);
107 Status
= STATUS_SUCCESS
;
110 case FILE_PIPE_CONNECTED_STATE
:
112 EventBuffer
= NonPagedCcb
->EventBuffer
[FILE_PIPE_CLIENT_END
];
114 while (Ccb
->DataQueue
[FILE_PIPE_INBOUND
].QueueState
!= Empty
)
116 Irp
= NpRemoveDataQueueEntry(&Ccb
->DataQueue
[FILE_PIPE_INBOUND
], FALSE
, List
);
119 Irp
->IoStatus
.Status
= STATUS_PIPE_DISCONNECTED
;
120 InsertTailList(List
, &Irp
->Tail
.Overlay
.ListEntry
);
124 while (Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
].QueueState
!= Empty
)
126 Irp
= NpRemoveDataQueueEntry(&Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
], FALSE
, List
);
129 Irp
->IoStatus
.Status
= STATUS_PIPE_DISCONNECTED
;
130 InsertTailList(List
, &Irp
->Tail
.Overlay
.ListEntry
);
134 if (EventBuffer
) KeSetEvent(EventBuffer
->Event
, IO_NO_INCREMENT
, FALSE
);
136 // drop down on purpose... queue will be empty so flush code is nop
137 ASSERT(Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
].QueueState
== Empty
);
139 case FILE_PIPE_CLOSING_STATE
:
141 EventBuffer
= NonPagedCcb
->EventBuffer
[FILE_PIPE_CLIENT_END
];
143 while (Ccb
->DataQueue
[FILE_PIPE_INBOUND
].QueueState
!= Empty
)
145 Irp
= NpRemoveDataQueueEntry(&Ccb
->DataQueue
[FILE_PIPE_INBOUND
], FALSE
, List
);
148 Irp
->IoStatus
.Status
= STATUS_PIPE_DISCONNECTED
;
149 InsertTailList(List
, &Irp
->Tail
.Overlay
.ListEntry
);
153 ASSERT(Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
].QueueState
== Empty
);
155 NpDeleteEventTableEntry(&NpVcb
->EventTable
, EventBuffer
);
156 NonPagedCcb
->EventBuffer
[FILE_PIPE_CLIENT_END
] = NULL
;
158 NpSetFileObject(Ccb
->FileObject
[FILE_PIPE_CLIENT_END
], NULL
, NULL
, FALSE
);
159 Ccb
->FileObject
[FILE_PIPE_CLIENT_END
] = NULL
;
161 NpUninitializeSecurity(Ccb
);
163 if (Ccb
->ClientSession
)
165 ExFreePool(Ccb
->ClientSession
);
166 Ccb
->ClientSession
= NULL
;
169 Status
= STATUS_SUCCESS
;
173 KeBugCheckEx(NPFS_FILE_SYSTEM
, 0x1603DD, Ccb
->NamedPipeState
, 0, 0);
177 Ccb
->NamedPipeState
= FILE_PIPE_DISCONNECTED_STATE
;
183 NpSetListeningPipeState(IN PNP_CCB Ccb
,
189 switch (Ccb
->NamedPipeState
)
191 case FILE_PIPE_DISCONNECTED_STATE
:
193 Status
= NpCancelWaiter(&NpVcb
->WaitQueue
,
197 if (!NT_SUCCESS(Status
)) return Status
;
200 // Drop down on purpose
203 case FILE_PIPE_LISTENING_STATE
:
205 if (Ccb
->CompletionMode
[FILE_PIPE_SERVER_END
] == FILE_PIPE_COMPLETE_OPERATION
)
207 Ccb
->NamedPipeState
= FILE_PIPE_LISTENING_STATE
;
208 return STATUS_PIPE_LISTENING
;
211 IoSetCancelRoutine(Irp
, NpCancelListeningQueueIrp
);
212 if (Irp
->Cancel
&& IoSetCancelRoutine(Irp
, NULL
))
214 return STATUS_CANCELLED
;
217 Ccb
->NamedPipeState
= FILE_PIPE_LISTENING_STATE
;
218 IoMarkIrpPending(Irp
);
219 InsertTailList(&Ccb
->IrpList
, &Irp
->Tail
.Overlay
.ListEntry
);
220 return STATUS_PENDING
;
222 case FILE_PIPE_CONNECTED_STATE
:
223 Status
= STATUS_PIPE_CONNECTED
;
226 case FILE_PIPE_CLOSING_STATE
:
227 Status
= STATUS_PIPE_CLOSING
;
231 KeBugCheckEx(NPFS_FILE_SYSTEM
, 0x160133, Ccb
->NamedPipeState
, 0, 0);
240 NpSetClosingPipeState(IN PNP_CCB Ccb
,
242 IN ULONG NamedPipeEnd
,
245 PNP_NONPAGED_CCB NonPagedCcb
;
247 PLIST_ENTRY NextEntry
;
248 PNP_DATA_QUEUE ReadQueue
, WriteQueue
, DataQueue
;
249 PNP_EVENT_BUFFER EventBuffer
;
252 NonPagedCcb
= Ccb
->NonPagedCcb
;
255 switch (Ccb
->NamedPipeState
)
257 case FILE_PIPE_LISTENING_STATE
:
259 ASSERT(NamedPipeEnd
== FILE_PIPE_SERVER_END
);
261 while (!IsListEmpty(&Ccb
->IrpList
))
263 NextEntry
= RemoveHeadList(&Ccb
->IrpList
);
265 ListIrp
= CONTAINING_RECORD(NextEntry
, IRP
, Tail
.Overlay
.ListEntry
);
267 if (IoSetCancelRoutine(ListIrp
, NULL
))
269 ListIrp
->IoStatus
.Status
= STATUS_PIPE_BROKEN
;
270 InsertTailList(List
, NextEntry
);
274 InitializeListHead(NextEntry
);
280 case FILE_PIPE_DISCONNECTED_STATE
:
282 ASSERT(NamedPipeEnd
== FILE_PIPE_SERVER_END
);
284 NpSetFileObject(Ccb
->FileObject
[FILE_PIPE_SERVER_END
], NULL
, NULL
, TRUE
);
285 Ccb
->FileObject
[FILE_PIPE_SERVER_END
] = NULL
;
287 NpSetFileObject(Ccb
->FileObject
[FILE_PIPE_CLIENT_END
], NULL
, NULL
, FALSE
);
288 Ccb
->FileObject
[FILE_PIPE_CLIENT_END
] = NULL
;
290 NpDeleteCcb(Ccb
, List
);
291 if (!Fcb
->CurrentInstances
) NpDeleteFcb(Fcb
, List
);
294 case FILE_PIPE_CLOSING_STATE
:
296 if (NamedPipeEnd
== FILE_PIPE_SERVER_END
)
298 DataQueue
= &Ccb
->DataQueue
[FILE_PIPE_INBOUND
];
302 DataQueue
= &Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
];
305 NpSetFileObject(Ccb
->FileObject
[FILE_PIPE_SERVER_END
], NULL
, NULL
, TRUE
);
306 Ccb
->FileObject
[FILE_PIPE_SERVER_END
] = NULL
;
308 NpSetFileObject(Ccb
->FileObject
[FILE_PIPE_CLIENT_END
], NULL
, NULL
, FALSE
);
309 Ccb
->FileObject
[FILE_PIPE_CLIENT_END
] = NULL
;
311 while (DataQueue
->QueueState
!= Empty
)
313 ListIrp
= NpRemoveDataQueueEntry(DataQueue
, FALSE
, List
);
316 ListIrp
->IoStatus
.Status
= STATUS_PIPE_BROKEN
;
317 InsertTailList(List
, &ListIrp
->Tail
.Overlay
.ListEntry
);
321 NpUninitializeSecurity(Ccb
);
323 if (Ccb
->ClientSession
)
325 ExFreePool(Ccb
->ClientSession
);
326 Ccb
->ClientSession
= NULL
;
329 NpDeleteCcb(Ccb
, List
);
330 if (!Fcb
->CurrentInstances
) NpDeleteFcb(Fcb
, List
);
333 case FILE_PIPE_CONNECTED_STATE
:
335 if (NamedPipeEnd
== FILE_PIPE_SERVER_END
)
337 ReadQueue
= &Ccb
->DataQueue
[FILE_PIPE_INBOUND
];
338 WriteQueue
= &Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
];
340 NpSetFileObject(Ccb
->FileObject
[FILE_PIPE_SERVER_END
], NULL
, NULL
, TRUE
);
341 Ccb
->FileObject
[FILE_PIPE_SERVER_END
] = NULL
;
345 ReadQueue
= &Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
];
346 WriteQueue
= &Ccb
->DataQueue
[FILE_PIPE_INBOUND
];
348 NpSetFileObject(Ccb
->FileObject
[FILE_PIPE_CLIENT_END
], NULL
, NULL
, FALSE
);
349 Ccb
->FileObject
[FILE_PIPE_CLIENT_END
] = NULL
;
352 EventBuffer
= NonPagedCcb
->EventBuffer
[NamedPipeEnd
];
354 Ccb
->NamedPipeState
= FILE_PIPE_CLOSING_STATE
;
356 while (ReadQueue
->QueueState
!= Empty
)
358 ListIrp
= NpRemoveDataQueueEntry(ReadQueue
, FALSE
, List
);
361 ListIrp
->IoStatus
.Status
= STATUS_PIPE_BROKEN
;
362 InsertTailList(List
, &ListIrp
->Tail
.Overlay
.ListEntry
);
366 while (WriteQueue
->QueueState
== ReadEntries
)
368 ListIrp
= NpRemoveDataQueueEntry(WriteQueue
, FALSE
, List
);
371 ListIrp
->IoStatus
.Status
= STATUS_PIPE_BROKEN
;
372 InsertTailList(List
, &ListIrp
->Tail
.Overlay
.ListEntry
);
376 if (EventBuffer
) KeSetEvent(EventBuffer
->Event
, IO_NO_INCREMENT
, FALSE
);
380 KeBugCheckEx(NPFS_FILE_SYSTEM
, 0x1602F9, Ccb
->NamedPipeState
, 0, 0);
383 return STATUS_SUCCESS
;