1 /* $Id: create.c,v 1.7 2001/06/12 12:35:04 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/fs/np/create.c
6 * PURPOSE: Named pipe filesystem
7 * PROGRAMMER: David Welch <welch@cwcom.net>
10 /* INCLUDES ******************************************************************/
12 #include <ddk/ntddk.h>
20 /* GLOBALS *******************************************************************/
23 /* FUNCTIONS *****************************************************************/
26 NpfsCreate(PDEVICE_OBJECT DeviceObject
,
29 PIO_STACK_LOCATION IoStack
;
30 PFILE_OBJECT FileObject
;
36 PLIST_ENTRY current_entry
;
37 PNPFS_DEVICE_EXTENSION DeviceExt
;
40 DPRINT1("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
42 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
43 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
44 FileObject
= IoStack
->FileObject
;
45 DPRINT("FileObject %p\n", FileObject
);
47 Fcb
= ExAllocatePool(NonPagedPool
, sizeof(NPFS_FCB
));
50 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
51 Irp
->IoStatus
.Information
= 0;
53 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
55 return(STATUS_NO_MEMORY
);
58 KeLockMutex(&DeviceExt
->PipeListLock
);
59 current_entry
= DeviceExt
->PipeListHead
.Flink
;
60 while (current_entry
!= &DeviceExt
->PipeListHead
)
62 current
= CONTAINING_RECORD(current_entry
,
66 if (RtlCompareUnicodeString(&Pipe
->PipeName
,
73 current_entry
= current_entry
->Flink
;
76 if (current_entry
== &DeviceExt
->PipeListHead
)
79 KeUnlockMutex(&DeviceExt
->PipeListLock
);
81 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
82 Irp
->IoStatus
.Information
= 0;
84 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
86 return(STATUS_UNSUCCESSFUL
);
91 Fcb
->WriteModeMessage
= FALSE
;
92 Fcb
->ReadModeMessage
= FALSE
;
93 Fcb
->NonBlocking
= FALSE
;
94 Fcb
->InBufferSize
= PAGESIZE
;
95 Fcb
->OutBufferSize
= PAGESIZE
;
97 Fcb
->IsServer
= FALSE
;
98 Fcb
->OtherSide
= NULL
;
100 /* search for disconnected server fcb */
102 current_entry
= Pipe
->FcbListHead
.Flink
;
103 while (current_entry
!= &Pipe
->FcbListHead
)
105 ServerFcb
= CONTAINING_RECORD(current_entry
,
109 DPRINT("ServerFcb->IsServer: %x\n", ServerFcb
->IsServer
);
110 DPRINT("ServerFcb->OtherSide: %p\n", ServerFcb
->OtherSide
);
111 if ((ServerFcb
->IsServer
== TRUE
) && (ServerFcb
->OtherSide
== NULL
))
113 DPRINT("Server found! Fcb %p\n", ServerFcb
);
117 current_entry
= current_entry
->Flink
;
120 if (current_entry
== &Pipe
->FcbListHead
)
122 DPRINT("No server fcb found!\n");
125 KeUnlockMutex(&DeviceExt
->PipeListLock
);
127 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
128 Irp
->IoStatus
.Information
= 0;
130 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
132 return(STATUS_UNSUCCESSFUL
);
135 KeAcquireSpinLock(&Pipe
->FcbListLock
, &oldIrql
);
136 InsertTailList(&Pipe
->FcbListHead
, &Fcb
->FcbListEntry
);
137 KeReleaseSpinLock(&Pipe
->FcbListLock
, oldIrql
);
139 Pipe
->ReferenceCount
++;
142 Fcb
->OtherSide
= ServerFcb
;
143 ServerFcb
->OtherSide
= Fcb
;
145 KeSetEvent(&ServerFcb
->ConnectEvent
, 0, FALSE
);
147 KeUnlockMutex(&DeviceExt
->PipeListLock
);
149 FileObject
->FsContext
= Fcb
;
151 Irp
->IoStatus
.Status
= Status
;
152 Irp
->IoStatus
.Information
= 0;
154 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
161 NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject
,
164 PIO_STACK_LOCATION IoStack
;
165 PFILE_OBJECT FileObject
;
166 NTSTATUS Status
= STATUS_SUCCESS
;
167 PNPFS_DEVICE_EXTENSION DeviceExt
;
171 PLIST_ENTRY current_entry
;
173 PIO_PIPE_CREATE_BUFFER Buffer
;
175 DPRINT1("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
177 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
178 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
179 FileObject
= IoStack
->FileObject
;
180 DPRINT("FileObject %p\n", FileObject
);
181 DPRINT("Pipe name %wZ\n", &FileObject
->FileName
);
183 Buffer
= (PIO_PIPE_CREATE_BUFFER
)Irp
->Tail
.Overlay
.AuxiliaryBuffer
;
185 Pipe
= ExAllocatePool(NonPagedPool
, sizeof(NPFS_PIPE
));
188 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
189 Irp
->IoStatus
.Information
= 0;
191 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
193 return(STATUS_NO_MEMORY
);
196 Fcb
= ExAllocatePool(NonPagedPool
, sizeof(NPFS_FCB
));
201 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
202 Irp
->IoStatus
.Information
= 0;
204 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
206 return(STATUS_NO_MEMORY
);
209 if (RtlCreateUnicodeString(&Pipe
->PipeName
, FileObject
->FileName
.Buffer
) == 0)
214 Irp
->IoStatus
.Status
= STATUS_NO_MEMORY
;
215 Irp
->IoStatus
.Information
= 0;
217 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
219 return(STATUS_NO_MEMORY
);
222 Pipe
->ReferenceCount
= 0;
223 InitializeListHead(&Pipe
->FcbListHead
);
224 KeInitializeSpinLock(&Pipe
->FcbListLock
);
226 Pipe
->MaxInstances
= Buffer
->MaxInstances
;
227 Pipe
->TimeOut
= Buffer
->TimeOut
;
229 KeLockMutex(&DeviceExt
->PipeListLock
);
230 current_entry
= DeviceExt
->PipeListHead
.Flink
;
231 while (current_entry
!= &DeviceExt
->PipeListHead
)
233 current
= CONTAINING_RECORD(current_entry
,
237 if (RtlCompareUnicodeString(&Pipe
->PipeName
, ¤t
->PipeName
, TRUE
) == 0)
242 current_entry
= current_entry
->Flink
;
245 if (current_entry
!= &DeviceExt
->PipeListHead
)
247 RtlFreeUnicodeString(&Pipe
->PipeName
);
254 InsertTailList(&DeviceExt
->PipeListHead
, &Pipe
->PipeListEntry
);
256 Pipe
->ReferenceCount
++;
258 KeAcquireSpinLock(&Pipe
->FcbListLock
, &oldIrql
);
259 InsertTailList(&Pipe
->FcbListHead
, &Fcb
->FcbListEntry
);
260 KeReleaseSpinLock(&Pipe
->FcbListLock
, oldIrql
);
262 Fcb
->WriteModeMessage
= Buffer
->WriteModeMessage
;
263 Fcb
->ReadModeMessage
= Buffer
->ReadModeMessage
;
264 Fcb
->NonBlocking
= Buffer
->NonBlocking
;
265 Fcb
->InBufferSize
= Buffer
->InBufferSize
;
266 Fcb
->OutBufferSize
= Buffer
->OutBufferSize
;
269 Fcb
->IsServer
= TRUE
;
270 Fcb
->OtherSide
= NULL
;
272 KeInitializeEvent(&Fcb
->ConnectEvent
,
273 SynchronizationEvent
,
276 KeUnlockMutex(&DeviceExt
->PipeListLock
);
278 FileObject
->FsContext
= Fcb
;
280 Irp
->IoStatus
.Status
= Status
;
281 Irp
->IoStatus
.Information
= 0;
283 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
290 NpfsClose(PDEVICE_OBJECT DeviceObject
,
293 PNPFS_DEVICE_EXTENSION DeviceExt
;
294 PIO_STACK_LOCATION IoStack
;
295 PFILE_OBJECT FileObject
;
300 DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject
, Irp
);
302 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
303 DeviceExt
= (PNPFS_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
304 FileObject
= IoStack
->FileObject
;
305 Fcb
= FileObject
->FsContext
;
308 DPRINT("Closing pipe %wZ\n", &Pipe
->PipeName
);
310 KeLockMutex(&DeviceExt
->PipeListLock
);
312 Pipe
->ReferenceCount
--;
314 KeAcquireSpinLock(&Pipe
->FcbListLock
, &oldIrql
);
315 RemoveEntryList(&Fcb
->FcbListEntry
);
316 KeReleaseSpinLock(&Pipe
->FcbListLock
, oldIrql
);
318 FileObject
->FsContext
= NULL
;
320 if (Pipe
->ReferenceCount
== 0)
322 RtlFreeUnicodeString(&Pipe
->PipeName
);
323 RemoveEntryList(&Pipe
->PipeListEntry
);
327 KeUnlockMutex(&DeviceExt
->PipeListLock
);
329 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
330 Irp
->IoStatus
.Information
= 0;
332 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
334 return(STATUS_SUCCESS
);