02b09fd9a45a08d2e7cc703269f62723e4051ffe
[reactos.git] / reactos / drivers / fs / np / fsctrl.c
1 /* $Id: fsctrl.c,v 1.5 2001/07/29 16:40:20 ekohl Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/fs/np/fsctrl.c
6 * PURPOSE: Named pipe filesystem
7 * PROGRAMMER: David Welch <welch@cwcom.net>
8 * Eric Kohl <ekohl@rz-online.de>
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include "npfs.h"
15
16 //#define NDEBUG
17 #include <debug.h>
18
19
20 /* FUNCTIONS *****************************************************************/
21
22 static NTSTATUS
23 NpfsConnectPipe(PNPFS_FCB Fcb)
24 {
25 PNPFS_PIPE Pipe;
26 PLIST_ENTRY current_entry;
27 PNPFS_FCB ClientFcb;
28 NTSTATUS Status;
29
30 DPRINT("NpfsConnectPipe()\n");
31
32 if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
33 return STATUS_PIPE_CONNECTED;
34
35 if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
36 return STATUS_PIPE_CLOSING;
37
38 /*
39 * Acceptable states are: FILE_PIPE_DISCONNECTED_STATE and
40 * FILE_PIPE_LISTENING_STATE
41 */
42
43 DPRINT("Waiting for connection...\n");
44
45 Pipe = Fcb->Pipe;
46
47 Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
48
49 /* search for a listening client fcb */
50
51 current_entry = Pipe->ClientFcbListHead.Flink;
52 while (current_entry != &Pipe->ClientFcbListHead)
53 {
54 ClientFcb = CONTAINING_RECORD(current_entry,
55 NPFS_FCB,
56 FcbListEntry);
57
58 if (ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE)
59 {
60 break;
61 }
62
63 current_entry = current_entry->Flink;
64 }
65
66 if (current_entry != &Pipe->ClientFcbListHead)
67 {
68 /* found a listening client fcb */
69 DPRINT("Listening client fcb found -- connecting\n");
70
71 /* connect client and server fcb's */
72 Fcb->OtherSide = ClientFcb;
73 ClientFcb->OtherSide = Fcb;
74
75 /* set connected state */
76 Fcb->PipeState = FILE_PIPE_CONNECTED_STATE;
77 ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
78
79 /* FIXME: create and initialize data queues */
80
81 /* signal client's connect event */
82 KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
83
84 }
85 else
86 {
87 /* no listening client fcb found */
88 DPRINT("No listening client fcb found -- waiting for client\n");
89 Status = KeWaitForSingleObject(&Fcb->ConnectEvent,
90 UserRequest,
91 KernelMode,
92 FALSE,
93 NULL);
94
95 DPRINT("Finished waiting! Status: %x\n", Status);
96 }
97
98
99 DPRINT("Client Fcb: %p\n", Fcb->OtherSide);
100
101 return STATUS_PIPE_CONNECTED;
102 }
103
104
105 static NTSTATUS
106 NpfsDisconnectPipe(PNPFS_FCB Fcb)
107 {
108 PNPFS_FCB ServerFcb;
109
110 DPRINT("NpfsDisconnectPipe()\n");
111
112 if (Fcb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
113 return(STATUS_SUCCESS);
114
115 if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
116 {
117 Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
118 Fcb->OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
119
120 /* FIXME: remove data queue(s) */
121
122 Fcb->OtherSide->OtherSide = NULL;
123 Fcb->OtherSide = NULL;
124
125 DPRINT("Pipe disconnected\n");
126 return(STATUS_SUCCESS);
127 }
128
129 if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
130 {
131 Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
132
133 /* FIXME: remove data queue(s) */
134
135 DPRINT("Pipe disconnected\n");
136 return(STATUS_SUCCESS);
137 }
138
139 return(STATUS_UNSUCCESSFUL);
140 }
141
142
143 static NTSTATUS
144 NpfsWaitPipe(PNPFS_FCB Fcb)
145 {
146 DPRINT("NpfsWaitPipe\n");
147 return STATUS_NOT_IMPLEMENTED;
148 }
149
150
151 NTSTATUS STDCALL
152 NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
153 PIRP Irp)
154 {
155 PIO_STACK_LOCATION IoStack;
156 PFILE_OBJECT FileObject;
157 NTSTATUS Status;
158 PNPFS_DEVICE_EXTENSION DeviceExt;
159 PNPFS_PIPE Pipe;
160 PNPFS_FCB Fcb;
161
162 DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
163
164 DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
165 IoStack = IoGetCurrentIrpStackLocation(Irp);
166 DPRINT("IoStack: %p\n", IoStack);
167 FileObject = IoStack->FileObject;
168 DPRINT("FileObject: %p\n", FileObject);
169 Fcb = FileObject->FsContext;
170 DPRINT("Fcb: %p\n", Fcb);
171 Pipe = Fcb->Pipe;
172 DPRINT("Pipe: %p\n", Pipe);
173 DPRINT("PipeName: %wZ\n", &Pipe->PipeName);
174
175 switch (IoStack->Parameters.FileSystemControl.IoControlCode)
176 {
177 case FSCTL_PIPE_LISTEN:
178 DPRINT("Connecting pipe %wZ\n", &Pipe->PipeName);
179 Status = NpfsConnectPipe(Fcb);
180 break;
181
182 case FSCTL_PIPE_DISCONNECT:
183 DPRINT("Disconnecting pipe %wZ\n", &Pipe->PipeName);
184 Status = NpfsDisconnectPipe(Fcb);
185 break;
186
187 case FSCTL_PIPE_WAIT:
188 DPRINT("Waiting for pipe %wZ\n", &Pipe->PipeName);
189 Status = NpfsWaitPipe(Fcb);
190 break;
191
192 default:
193 DPRINT("IoControlCode: %x\n", IoStack->Parameters.FileSystemControl.IoControlCode)
194 Status = STATUS_UNSUCCESSFUL;
195 }
196
197 Irp->IoStatus.Status = Status;
198 Irp->IoStatus.Information = 0;
199
200 IoCompleteRequest(Irp, IO_NO_INCREMENT);
201
202 return(Status);
203 }
204
205 /* EOF */