2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/fs/np/create.c
5 * PURPOSE: Named pipe filesystem
6 * PROGRAMMER: David Welch <welch@cwcom.net>
9 /* INCLUDES ******************************************************************/
16 /* FUNCTIONS *****************************************************************/
19 NpfsFindPipe(PNPFS_DEVICE_EXTENSION DeviceExt
,
20 PUNICODE_STRING PipeName
)
22 PLIST_ENTRY CurrentEntry
;
25 CurrentEntry
= DeviceExt
->PipeListHead
.Flink
;
26 while (CurrentEntry
!= &DeviceExt
->PipeListHead
)
28 Pipe
= CONTAINING_RECORD(CurrentEntry
, NPFS_PIPE
, PipeListEntry
);
29 if (RtlCompareUnicodeString(PipeName
,
33 DPRINT("<%wZ> = <%wZ>\n", PipeName
, &Pipe
->PipeName
);
37 CurrentEntry
= CurrentEntry
->Flink
;
45 NpfsFindListeningServerInstance(PNPFS_PIPE Pipe
)
47 PLIST_ENTRY CurrentEntry
;
48 PNPFS_WAITER_ENTRY Waiter
;
52 CurrentEntry
= Pipe
->WaiterListHead
.Flink
;
53 while (CurrentEntry
!= &Pipe
->WaiterListHead
)
55 Waiter
= CONTAINING_RECORD(CurrentEntry
, NPFS_WAITER_ENTRY
, Entry
);
56 Irp
= CONTAINING_RECORD(Waiter
, IRP
, Tail
.Overlay
.DriverContext
);
57 if (Waiter
->Fcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
59 DPRINT("Server found! Fcb %p\n", Waiter
->Fcb
);
61 IoAcquireCancelSpinLock(&oldIrql
);
64 IoSetCancelRoutine(Irp
, NULL
);
65 IoReleaseCancelSpinLock(oldIrql
);
68 IoReleaseCancelSpinLock(oldIrql
);
71 CurrentEntry
= CurrentEntry
->Flink
;
79 NpfsSignalAndRemoveListeningServerInstance(PNPFS_PIPE Pipe
,
82 PLIST_ENTRY CurrentEntry
;
83 PNPFS_WAITER_ENTRY Waiter
;
86 CurrentEntry
= Pipe
->WaiterListHead
.Flink
;
87 while (CurrentEntry
!= &Pipe
->WaiterListHead
)
89 Waiter
= CONTAINING_RECORD(CurrentEntry
, NPFS_WAITER_ENTRY
, Entry
);
90 if (Waiter
->Fcb
== Fcb
)
92 DPRINT("Server found! Fcb %p\n", Waiter
->Fcb
);
94 RemoveEntryList(&Waiter
->Entry
);
95 Irp
= CONTAINING_RECORD(Waiter
, IRP
, Tail
.Overlay
.DriverContext
);
96 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
97 Irp
->IoStatus
.Information
= 0;
98 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
101 CurrentEntry
= CurrentEntry
->Flink
;
107 NpfsCreate(PDEVICE_OBJECT DeviceObject
,
110 PEXTENDED_IO_STACK_LOCATION IoStack
;
111 PFILE_OBJECT FileObject
;
114 PNPFS_FCB ServerFcb
= NULL
;
115 PNPFS_DEVICE_EXTENSION DeviceExt
;
116 BOOLEAN SpecialAccess
;
118 DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
120 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
121 IoStack
= (PEXTENDED_IO_STACK_LOCATION
)IoGetCurrentIrpStackLocation(Irp
);
122 FileObject
= IoStack
->FileObject
;
123 DPRINT("FileObject %p\n", FileObject
);
124 DPRINT("FileName %wZ\n", &FileObject
->FileName
);
126 Irp
->IoStatus
.Information
= 0;
128 SpecialAccess
= ((IoStack
->Parameters
.CreatePipe
.ShareAccess
& 3) == 3);
131 DPRINT("NpfsCreate() open client end for special use!\n");
135 * Step 1. Find the pipe we're trying to open.
137 KeLockMutex(&DeviceExt
->PipeListLock
);
138 Pipe
= NpfsFindPipe(DeviceExt
,
139 &FileObject
->FileName
);
142 /* Not found, bail out with error. */
143 DPRINT("No pipe found!\n");
144 KeUnlockMutex(&DeviceExt
->PipeListLock
);
145 Irp
->IoStatus
.Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
146 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
147 return STATUS_OBJECT_NAME_NOT_FOUND
;
150 KeUnlockMutex(&DeviceExt
->PipeListLock
);
153 * Acquire the lock for FCB lists. From now on no modifications to the
154 * FCB lists are allowed, because it can cause various misconsistencies.
156 KeLockMutex(&Pipe
->FcbListLock
);
159 * Step 2. Create the client FCB.
161 ClientFcb
= ExAllocatePool(NonPagedPool
, sizeof(NPFS_FCB
));
162 if (ClientFcb
== NULL
)
164 DPRINT("No memory!\n");
165 KeUnlockMutex(&Pipe
->FcbListLock
);
166 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
167 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
168 return STATUS_NO_MEMORY
;
171 ClientFcb
->Thread
= (struct ETHREAD
*)Irp
->Tail
.Overlay
.Thread
;
172 ClientFcb
->Pipe
= Pipe
;
173 ClientFcb
->PipeEnd
= FILE_PIPE_CLIENT_END
;
174 ClientFcb
->OtherSide
= NULL
;
175 ClientFcb
->PipeState
= SpecialAccess
? 0 : FILE_PIPE_DISCONNECTED_STATE
;
176 InitializeListHead(&ClientFcb
->ReadRequestListHead
);
178 DPRINT("Fcb: %x\n", ClientFcb
);
180 /* Initialize data list. */
181 if (Pipe
->OutboundQuota
)
183 ClientFcb
->Data
= ExAllocatePool(PagedPool
, Pipe
->OutboundQuota
);
184 if (ClientFcb
->Data
== NULL
)
186 DPRINT("No memory!\n");
187 ExFreePool(ClientFcb
);
188 KeUnlockMutex(&Pipe
->FcbListLock
);
189 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
190 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
191 return STATUS_NO_MEMORY
;
196 ClientFcb
->Data
= NULL
;
199 ClientFcb
->ReadPtr
= ClientFcb
->Data
;
200 ClientFcb
->WritePtr
= ClientFcb
->Data
;
201 ClientFcb
->ReadDataAvailable
= 0;
202 ClientFcb
->WriteQuotaAvailable
= Pipe
->OutboundQuota
;
203 ClientFcb
->MaxDataLength
= Pipe
->OutboundQuota
;
204 ExInitializeFastMutex(&ClientFcb
->DataListLock
);
205 KeInitializeEvent(&ClientFcb
->ConnectEvent
, SynchronizationEvent
, FALSE
);
206 KeInitializeEvent(&ClientFcb
->ReadEvent
, SynchronizationEvent
, FALSE
);
207 KeInitializeEvent(&ClientFcb
->WriteEvent
, SynchronizationEvent
, FALSE
);
211 * Step 3. Search for listening server FCB.
217 * WARNING: Point of no return! Once we get the server FCB it's
218 * possible that we completed a wait request and so we have to
219 * complete even this request.
222 ServerFcb
= NpfsFindListeningServerInstance(Pipe
);
223 if (ServerFcb
== NULL
)
225 PLIST_ENTRY CurrentEntry
;
229 * If no waiting server FCB was found then try to pick
230 * one of the listing server FCB on the pipe.
233 CurrentEntry
= Pipe
->ServerFcbListHead
.Flink
;
234 while (CurrentEntry
!= &Pipe
->ServerFcbListHead
)
236 Fcb
= CONTAINING_RECORD(CurrentEntry
, NPFS_FCB
, FcbListEntry
);
237 if (Fcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
242 CurrentEntry
= CurrentEntry
->Flink
;
246 * No one is listening to me?! I'm so lonely... :(
249 if (ServerFcb
== NULL
)
251 /* Not found, bail out with error for FILE_OPEN requests. */
252 DPRINT("No listening server fcb found!\n");
254 ExFreePool(ClientFcb
->Data
);
255 KeUnlockMutex(&Pipe
->FcbListLock
);
256 Irp
->IoStatus
.Status
= STATUS_PIPE_BUSY
;
257 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
258 return STATUS_PIPE_BUSY
;
263 /* Signal the server thread and remove it from the waiter list */
264 /* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */
265 NpfsSignalAndRemoveListeningServerInstance(Pipe
, ServerFcb
);
268 else if (IsListEmpty(&Pipe
->ServerFcbListHead
))
270 DPRINT("No server fcb found!\n");
271 KeUnlockMutex(&Pipe
->FcbListLock
);
272 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
273 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
274 return STATUS_UNSUCCESSFUL
;
278 * Step 4. Add the client FCB to a list and connect it if possible.
281 /* Add the client FCB to the pipe FCB list. */
282 InsertTailList(&Pipe
->ClientFcbListHead
, &ClientFcb
->FcbListEntry
);
284 /* Connect to listening server side */
287 ClientFcb
->OtherSide
= ServerFcb
;
288 ServerFcb
->OtherSide
= ClientFcb
;
289 ClientFcb
->PipeState
= FILE_PIPE_CONNECTED_STATE
;
290 ServerFcb
->PipeState
= FILE_PIPE_CONNECTED_STATE
;
293 KeUnlockMutex(&Pipe
->FcbListLock
);
295 FileObject
->FsContext
= ClientFcb
;
297 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
298 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
300 DPRINT("Success!\n");
302 return STATUS_SUCCESS
;
307 NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject
,
310 PEXTENDED_IO_STACK_LOCATION IoStack
;
311 PFILE_OBJECT FileObject
;
312 PNPFS_DEVICE_EXTENSION DeviceExt
;
315 PNAMED_PIPE_CREATE_PARAMETERS Buffer
;
316 BOOLEAN NewPipe
= FALSE
;
318 DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
320 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
321 IoStack
= (PEXTENDED_IO_STACK_LOCATION
)IoGetCurrentIrpStackLocation(Irp
);
322 FileObject
= IoStack
->FileObject
;
323 DPRINT("FileObject %p\n", FileObject
);
324 DPRINT("Pipe name %wZ\n", &FileObject
->FileName
);
326 Buffer
= IoStack
->Parameters
.CreatePipe
.Parameters
;
328 Irp
->IoStatus
.Information
= 0;
330 Fcb
= ExAllocatePool(NonPagedPool
, sizeof(NPFS_FCB
));
333 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
334 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
335 return STATUS_NO_MEMORY
;
338 Fcb
->Thread
= (struct ETHREAD
*)Irp
->Tail
.Overlay
.Thread
;
339 KeLockMutex(&DeviceExt
->PipeListLock
);
342 * First search for existing Pipe with the same name.
344 Pipe
= NpfsFindPipe(DeviceExt
,
345 &FileObject
->FileName
);
349 * Found Pipe with the same name. Check if we are
352 KeUnlockMutex(&DeviceExt
->PipeListLock
);
354 if (Pipe
->CurrentInstances
>= Pipe
->MaximumInstances
)
356 DPRINT("Out of instances.\n");
358 Irp
->IoStatus
.Status
= STATUS_PIPE_BUSY
;
359 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
360 return STATUS_PIPE_BUSY
;
363 /* FIXME: Check pipe modes also! */
364 if (Pipe
->MaximumInstances
!= Buffer
->MaximumInstances
||
365 Pipe
->TimeOut
.QuadPart
!= Buffer
->DefaultTimeout
.QuadPart
)
367 DPRINT("Asked for invalid pipe mode.\n");
369 Irp
->IoStatus
.Status
= STATUS_ACCESS_DENIED
;
370 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
371 return STATUS_ACCESS_DENIED
;
377 Pipe
= ExAllocatePool(NonPagedPool
, sizeof(NPFS_PIPE
));
380 KeUnlockMutex(&DeviceExt
->PipeListLock
);
381 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
382 Irp
->IoStatus
.Information
= 0;
383 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
384 return STATUS_NO_MEMORY
;
387 Pipe
->PipeName
.Length
= FileObject
->FileName
.Length
;
388 Pipe
->PipeName
.MaximumLength
= Pipe
->PipeName
.Length
+ sizeof(UNICODE_NULL
);
389 Pipe
->PipeName
.Buffer
= ExAllocatePool(NonPagedPool
, Pipe
->PipeName
.MaximumLength
);
390 if (Pipe
->PipeName
.Buffer
== NULL
)
392 KeUnlockMutex(&DeviceExt
->PipeListLock
);
395 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
396 Irp
->IoStatus
.Information
= 0;
397 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
398 return STATUS_NO_MEMORY
;
401 RtlCopyUnicodeString(&Pipe
->PipeName
, &FileObject
->FileName
);
403 InitializeListHead(&Pipe
->ServerFcbListHead
);
404 InitializeListHead(&Pipe
->ClientFcbListHead
);
405 InitializeListHead(&Pipe
->WaiterListHead
);
406 KeInitializeMutex(&Pipe
->FcbListLock
, 0);
408 Pipe
->PipeType
= Buffer
->NamedPipeType
;
409 Pipe
->WriteMode
= Buffer
->ReadMode
;
410 Pipe
->ReadMode
= Buffer
->ReadMode
;
411 Pipe
->CompletionMode
= Buffer
->CompletionMode
;
412 Pipe
->PipeConfiguration
= IoStack
->Parameters
.CreatePipe
.Options
& 0x3;
413 Pipe
->MaximumInstances
= Buffer
->MaximumInstances
;
414 Pipe
->CurrentInstances
= 0;
415 Pipe
->TimeOut
= Buffer
->DefaultTimeout
;
416 if (!(IoStack
->Parameters
.CreatePipe
.Options
& FILE_PIPE_OUTBOUND
) ||
417 IoStack
->Parameters
.CreatePipe
.Options
& FILE_PIPE_FULL_DUPLEX
)
419 if (Buffer
->InboundQuota
== 0)
421 Pipe
->InboundQuota
= DeviceExt
->DefaultQuota
;
425 Pipe
->InboundQuota
= PAGE_ROUND_UP(Buffer
->InboundQuota
);
426 if (Pipe
->InboundQuota
< DeviceExt
->MinQuota
)
428 Pipe
->InboundQuota
= DeviceExt
->MinQuota
;
430 else if (Pipe
->InboundQuota
> DeviceExt
->MaxQuota
)
432 Pipe
->InboundQuota
= DeviceExt
->MaxQuota
;
438 Pipe
->InboundQuota
= 0;
441 if (IoStack
->Parameters
.CreatePipe
.Options
& (FILE_PIPE_FULL_DUPLEX
|FILE_PIPE_OUTBOUND
))
443 if (Buffer
->OutboundQuota
== 0)
445 Pipe
->OutboundQuota
= DeviceExt
->DefaultQuota
;
449 Pipe
->OutboundQuota
= PAGE_ROUND_UP(Buffer
->OutboundQuota
);
450 if (Pipe
->OutboundQuota
< DeviceExt
->MinQuota
)
452 Pipe
->OutboundQuota
= DeviceExt
->MinQuota
;
454 else if (Pipe
->OutboundQuota
> DeviceExt
->MaxQuota
)
456 Pipe
->OutboundQuota
= DeviceExt
->MaxQuota
;
462 Pipe
->OutboundQuota
= 0;
465 InsertTailList(&DeviceExt
->PipeListHead
, &Pipe
->PipeListEntry
);
466 KeUnlockMutex(&DeviceExt
->PipeListLock
);
469 if (Pipe
->InboundQuota
)
471 Fcb
->Data
= ExAllocatePool(PagedPool
, Pipe
->InboundQuota
);
472 if (Fcb
->Data
== NULL
)
478 KeLockMutex(&DeviceExt
->PipeListLock
);
479 RemoveEntryList(&Pipe
->PipeListEntry
);
480 KeUnlockMutex(&DeviceExt
->PipeListLock
);
481 RtlFreeUnicodeString(&Pipe
->PipeName
);
485 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
486 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
487 return STATUS_NO_MEMORY
;
495 Fcb
->ReadPtr
= Fcb
->Data
;
496 Fcb
->WritePtr
= Fcb
->Data
;
497 Fcb
->ReadDataAvailable
= 0;
498 Fcb
->WriteQuotaAvailable
= Pipe
->InboundQuota
;
499 Fcb
->MaxDataLength
= Pipe
->InboundQuota
;
500 InitializeListHead(&Fcb
->ReadRequestListHead
);
501 ExInitializeFastMutex(&Fcb
->DataListLock
);
503 Pipe
->CurrentInstances
++;
506 Fcb
->PipeEnd
= FILE_PIPE_SERVER_END
;
507 Fcb
->PipeState
= FILE_PIPE_LISTENING_STATE
;
508 Fcb
->OtherSide
= NULL
;
510 DPRINT("Fcb: %x\n", Fcb
);
512 KeInitializeEvent(&Fcb
->ConnectEvent
, SynchronizationEvent
, FALSE
);
513 KeInitializeEvent(&Fcb
->ReadEvent
, SynchronizationEvent
, FALSE
);
514 KeInitializeEvent(&Fcb
->WriteEvent
, SynchronizationEvent
, FALSE
);
516 KeLockMutex(&Pipe
->FcbListLock
);
517 InsertTailList(&Pipe
->ServerFcbListHead
, &Fcb
->FcbListEntry
);
518 KeUnlockMutex(&Pipe
->FcbListLock
);
520 FileObject
->FsContext
= Fcb
;
522 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
523 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
525 DPRINT("Success!\n");
527 return STATUS_SUCCESS
;
532 NpfsCleanup(PDEVICE_OBJECT DeviceObject
,
535 PNPFS_DEVICE_EXTENSION DeviceExt
;
536 PIO_STACK_LOCATION IoStack
;
537 PFILE_OBJECT FileObject
;
538 PNPFS_FCB Fcb
, OtherSide
;
542 DPRINT("NpfsCleanup(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
544 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
545 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
546 FileObject
= IoStack
->FileObject
;
547 Fcb
= FileObject
->FsContext
;
551 DPRINT("Success!\n");
552 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
553 Irp
->IoStatus
.Information
= 0;
554 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
555 return STATUS_SUCCESS
;
558 DPRINT("Fcb %x\n", Fcb
);
561 DPRINT("Cleaning pipe %wZ\n", &Pipe
->PipeName
);
563 KeLockMutex(&Pipe
->FcbListLock
);
565 Server
= (Fcb
->PipeEnd
== FILE_PIPE_SERVER_END
);
569 /* FIXME: Clean up existing connections here ?? */
576 if (Fcb
->PipeState
== FILE_PIPE_CONNECTED_STATE
)
578 OtherSide
= Fcb
->OtherSide
;
579 /* Lock the server first */
582 ExAcquireFastMutex(&Fcb
->DataListLock
);
583 ExAcquireFastMutex(&OtherSide
->DataListLock
);
587 ExAcquireFastMutex(&OtherSide
->DataListLock
);
588 ExAcquireFastMutex(&Fcb
->DataListLock
);
590 OtherSide
->PipeState
= FILE_PIPE_DISCONNECTED_STATE
;
591 OtherSide
->OtherSide
= NULL
;
593 * Signaling the write event. If is possible that an other
594 * thread waits for an empty buffer.
596 KeSetEvent(&OtherSide
->ReadEvent
, IO_NO_INCREMENT
, FALSE
);
597 KeSetEvent(&OtherSide
->WriteEvent
, IO_NO_INCREMENT
, FALSE
);
600 ExReleaseFastMutex(&Fcb
->DataListLock
);
601 ExReleaseFastMutex(&OtherSide
->DataListLock
);
605 ExReleaseFastMutex(&OtherSide
->DataListLock
);
606 ExReleaseFastMutex(&Fcb
->DataListLock
);
609 else if (Fcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
612 PNPFS_WAITER_ENTRY WaitEntry
= NULL
;
613 BOOLEAN Complete
= FALSE
;
617 Entry
= Fcb
->Pipe
->WaiterListHead
.Flink
;
618 while (Entry
!= &Fcb
->Pipe
->WaiterListHead
)
620 WaitEntry
= CONTAINING_RECORD(Entry
, NPFS_WAITER_ENTRY
, Entry
);
621 if (WaitEntry
->Fcb
== Fcb
)
623 RemoveEntryList(Entry
);
624 tmpIrp
= CONTAINING_RECORD(WaitEntry
, IRP
, Tail
.Overlay
.DriverContext
);
625 IoAcquireCancelSpinLock(&oldIrql
);
628 IoSetCancelRoutine(tmpIrp
, NULL
);
631 IoReleaseCancelSpinLock(oldIrql
);
634 tmpIrp
->IoStatus
.Status
= STATUS_PIPE_BROKEN
;
635 tmpIrp
->IoStatus
.Information
= 0;
636 IoCompleteRequest(tmpIrp
, IO_NO_INCREMENT
);
640 Entry
= Entry
->Flink
;
644 Fcb
->PipeState
= FILE_PIPE_CLOSING_STATE
;
646 KeUnlockMutex(&Pipe
->FcbListLock
);
648 ExAcquireFastMutex(&Fcb
->DataListLock
);
651 ExFreePool(Fcb
->Data
);
654 Fcb
->WritePtr
= NULL
;
656 ExReleaseFastMutex(&Fcb
->DataListLock
);
658 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
659 Irp
->IoStatus
.Information
= 0;
660 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
662 DPRINT("Success!\n");
664 return STATUS_SUCCESS
;
668 NpfsClose(PDEVICE_OBJECT DeviceObject
,
671 PNPFS_DEVICE_EXTENSION DeviceExt
;
672 PIO_STACK_LOCATION IoStack
;
673 PFILE_OBJECT FileObject
;
678 DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
680 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
681 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
682 FileObject
= IoStack
->FileObject
;
683 Fcb
= FileObject
->FsContext
;
687 DPRINT("Success!\n");
688 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
689 Irp
->IoStatus
.Information
= 0;
690 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
691 return STATUS_SUCCESS
;
694 DPRINT("Fcb %x\n", Fcb
);
697 DPRINT("Closing pipe %wZ\n", &Pipe
->PipeName
);
699 KeLockMutex(&Pipe
->FcbListLock
);
701 Server
= (Fcb
->PipeEnd
== FILE_PIPE_SERVER_END
);
706 Pipe
->CurrentInstances
--;
713 ASSERT (Fcb
->PipeState
== FILE_PIPE_CLOSING_STATE
);
715 FileObject
->FsContext
= NULL
;
717 RemoveEntryList(&Fcb
->FcbListEntry
);
721 KeUnlockMutex(&Pipe
->FcbListLock
);
723 if (IsListEmpty(&Pipe
->ServerFcbListHead
) &&
724 IsListEmpty(&Pipe
->ClientFcbListHead
))
726 RtlFreeUnicodeString(&Pipe
->PipeName
);
727 KeLockMutex(&DeviceExt
->PipeListLock
);
728 RemoveEntryList(&Pipe
->PipeListEntry
);
729 KeUnlockMutex(&DeviceExt
->PipeListLock
);
733 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
734 Irp
->IoStatus
.Information
= 0;
735 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
737 DPRINT("Success!\n");
739 return STATUS_SUCCESS
;