Minor changes.
[reactos.git] / reactos / lib / kernel32 / file / npipe.c
1 /* $Id: npipe.c,v 1.3 2000/06/03 14:47:32 ea Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/file/npipe.c
6 * PURPOSE: Directory functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
8 * UPDATE HISTORY:
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <windows.h>
15 #include <wchar.h>
16 #include <string.h>
17 #include <ntdll/rtl.h>
18
19 #include <kernel32/kernel32.h>
20 #include <kernel32/error.h>
21
22 /* FUNCTIONS ****************************************************************/
23
24 HANDLE STDCALL CreateNamedPipeA(LPCSTR lpName,
25 DWORD dwOpenMode,
26 DWORD dwPipeMode,
27 DWORD nMaxInstances,
28 DWORD nOutBufferSize,
29 DWORD nInBufferSize,
30 DWORD nDefaultTimeOut,
31 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
32 {
33 HANDLE NamedPipeHandle;
34 UNICODE_STRING NameU;
35 ANSI_STRING NameA;
36
37 RtlInitAnsiString(&NameA, (LPSTR)lpName);
38 RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE);
39
40 NamedPipeHandle = CreateNamedPipeW(NameU.Buffer,
41 dwOpenMode,
42 dwPipeMode,
43 nMaxInstances,
44 nOutBufferSize,
45 nInBufferSize,
46 nDefaultTimeOut,
47 lpSecurityAttributes);
48
49 RtlFreeUnicodeString(&NameU);
50
51 return(NamedPipeHandle);
52 }
53
54 HANDLE STDCALL CreateNamedPipeW(LPCWSTR lpName,
55 DWORD dwOpenMode,
56 DWORD dwPipeMode,
57 DWORD nMaxInstances,
58 DWORD nOutBufferSize,
59 DWORD nInBufferSize,
60 DWORD nDefaultTimeOut,
61 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
62 {
63 UNICODE_STRING NamedPipeName;
64 BOOL Result;
65 NTSTATUS Status;
66 OBJECT_ATTRIBUTES ObjectAttributes;
67 HANDLE PipeHandle;
68 ACCESS_MASK DesiredAccess;
69 ULONG CreateOptions;
70 ULONG CreateDisposition;
71 BOOLEAN WriteModeMessage;
72 BOOLEAN ReadModeMessage;
73 BOOLEAN NonBlocking;
74 IO_STATUS_BLOCK Iosb;
75 ULONG ShareAccess;
76 LARGE_INTEGER DefaultTimeOut;
77
78 Result = RtlDosPathNameToNtPathName_U((LPWSTR)lpName,
79 &NamedPipeName,
80 NULL,
81 NULL);
82
83 if (!Result)
84 {
85 return(INVALID_HANDLE_VALUE);
86 }
87
88 InitializeObjectAttributes(&ObjectAttributes,
89 &NamedPipeName,
90 0,
91 NULL,
92 NULL);
93
94 DesiredAccess = 0;
95
96 ShareAccess = 0;
97
98 CreateDisposition = FILE_OPEN_IF;
99
100 CreateOptions = 0;
101 if (dwOpenMode & FILE_FLAG_WRITE_THROUGH)
102 {
103 CreateOptions = CreateOptions | FILE_FLAG_WRITE_THROUGH;
104 }
105 if (dwOpenMode & FILE_FLAG_OVERLAPPED)
106 {
107 CreateOptions = CreateOptions | FILE_SYNCHRONOUS_IO_ALERT;
108 }
109
110 if (dwPipeMode & PIPE_TYPE_BYTE)
111 {
112 WriteModeMessage = FALSE;
113 }
114 else if (dwPipeMode & PIPE_TYPE_MESSAGE)
115 {
116 WriteModeMessage = TRUE;
117 }
118 else
119 {
120 WriteModeMessage = FALSE;
121 }
122
123 if (dwPipeMode & PIPE_READMODE_BYTE)
124 {
125 ReadModeMessage = FALSE;
126 }
127 else if (dwPipeMode & PIPE_READMODE_MESSAGE)
128 {
129 ReadModeMessage = TRUE;
130 }
131 else
132 {
133 ReadModeMessage = FALSE;
134 }
135
136 if (dwPipeMode & PIPE_WAIT)
137 {
138 NonBlocking = FALSE;
139 }
140 else if (dwPipeMode & PIPE_NOWAIT)
141 {
142 NonBlocking = TRUE;
143 }
144 else
145 {
146 NonBlocking = FALSE;
147 }
148
149 DefaultTimeOut.QuadPart = nDefaultTimeOut * 1000 * 1000;
150
151 Status = NtCreateNamedPipeFile(&PipeHandle,
152 DesiredAccess,
153 &ObjectAttributes,
154 &Iosb,
155 ShareAccess,
156 CreateDisposition,
157 CreateOptions,
158 WriteModeMessage,
159 ReadModeMessage,
160 NonBlocking,
161 nMaxInstances,
162 nInBufferSize,
163 nOutBufferSize,
164 &DefaultTimeOut);
165 if (!NT_SUCCESS(Status))
166 {
167 SetLastErrorByStatus (Status);
168 return(INVALID_HANDLE_VALUE);
169 }
170 return(PipeHandle);
171 }
172
173 BOOL STDCALL WaitNamedPipeA(LPCSTR lpNamedPipeName,
174 DWORD nTimeOut)
175 {
176 BOOL r;
177 UNICODE_STRING NameU;
178 ANSI_STRING NameA;
179
180 RtlInitAnsiString(&NameA, lpNamedPipeName);
181 RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE);
182
183 r = WaitNamedPipeW(NameU.Buffer, nTimeOut);
184
185 RtlFreeUnicodeString(&NameU);
186
187 return(r);
188 }
189
190 BOOL STDCALL WaitNamedPipeW(LPCWSTR lpNamedPipeName,
191 DWORD nTimeOut)
192 {
193 UNICODE_STRING NamedPipeName;
194 BOOL r;
195 NTSTATUS Status;
196 OBJECT_ATTRIBUTES ObjectAttributes;
197 NPFS_WAIT_PIPE WaitPipe;
198 HANDLE FileHandle;
199 IO_STATUS_BLOCK Iosb;
200
201 r = RtlDosPathNameToNtPathName_U(lpNamedPipeName,
202 &NamedPipeName,
203 NULL,
204 NULL);
205
206 if (!r)
207 {
208 return(FALSE);
209 }
210
211 InitializeObjectAttributes(&ObjectAttributes,
212 &NamedPipeName,
213 0,
214 NULL,
215 NULL);
216 Status = NtOpenFile(&FileHandle,
217 FILE_GENERIC_READ,
218 &ObjectAttributes,
219 &Iosb,
220 0,
221 FILE_SYNCHRONOUS_IO_ALERT);
222 if (!NT_SUCCESS(Status))
223 {
224 SetLastErrorByStatus (Status);
225 return(FALSE);
226 }
227
228 WaitPipe.Timeout.QuadPart = nTimeOut * 1000 * 1000;
229
230 Status = NtFsControlFile(FileHandle,
231 NULL,
232 NULL,
233 NULL,
234 &Iosb,
235 FSCTL_WAIT_PIPE,
236 &WaitPipe,
237 sizeof(WaitPipe),
238 NULL,
239 0);
240 if (!NT_SUCCESS(Status))
241 {
242 SetLastErrorByStatus (Status);
243 return(FALSE);
244 }
245
246 NtClose(FileHandle);
247 return(TRUE);
248 }
249
250 BOOL STDCALL ConnectNamedPipe(HANDLE hNamedPipe,
251 LPOVERLAPPED lpOverLapped)
252 {
253 NPFS_LISTEN ListenPipe;
254 IO_STATUS_BLOCK Iosb;
255 HANDLE hEvent;
256 PIO_STATUS_BLOCK IoStatusBlock;
257 NTSTATUS Status;
258
259 if (lpOverLapped != NULL)
260 {
261 lpOverLapped->Internal = STATUS_PENDING;
262 hEvent = lpOverLapped->hEvent;
263 IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
264 }
265 else
266 {
267 IoStatusBlock = &Iosb;
268 hEvent = NULL;
269 }
270
271 Status = NtFsControlFile(hNamedPipe,
272 hEvent,
273 NULL,
274 NULL,
275 IoStatusBlock,
276 FSCTL_LISTEN,
277 &ListenPipe,
278 sizeof(ListenPipe),
279 NULL,
280 0);
281 if (!NT_SUCCESS(Status))
282 {
283 SetLastErrorByStatus (Status);
284 return(FALSE);
285 }
286 return(TRUE);
287 }
288
289 BOOL STDCALL SetNamedPipeHandleState(HANDLE hNamedPipe,
290 LPDWORD lpMode,
291 LPDWORD lpMaxCollectionCount,
292 LPDWORD lpCollectDataTimeout)
293 {
294 NPFS_GET_STATE GetState;
295 NPFS_SET_STATE SetState;
296 IO_STATUS_BLOCK Iosb;
297 NTSTATUS Status;
298
299 Status = NtFsControlFile(hNamedPipe,
300 NULL,
301 NULL,
302 NULL,
303 &Iosb,
304 FSCTL_GET_STATE,
305 NULL,
306 0,
307 &GetState,
308 sizeof(GetState));
309 if (!NT_SUCCESS(Status))
310 {
311 SetLastErrorByStatus (Status);
312 return(FALSE);
313 }
314
315 if (lpMode != NULL)
316 {
317 if ((*lpMode) & PIPE_READMODE_MESSAGE)
318 {
319 SetState.ReadModeMessage = TRUE;
320 }
321 else
322 {
323 SetState.ReadModeMessage = FALSE;
324 }
325 if ((*lpMode) & PIPE_NOWAIT)
326 {
327 SetState.NonBlocking = TRUE;
328 }
329 else
330 {
331 SetState.NonBlocking = FALSE;
332 }
333 SetState.WriteModeMessage = GetState.WriteModeMessage;
334 }
335 else
336 {
337 SetState.ReadModeMessage = GetState.ReadModeMessage;
338 SetState.WriteModeMessage = GetState.WriteModeMessage;
339 SetState.NonBlocking = SetState.NonBlocking;
340 }
341
342 if (lpMaxCollectionCount != NULL)
343 {
344 SetState.InBufferSize = *lpMaxCollectionCount;
345 }
346 else
347 {
348 SetState.InBufferSize = GetState.InBufferSize;
349 }
350
351 SetState.OutBufferSize = GetState.OutBufferSize;
352
353 if (lpCollectDataTimeout != NULL)
354 {
355 SetState.Timeout.QuadPart = (*lpCollectDataTimeout) * 1000 * 1000;
356 }
357 else
358 {
359 SetState.Timeout = GetState.Timeout;
360 }
361
362 Status = NtFsControlFile(hNamedPipe,
363 NULL,
364 NULL,
365 NULL,
366 &Iosb,
367 FSCTL_SET_STATE,
368 &SetState,
369 sizeof(SetState),
370 NULL,
371 0);
372 if (!NT_SUCCESS(Status))
373 {
374 SetLastErrorByStatus (Status);
375 return(FALSE);
376 }
377 return(TRUE);
378 }
379
380 /* EOF */