Fixed some NT compatibility issues in Nt[Query/Set]InformationFile().
[reactos.git] / reactos / drivers / fs / np / create.c
1 /* $Id: create.c,v 1.7 2001/06/12 12:35:04 ekohl Exp $
2 *
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>
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <ddk/ntddk.h>
13
14 #include "npfs.h"
15
16 //#define NDEBUG
17 #include <debug.h>
18
19
20 /* GLOBALS *******************************************************************/
21
22
23 /* FUNCTIONS *****************************************************************/
24
25 NTSTATUS STDCALL
26 NpfsCreate(PDEVICE_OBJECT DeviceObject,
27 PIRP Irp)
28 {
29 PIO_STACK_LOCATION IoStack;
30 PFILE_OBJECT FileObject;
31 NTSTATUS Status;
32 PNPFS_PIPE Pipe;
33 PNPFS_FCB Fcb;
34 PNPFS_FCB ServerFcb;
35 PNPFS_PIPE current;
36 PLIST_ENTRY current_entry;
37 PNPFS_DEVICE_EXTENSION DeviceExt;
38 KIRQL oldIrql;
39
40 DPRINT1("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
41
42 DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
43 IoStack = IoGetCurrentIrpStackLocation(Irp);
44 FileObject = IoStack->FileObject;
45 DPRINT("FileObject %p\n", FileObject);
46
47 Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
48 if (Fcb == NULL)
49 {
50 Irp->IoStatus.Status = STATUS_NO_MEMORY;
51 Irp->IoStatus.Information = 0;
52
53 IoCompleteRequest(Irp, IO_NO_INCREMENT);
54
55 return(STATUS_NO_MEMORY);
56 }
57
58 KeLockMutex(&DeviceExt->PipeListLock);
59 current_entry = DeviceExt->PipeListHead.Flink;
60 while (current_entry != &DeviceExt->PipeListHead)
61 {
62 current = CONTAINING_RECORD(current_entry,
63 NPFS_PIPE,
64 PipeListEntry);
65
66 if (RtlCompareUnicodeString(&Pipe->PipeName,
67 &current->PipeName,
68 TRUE) == 0)
69 {
70 break;
71 }
72
73 current_entry = current_entry->Flink;
74 }
75
76 if (current_entry == &DeviceExt->PipeListHead)
77 {
78 ExFreePool(Fcb);
79 KeUnlockMutex(&DeviceExt->PipeListLock);
80
81 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
82 Irp->IoStatus.Information = 0;
83
84 IoCompleteRequest(Irp, IO_NO_INCREMENT);
85
86 return(STATUS_UNSUCCESSFUL);
87 }
88
89 Pipe = current;
90
91 Fcb->WriteModeMessage = FALSE;
92 Fcb->ReadModeMessage = FALSE;
93 Fcb->NonBlocking = FALSE;
94 Fcb->InBufferSize = PAGESIZE;
95 Fcb->OutBufferSize = PAGESIZE;
96 Fcb->Pipe = Pipe;
97 Fcb->IsServer = FALSE;
98 Fcb->OtherSide = NULL;
99
100 /* search for disconnected server fcb */
101
102 current_entry = Pipe->FcbListHead.Flink;
103 while (current_entry != &Pipe->FcbListHead)
104 {
105 ServerFcb = CONTAINING_RECORD(current_entry,
106 NPFS_FCB,
107 FcbListEntry);
108
109 DPRINT("ServerFcb->IsServer: %x\n", ServerFcb->IsServer);
110 DPRINT("ServerFcb->OtherSide: %p\n", ServerFcb->OtherSide);
111 if ((ServerFcb->IsServer == TRUE) && (ServerFcb->OtherSide == NULL))
112 {
113 DPRINT("Server found! Fcb %p\n", ServerFcb);
114 break;
115 }
116
117 current_entry = current_entry->Flink;
118 }
119
120 if (current_entry == &Pipe->FcbListHead)
121 {
122 DPRINT("No server fcb found!\n");
123
124 ExFreePool(Fcb);
125 KeUnlockMutex(&DeviceExt->PipeListLock);
126
127 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
128 Irp->IoStatus.Information = 0;
129
130 IoCompleteRequest(Irp, IO_NO_INCREMENT);
131
132 return(STATUS_UNSUCCESSFUL);
133 }
134
135 KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql);
136 InsertTailList(&Pipe->FcbListHead, &Fcb->FcbListEntry);
137 KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql);
138
139 Pipe->ReferenceCount++;
140
141
142 Fcb->OtherSide = ServerFcb;
143 ServerFcb->OtherSide = Fcb;
144
145 KeSetEvent(&ServerFcb->ConnectEvent, 0, FALSE);
146
147 KeUnlockMutex(&DeviceExt->PipeListLock);
148
149 FileObject->FsContext = Fcb;
150
151 Irp->IoStatus.Status = Status;
152 Irp->IoStatus.Information = 0;
153
154 IoCompleteRequest(Irp, IO_NO_INCREMENT);
155
156 return(Status);
157 }
158
159
160 NTSTATUS STDCALL
161 NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
162 PIRP Irp)
163 {
164 PIO_STACK_LOCATION IoStack;
165 PFILE_OBJECT FileObject;
166 NTSTATUS Status = STATUS_SUCCESS;
167 PNPFS_DEVICE_EXTENSION DeviceExt;
168 PNPFS_PIPE Pipe;
169 PNPFS_FCB Fcb;
170 KIRQL oldIrql;
171 PLIST_ENTRY current_entry;
172 PNPFS_PIPE current;
173 PIO_PIPE_CREATE_BUFFER Buffer;
174
175 DPRINT1("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
176
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);
182
183 Buffer = (PIO_PIPE_CREATE_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
184
185 Pipe = ExAllocatePool(NonPagedPool, sizeof(NPFS_PIPE));
186 if (Pipe == NULL)
187 {
188 Irp->IoStatus.Status = STATUS_NO_MEMORY;
189 Irp->IoStatus.Information = 0;
190
191 IoCompleteRequest(Irp, IO_NO_INCREMENT);
192
193 return(STATUS_NO_MEMORY);
194 }
195
196 Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
197 if (Fcb == NULL)
198 {
199 ExFreePool(Pipe);
200
201 Irp->IoStatus.Status = STATUS_NO_MEMORY;
202 Irp->IoStatus.Information = 0;
203
204 IoCompleteRequest(Irp, IO_NO_INCREMENT);
205
206 return(STATUS_NO_MEMORY);
207 }
208
209 if (RtlCreateUnicodeString(&Pipe->PipeName, FileObject->FileName.Buffer) == 0)
210 {
211 ExFreePool(Pipe);
212 ExFreePool(Fcb);
213
214 Irp->IoStatus.Status = STATUS_NO_MEMORY;
215 Irp->IoStatus.Information = 0;
216
217 IoCompleteRequest(Irp, IO_NO_INCREMENT);
218
219 return(STATUS_NO_MEMORY);
220 }
221
222 Pipe->ReferenceCount = 0;
223 InitializeListHead(&Pipe->FcbListHead);
224 KeInitializeSpinLock(&Pipe->FcbListLock);
225
226 Pipe->MaxInstances = Buffer->MaxInstances;
227 Pipe->TimeOut = Buffer->TimeOut;
228
229 KeLockMutex(&DeviceExt->PipeListLock);
230 current_entry = DeviceExt->PipeListHead.Flink;
231 while (current_entry != &DeviceExt->PipeListHead)
232 {
233 current = CONTAINING_RECORD(current_entry,
234 NPFS_PIPE,
235 PipeListEntry);
236
237 if (RtlCompareUnicodeString(&Pipe->PipeName, &current->PipeName, TRUE) == 0)
238 {
239 break;
240 }
241
242 current_entry = current_entry->Flink;
243 }
244
245 if (current_entry != &DeviceExt->PipeListHead)
246 {
247 RtlFreeUnicodeString(&Pipe->PipeName);
248 ExFreePool(Pipe);
249
250 Pipe = current;
251 }
252 else
253 {
254 InsertTailList(&DeviceExt->PipeListHead, &Pipe->PipeListEntry);
255 }
256 Pipe->ReferenceCount++;
257
258 KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql);
259 InsertTailList(&Pipe->FcbListHead, &Fcb->FcbListEntry);
260 KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql);
261
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;
267
268 Fcb->Pipe = Pipe;
269 Fcb->IsServer = TRUE;
270 Fcb->OtherSide = NULL;
271
272 KeInitializeEvent(&Fcb->ConnectEvent,
273 SynchronizationEvent,
274 FALSE);
275
276 KeUnlockMutex(&DeviceExt->PipeListLock);
277
278 FileObject->FsContext = Fcb;
279
280 Irp->IoStatus.Status = Status;
281 Irp->IoStatus.Information = 0;
282
283 IoCompleteRequest(Irp, IO_NO_INCREMENT);
284
285 return(Status);
286 }
287
288
289 NTSTATUS STDCALL
290 NpfsClose(PDEVICE_OBJECT DeviceObject,
291 PIRP Irp)
292 {
293 PNPFS_DEVICE_EXTENSION DeviceExt;
294 PIO_STACK_LOCATION IoStack;
295 PFILE_OBJECT FileObject;
296 PNPFS_FCB Fcb;
297 PNPFS_PIPE Pipe;
298 KIRQL oldIrql;
299
300 DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
301
302 IoStack = IoGetCurrentIrpStackLocation(Irp);
303 DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
304 FileObject = IoStack->FileObject;
305 Fcb = FileObject->FsContext;
306 Pipe = Fcb->Pipe;
307
308 DPRINT("Closing pipe %wZ\n", &Pipe->PipeName);
309
310 KeLockMutex(&DeviceExt->PipeListLock);
311
312 Pipe->ReferenceCount--;
313
314 KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql);
315 RemoveEntryList(&Fcb->FcbListEntry);
316 KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql);
317 ExFreePool(Fcb);
318 FileObject->FsContext = NULL;
319
320 if (Pipe->ReferenceCount == 0)
321 {
322 RtlFreeUnicodeString(&Pipe->PipeName);
323 RemoveEntryList(&Pipe->PipeListEntry);
324 ExFreePool(Pipe);
325 }
326
327 KeUnlockMutex(&DeviceExt->PipeListLock);
328
329 Irp->IoStatus.Status = STATUS_SUCCESS;
330 Irp->IoStatus.Information = 0;
331
332 IoCompleteRequest(Irp, IO_NO_INCREMENT);
333
334 return(STATUS_SUCCESS);
335 }
336
337 /* EOF */