3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: drivers/fs/np/create.c
6 * PURPOSE: Named pipe filesystem
7 * PROGRAMMER: David Welch <welch@cwcom.net>
10 /* INCLUDES ******************************************************************/
13 #include <ndk/iotypes.h>
19 /* FUNCTIONS *****************************************************************/
22 NpfsFindPipe(PNPFS_DEVICE_EXTENSION DeviceExt
,
23 PUNICODE_STRING PipeName
)
25 PLIST_ENTRY CurrentEntry
;
28 CurrentEntry
= DeviceExt
->PipeListHead
.Flink
;
29 while (CurrentEntry
!= &DeviceExt
->PipeListHead
)
31 Pipe
= CONTAINING_RECORD(CurrentEntry
, NPFS_PIPE
, PipeListEntry
);
32 if (RtlCompareUnicodeString(PipeName
,
36 DPRINT("<%wZ> = <%wZ>\n", PipeName
, &Pipe
->PipeName
);
40 CurrentEntry
= CurrentEntry
->Flink
;
48 NpfsFindListeningServerInstance(PNPFS_PIPE Pipe
)
50 PLIST_ENTRY CurrentEntry
;
51 PNPFS_WAITER_ENTRY Waiter
;
55 CurrentEntry
= Pipe
->WaiterListHead
.Flink
;
56 while (CurrentEntry
!= &Pipe
->WaiterListHead
)
58 Waiter
= CONTAINING_RECORD(CurrentEntry
, NPFS_WAITER_ENTRY
, Entry
);
59 Irp
= CONTAINING_RECORD(Waiter
, IRP
, Tail
.Overlay
.DriverContext
);
60 if (Waiter
->Fcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
62 DPRINT("Server found! Fcb %p\n", Waiter
->Fcb
);
64 IoAcquireCancelSpinLock(&oldIrql
);
67 IoSetCancelRoutine(Irp
, NULL
);
68 IoReleaseCancelSpinLock(oldIrql
);
71 IoReleaseCancelSpinLock(oldIrql
);
74 CurrentEntry
= CurrentEntry
->Flink
;
82 NpfsSignalAndRemoveListeningServerInstance(PNPFS_PIPE Pipe
,
85 PLIST_ENTRY CurrentEntry
;
86 PNPFS_WAITER_ENTRY Waiter
;
89 CurrentEntry
= Pipe
->WaiterListHead
.Flink
;
90 while (CurrentEntry
!= &Pipe
->WaiterListHead
)
92 Waiter
= CONTAINING_RECORD(CurrentEntry
, NPFS_WAITER_ENTRY
, Entry
);
93 if (Waiter
->Fcb
== Fcb
)
95 DPRINT("Server found! Fcb %p\n", Waiter
->Fcb
);
97 RemoveEntryList(&Waiter
->Entry
);
98 Irp
= CONTAINING_RECORD(Waiter
, IRP
, Tail
.Overlay
.DriverContext
);
99 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
100 Irp
->IoStatus
.Information
= 0;
101 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
104 CurrentEntry
= CurrentEntry
->Flink
;
110 NpfsCreate(PDEVICE_OBJECT DeviceObject
,
113 PIO_STACK_LOCATION IoStack
;
114 PFILE_OBJECT FileObject
;
117 PNPFS_FCB ServerFcb
= NULL
;
118 PNPFS_DEVICE_EXTENSION DeviceExt
;
119 BOOLEAN SpecialAccess
;
121 DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
123 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
124 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
125 FileObject
= IoStack
->FileObject
;
126 DPRINT("FileObject %p\n", FileObject
);
127 DPRINT("FileName %wZ\n", &FileObject
->FileName
);
129 Irp
->IoStatus
.Information
= 0;
131 SpecialAccess
= ((IoStack
->Parameters
.Create
.ShareAccess
& 3) == 3);
134 DPRINT("NpfsCreate() open client end for special use!\n");
138 * Step 1. Find the pipe we're trying to open.
140 KeLockMutex(&DeviceExt
->PipeListLock
);
141 Pipe
= NpfsFindPipe(DeviceExt
,
142 &FileObject
->FileName
);
145 /* Not found, bail out with error. */
146 DPRINT("No pipe found!\n");
147 KeUnlockMutex(&DeviceExt
->PipeListLock
);
148 Irp
->IoStatus
.Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
149 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
150 return STATUS_OBJECT_NAME_NOT_FOUND
;
153 KeUnlockMutex(&DeviceExt
->PipeListLock
);
156 * Acquire the lock for FCB lists. From now on no modifications to the
157 * FCB lists are allowed, because it can cause various misconsistencies.
159 KeLockMutex(&Pipe
->FcbListLock
);
162 * Step 2. Create the client FCB.
164 ClientFcb
= ExAllocatePool(NonPagedPool
, sizeof(NPFS_FCB
));
165 if (ClientFcb
== NULL
)
167 DPRINT("No memory!\n");
168 KeUnlockMutex(&Pipe
->FcbListLock
);
169 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
170 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
171 return STATUS_NO_MEMORY
;
174 ClientFcb
->Thread
= (struct ETHREAD
*)Irp
->Tail
.Overlay
.Thread
;
175 ClientFcb
->Pipe
= Pipe
;
176 ClientFcb
->PipeEnd
= FILE_PIPE_CLIENT_END
;
177 ClientFcb
->OtherSide
= NULL
;
178 ClientFcb
->PipeState
= SpecialAccess
? 0 : FILE_PIPE_DISCONNECTED_STATE
;
179 InitializeListHead(&ClientFcb
->ReadRequestListHead
);
181 DPRINT("Fcb: %x\n", ClientFcb
);
183 /* Initialize data list. */
184 if (Pipe
->OutboundQuota
)
186 ClientFcb
->Data
= ExAllocatePool(PagedPool
, Pipe
->OutboundQuota
);
187 if (ClientFcb
->Data
== NULL
)
189 DPRINT("No memory!\n");
190 ExFreePool(ClientFcb
);
191 KeUnlockMutex(&Pipe
->FcbListLock
);
192 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
193 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
194 return STATUS_NO_MEMORY
;
199 ClientFcb
->Data
= NULL
;
202 ClientFcb
->ReadPtr
= ClientFcb
->Data
;
203 ClientFcb
->WritePtr
= ClientFcb
->Data
;
204 ClientFcb
->ReadDataAvailable
= 0;
205 ClientFcb
->WriteQuotaAvailable
= Pipe
->OutboundQuota
;
206 ClientFcb
->MaxDataLength
= Pipe
->OutboundQuota
;
207 ExInitializeFastMutex(&ClientFcb
->DataListLock
);
208 KeInitializeEvent(&ClientFcb
->ConnectEvent
, SynchronizationEvent
, FALSE
);
209 KeInitializeEvent(&ClientFcb
->ReadEvent
, SynchronizationEvent
, FALSE
);
210 KeInitializeEvent(&ClientFcb
->WriteEvent
, SynchronizationEvent
, FALSE
);
214 * Step 3. Search for listening server FCB.
220 * WARNING: Point of no return! Once we get the server FCB it's
221 * possible that we completed a wait request and so we have to
222 * complete even this request.
225 ServerFcb
= NpfsFindListeningServerInstance(Pipe
);
226 if (ServerFcb
== NULL
)
228 PLIST_ENTRY CurrentEntry
;
232 * If no waiting server FCB was found then try to pick
233 * one of the listing server FCB on the pipe.
236 CurrentEntry
= Pipe
->ServerFcbListHead
.Flink
;
237 while (CurrentEntry
!= &Pipe
->ServerFcbListHead
)
239 Fcb
= CONTAINING_RECORD(CurrentEntry
, NPFS_FCB
, FcbListEntry
);
240 if (Fcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
245 CurrentEntry
= CurrentEntry
->Flink
;
249 * No one is listening to me?! I'm so lonely... :(
252 if (ServerFcb
== NULL
)
254 /* Not found, bail out with error for FILE_OPEN requests. */
255 DPRINT("No listening server fcb found!\n");
257 ExFreePool(ClientFcb
->Data
);
258 KeUnlockMutex(&Pipe
->FcbListLock
);
259 Irp
->IoStatus
.Status
= STATUS_PIPE_BUSY
;
260 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
261 return STATUS_PIPE_BUSY
;
266 /* Signal the server thread and remove it from the waiter list */
267 /* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */
268 NpfsSignalAndRemoveListeningServerInstance(Pipe
, ServerFcb
);
271 else if (IsListEmpty(&Pipe
->ServerFcbListHead
))
273 DPRINT("No server fcb found!\n");
274 KeUnlockMutex(&Pipe
->FcbListLock
);
275 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
276 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
277 return STATUS_UNSUCCESSFUL
;
281 * Step 4. Add the client FCB to a list and connect it if possible.
284 /* Add the client FCB to the pipe FCB list. */
285 InsertTailList(&Pipe
->ClientFcbListHead
, &ClientFcb
->FcbListEntry
);
287 /* Connect to listening server side */
290 ClientFcb
->OtherSide
= ServerFcb
;
291 ServerFcb
->OtherSide
= ClientFcb
;
292 ClientFcb
->PipeState
= FILE_PIPE_CONNECTED_STATE
;
293 ServerFcb
->PipeState
= FILE_PIPE_CONNECTED_STATE
;
296 KeUnlockMutex(&Pipe
->FcbListLock
);
298 FileObject
->FsContext
= ClientFcb
;
300 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
301 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
303 DPRINT("Success!\n");
305 return STATUS_SUCCESS
;
310 NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject
,
313 PIO_STACK_LOCATION IoStack
;
314 PFILE_OBJECT FileObject
;
315 PNPFS_DEVICE_EXTENSION DeviceExt
;
318 PNAMED_PIPE_CREATE_PARAMETERS Buffer
;
319 BOOLEAN NewPipe
= FALSE
;
321 DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
323 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
324 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
325 FileObject
= IoStack
->FileObject
;
326 DPRINT("FileObject %p\n", FileObject
);
327 DPRINT("Pipe name %wZ\n", &FileObject
->FileName
);
329 Buffer
= IoStack
->Parameters
.CreatePipe
.Parameters
;
331 Irp
->IoStatus
.Information
= 0;
333 Fcb
= ExAllocatePool(NonPagedPool
, sizeof(NPFS_FCB
));
336 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
337 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
338 return STATUS_NO_MEMORY
;
341 Fcb
->Thread
= (struct ETHREAD
*)Irp
->Tail
.Overlay
.Thread
;
342 KeLockMutex(&DeviceExt
->PipeListLock
);
345 * First search for existing Pipe with the same name.
347 Pipe
= NpfsFindPipe(DeviceExt
,
348 &FileObject
->FileName
);
352 * Found Pipe with the same name. Check if we are
355 KeUnlockMutex(&DeviceExt
->PipeListLock
);
357 if (Pipe
->CurrentInstances
>= Pipe
->MaximumInstances
)
359 DPRINT("Out of instances.\n");
361 Irp
->IoStatus
.Status
= STATUS_PIPE_BUSY
;
362 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
363 return STATUS_PIPE_BUSY
;
366 /* FIXME: Check pipe modes also! */
367 if (Pipe
->MaximumInstances
!= Buffer
->MaximumInstances
||
368 Pipe
->TimeOut
.QuadPart
!= Buffer
->DefaultTimeout
.QuadPart
)
370 DPRINT("Asked for invalid pipe mode.\n");
372 Irp
->IoStatus
.Status
= STATUS_ACCESS_DENIED
;
373 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
374 return STATUS_ACCESS_DENIED
;
380 Pipe
= ExAllocatePool(NonPagedPool
, sizeof(NPFS_PIPE
));
383 KeUnlockMutex(&DeviceExt
->PipeListLock
);
384 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
385 Irp
->IoStatus
.Information
= 0;
386 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
387 return STATUS_NO_MEMORY
;
390 Pipe
->PipeName
.Length
= FileObject
->FileName
.Length
;
391 Pipe
->PipeName
.MaximumLength
= Pipe
->PipeName
.Length
+ sizeof(UNICODE_NULL
);
392 Pipe
->PipeName
.Buffer
= ExAllocatePool(NonPagedPool
, Pipe
->PipeName
.MaximumLength
);
393 if (Pipe
->PipeName
.Buffer
== NULL
)
395 KeUnlockMutex(&DeviceExt
->PipeListLock
);
398 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
399 Irp
->IoStatus
.Information
= 0;
400 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
401 return STATUS_NO_MEMORY
;
404 RtlCopyUnicodeString(&Pipe
->PipeName
, &FileObject
->FileName
);
406 InitializeListHead(&Pipe
->ServerFcbListHead
);
407 InitializeListHead(&Pipe
->ClientFcbListHead
);
408 InitializeListHead(&Pipe
->WaiterListHead
);
409 KeInitializeMutex(&Pipe
->FcbListLock
, 0);
411 Pipe
->PipeType
= Buffer
->NamedPipeType
;
412 Pipe
->WriteMode
= Buffer
->ReadMode
;
413 Pipe
->ReadMode
= Buffer
->ReadMode
;
414 Pipe
->CompletionMode
= Buffer
->CompletionMode
;
415 Pipe
->PipeConfiguration
= IoStack
->Parameters
.CreatePipe
.Options
& 0x3;
416 Pipe
->MaximumInstances
= Buffer
->MaximumInstances
;
417 Pipe
->CurrentInstances
= 0;
418 Pipe
->TimeOut
= Buffer
->DefaultTimeout
;
419 if (!(IoStack
->Parameters
.Create
.Options
& FILE_PIPE_OUTBOUND
) ||
420 IoStack
->Parameters
.Create
.Options
& FILE_PIPE_FULL_DUPLEX
)
422 if (Buffer
->InboundQuota
== 0)
424 Pipe
->InboundQuota
= DeviceExt
->DefaultQuota
;
428 Pipe
->InboundQuota
= PAGE_ROUND_UP(Buffer
->InboundQuota
);
429 if (Pipe
->InboundQuota
< DeviceExt
->MinQuota
)
431 Pipe
->InboundQuota
= DeviceExt
->MinQuota
;
433 else if (Pipe
->InboundQuota
> DeviceExt
->MaxQuota
)
435 Pipe
->InboundQuota
= DeviceExt
->MaxQuota
;
441 Pipe
->InboundQuota
= 0;
444 if (IoStack
->Parameters
.Create
.Options
& (FILE_PIPE_FULL_DUPLEX
|FILE_PIPE_OUTBOUND
))
446 if (Buffer
->OutboundQuota
== 0)
448 Pipe
->OutboundQuota
= DeviceExt
->DefaultQuota
;
452 Pipe
->OutboundQuota
= PAGE_ROUND_UP(Buffer
->OutboundQuota
);
453 if (Pipe
->OutboundQuota
< DeviceExt
->MinQuota
)
455 Pipe
->OutboundQuota
= DeviceExt
->MinQuota
;
457 else if (Pipe
->OutboundQuota
> DeviceExt
->MaxQuota
)
459 Pipe
->OutboundQuota
= DeviceExt
->MaxQuota
;
465 Pipe
->OutboundQuota
= 0;
468 InsertTailList(&DeviceExt
->PipeListHead
, &Pipe
->PipeListEntry
);
469 KeUnlockMutex(&DeviceExt
->PipeListLock
);
472 if (Pipe
->InboundQuota
)
474 Fcb
->Data
= ExAllocatePool(PagedPool
, Pipe
->InboundQuota
);
475 if (Fcb
->Data
== NULL
)
481 KeLockMutex(&DeviceExt
->PipeListLock
);
482 RemoveEntryList(&Pipe
->PipeListEntry
);
483 KeUnlockMutex(&DeviceExt
->PipeListLock
);
484 RtlFreeUnicodeString(&Pipe
->PipeName
);
488 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
489 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
490 return STATUS_NO_MEMORY
;
498 Fcb
->ReadPtr
= Fcb
->Data
;
499 Fcb
->WritePtr
= Fcb
->Data
;
500 Fcb
->ReadDataAvailable
= 0;
501 Fcb
->WriteQuotaAvailable
= Pipe
->InboundQuota
;
502 Fcb
->MaxDataLength
= Pipe
->InboundQuota
;
503 InitializeListHead(&Fcb
->ReadRequestListHead
);
504 ExInitializeFastMutex(&Fcb
->DataListLock
);
506 Pipe
->CurrentInstances
++;
509 Fcb
->PipeEnd
= FILE_PIPE_SERVER_END
;
510 Fcb
->PipeState
= FILE_PIPE_LISTENING_STATE
;
511 Fcb
->OtherSide
= NULL
;
513 DPRINT("Fcb: %x\n", Fcb
);
515 KeInitializeEvent(&Fcb
->ConnectEvent
, SynchronizationEvent
, FALSE
);
516 KeInitializeEvent(&Fcb
->ReadEvent
, SynchronizationEvent
, FALSE
);
517 KeInitializeEvent(&Fcb
->WriteEvent
, SynchronizationEvent
, FALSE
);
519 KeLockMutex(&Pipe
->FcbListLock
);
520 InsertTailList(&Pipe
->ServerFcbListHead
, &Fcb
->FcbListEntry
);
521 KeUnlockMutex(&Pipe
->FcbListLock
);
523 FileObject
->FsContext
= Fcb
;
525 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
526 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
528 DPRINT("Success!\n");
530 return STATUS_SUCCESS
;
535 NpfsCleanup(PDEVICE_OBJECT DeviceObject
,
538 PNPFS_DEVICE_EXTENSION DeviceExt
;
539 PIO_STACK_LOCATION IoStack
;
540 PFILE_OBJECT FileObject
;
541 PNPFS_FCB Fcb
, OtherSide
;
545 DPRINT("NpfsCleanup(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
547 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
548 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
549 FileObject
= IoStack
->FileObject
;
550 Fcb
= FileObject
->FsContext
;
554 DPRINT("Success!\n");
555 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
556 Irp
->IoStatus
.Information
= 0;
557 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
558 return STATUS_SUCCESS
;
561 DPRINT("Fcb %x\n", Fcb
);
564 DPRINT("Cleaning pipe %wZ\n", &Pipe
->PipeName
);
566 KeLockMutex(&Pipe
->FcbListLock
);
568 Server
= (Fcb
->PipeEnd
== FILE_PIPE_SERVER_END
);
572 /* FIXME: Clean up existing connections here ?? */
579 if (Fcb
->PipeState
== FILE_PIPE_CONNECTED_STATE
)
581 OtherSide
= Fcb
->OtherSide
;
582 /* Lock the server first */
585 ExAcquireFastMutex(&Fcb
->DataListLock
);
586 ExAcquireFastMutex(&OtherSide
->DataListLock
);
590 ExAcquireFastMutex(&OtherSide
->DataListLock
);
591 ExAcquireFastMutex(&Fcb
->DataListLock
);
593 OtherSide
->PipeState
= FILE_PIPE_DISCONNECTED_STATE
;
594 OtherSide
->OtherSide
= NULL
;
596 * Signaling the write event. If is possible that an other
597 * thread waits for an empty buffer.
599 KeSetEvent(&OtherSide
->ReadEvent
, IO_NO_INCREMENT
, FALSE
);
600 KeSetEvent(&OtherSide
->WriteEvent
, IO_NO_INCREMENT
, FALSE
);
603 ExReleaseFastMutex(&Fcb
->DataListLock
);
604 ExReleaseFastMutex(&OtherSide
->DataListLock
);
608 ExReleaseFastMutex(&OtherSide
->DataListLock
);
609 ExReleaseFastMutex(&Fcb
->DataListLock
);
612 else if (Fcb
->PipeState
== FILE_PIPE_LISTENING_STATE
)
615 PNPFS_WAITER_ENTRY WaitEntry
= NULL
;
616 BOOLEAN Complete
= FALSE
;
620 Entry
= Fcb
->Pipe
->WaiterListHead
.Flink
;
621 while (Entry
!= &Fcb
->Pipe
->WaiterListHead
)
623 WaitEntry
= CONTAINING_RECORD(Entry
, NPFS_WAITER_ENTRY
, Entry
);
624 if (WaitEntry
->Fcb
== Fcb
)
626 RemoveEntryList(Entry
);
627 tmpIrp
= CONTAINING_RECORD(WaitEntry
, IRP
, Tail
.Overlay
.DriverContext
);
628 IoAcquireCancelSpinLock(&oldIrql
);
631 IoSetCancelRoutine(tmpIrp
, NULL
);
634 IoReleaseCancelSpinLock(oldIrql
);
637 tmpIrp
->IoStatus
.Status
= STATUS_PIPE_BROKEN
;
638 tmpIrp
->IoStatus
.Information
= 0;
639 IoCompleteRequest(tmpIrp
, IO_NO_INCREMENT
);
643 Entry
= Entry
->Flink
;
647 Fcb
->PipeState
= FILE_PIPE_CLOSING_STATE
;
649 KeUnlockMutex(&Pipe
->FcbListLock
);
651 ExAcquireFastMutex(&Fcb
->DataListLock
);
654 ExFreePool(Fcb
->Data
);
657 Fcb
->WritePtr
= NULL
;
659 ExReleaseFastMutex(&Fcb
->DataListLock
);
661 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
662 Irp
->IoStatus
.Information
= 0;
663 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
665 DPRINT("Success!\n");
667 return STATUS_SUCCESS
;
671 NpfsClose(PDEVICE_OBJECT DeviceObject
,
674 PNPFS_DEVICE_EXTENSION DeviceExt
;
675 PIO_STACK_LOCATION IoStack
;
676 PFILE_OBJECT FileObject
;
681 DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
683 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
684 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
685 FileObject
= IoStack
->FileObject
;
686 Fcb
= FileObject
->FsContext
;
690 DPRINT("Success!\n");
691 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
692 Irp
->IoStatus
.Information
= 0;
693 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
694 return STATUS_SUCCESS
;
697 DPRINT("Fcb %x\n", Fcb
);
700 DPRINT("Closing pipe %wZ\n", &Pipe
->PipeName
);
702 KeLockMutex(&Pipe
->FcbListLock
);
704 Server
= (Fcb
->PipeEnd
== FILE_PIPE_SERVER_END
);
709 Pipe
->CurrentInstances
--;
716 ASSERT (Fcb
->PipeState
== FILE_PIPE_CLOSING_STATE
);
718 FileObject
->FsContext
= NULL
;
720 RemoveEntryList(&Fcb
->FcbListEntry
);
724 KeUnlockMutex(&Pipe
->FcbListLock
);
726 if (IsListEmpty(&Pipe
->ServerFcbListHead
) &&
727 IsListEmpty(&Pipe
->ClientFcbListHead
))
729 RtlFreeUnicodeString(&Pipe
->PipeName
);
730 KeLockMutex(&DeviceExt
->PipeListLock
);
731 RemoveEntryList(&Pipe
->PipeListEntry
);
732 KeUnlockMutex(&DeviceExt
->PipeListLock
);
736 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
737 Irp
->IoStatus
.Information
= 0;
738 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
740 DPRINT("Success!\n");
742 return STATUS_SUCCESS
;