Reverted latest changes.
[reactos.git] / reactos / lib / kernel32 / file / npipe.c
1 /* $Id: npipe.c,v 1.13 2002/09/08 10:22:42 chorns 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 <ntdll/rtl.h>
15 #include <windows.h>
16 #include <kernel32/error.h>
17 //#include <wchar.h>
18 //#include <string.h>
19 #include <limits.h>
20 #include <napi/npipe.h>
21
22 //#define NDEBUG
23 #include <kernel32/kernel32.h>
24
25 /* FUNCTIONS ****************************************************************/
26
27 HANDLE STDCALL
28 CreateNamedPipeA(LPCSTR lpName,
29 DWORD dwOpenMode,
30 DWORD dwPipeMode,
31 DWORD nMaxInstances,
32 DWORD nOutBufferSize,
33 DWORD nInBufferSize,
34 DWORD nDefaultTimeOut,
35 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
36 {
37 HANDLE NamedPipeHandle;
38 UNICODE_STRING NameU;
39 ANSI_STRING NameA;
40
41 RtlInitAnsiString(&NameA, (LPSTR)lpName);
42 RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE);
43
44 NamedPipeHandle = CreateNamedPipeW(NameU.Buffer,
45 dwOpenMode,
46 dwPipeMode,
47 nMaxInstances,
48 nOutBufferSize,
49 nInBufferSize,
50 nDefaultTimeOut,
51 lpSecurityAttributes);
52
53 RtlFreeUnicodeString(&NameU);
54
55 return(NamedPipeHandle);
56 }
57
58
59 HANDLE STDCALL
60 CreateNamedPipeW(LPCWSTR lpName,
61 DWORD dwOpenMode,
62 DWORD dwPipeMode,
63 DWORD nMaxInstances,
64 DWORD nOutBufferSize,
65 DWORD nInBufferSize,
66 DWORD nDefaultTimeOut,
67 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
68 {
69 UNICODE_STRING NamedPipeName;
70 BOOL Result;
71 NTSTATUS Status;
72 OBJECT_ATTRIBUTES ObjectAttributes;
73 HANDLE PipeHandle;
74 ACCESS_MASK DesiredAccess;
75 ULONG CreateOptions;
76 ULONG CreateDisposition;
77 BOOLEAN WriteModeMessage;
78 BOOLEAN ReadModeMessage;
79 BOOLEAN NonBlocking;
80 IO_STATUS_BLOCK Iosb;
81 ULONG ShareAccess;
82 LARGE_INTEGER DefaultTimeOut;
83
84 Result = RtlDosPathNameToNtPathName_U((LPWSTR)lpName,
85 &NamedPipeName,
86 NULL,
87 NULL);
88 if (!Result)
89 {
90 SetLastError(ERROR_PATH_NOT_FOUND);
91 return(INVALID_HANDLE_VALUE);
92 }
93
94 DPRINT("Pipe name: %wZ\n", &NamedPipeName);
95 DPRINT("Pipe name: %S\n", NamedPipeName.Buffer);
96
97 InitializeObjectAttributes(&ObjectAttributes,
98 &NamedPipeName,
99 OBJ_CASE_INSENSITIVE,
100 NULL,
101 NULL);
102
103 DesiredAccess = 0;
104
105 ShareAccess = 0;
106
107 CreateDisposition = FILE_OPEN_IF;
108
109 CreateOptions = 0;
110 if (dwOpenMode & FILE_FLAG_WRITE_THROUGH)
111 {
112 CreateOptions = CreateOptions | FILE_WRITE_THROUGH;
113 }
114 if (dwOpenMode & FILE_FLAG_OVERLAPPED)
115 {
116 CreateOptions = CreateOptions | FILE_SYNCHRONOUS_IO_ALERT;
117 }
118 if (dwOpenMode & PIPE_ACCESS_DUPLEX)
119 {
120 CreateOptions = CreateOptions | FILE_PIPE_FULL_DUPLEX;
121 }
122 else if (dwOpenMode & PIPE_ACCESS_INBOUND)
123 {
124 CreateOptions = CreateOptions | FILE_PIPE_INBOUND;
125 }
126 else if (dwOpenMode & PIPE_ACCESS_OUTBOUND)
127 {
128 CreateOptions = CreateOptions | FILE_PIPE_OUTBOUND;
129 }
130
131 if (dwPipeMode & PIPE_TYPE_BYTE)
132 {
133 WriteModeMessage = FALSE;
134 }
135 else if (dwPipeMode & PIPE_TYPE_MESSAGE)
136 {
137 WriteModeMessage = TRUE;
138 }
139 else
140 {
141 WriteModeMessage = FALSE;
142 }
143
144 if (dwPipeMode & PIPE_READMODE_BYTE)
145 {
146 ReadModeMessage = FALSE;
147 }
148 else if (dwPipeMode & PIPE_READMODE_MESSAGE)
149 {
150 ReadModeMessage = TRUE;
151 }
152 else
153 {
154 ReadModeMessage = FALSE;
155 }
156
157 if (dwPipeMode & PIPE_WAIT)
158 {
159 NonBlocking = FALSE;
160 }
161 else if (dwPipeMode & PIPE_NOWAIT)
162 {
163 NonBlocking = TRUE;
164 }
165 else
166 {
167 NonBlocking = FALSE;
168 }
169
170 if (nMaxInstances >= PIPE_UNLIMITED_INSTANCES)
171 {
172 nMaxInstances = ULONG_MAX;
173 }
174
175 DefaultTimeOut.QuadPart = nDefaultTimeOut * -10000;
176
177 Status = NtCreateNamedPipeFile(&PipeHandle,
178 DesiredAccess,
179 &ObjectAttributes,
180 &Iosb,
181 ShareAccess,
182 CreateDisposition,
183 CreateOptions,
184 WriteModeMessage,
185 ReadModeMessage,
186 NonBlocking,
187 nMaxInstances,
188 nInBufferSize,
189 nOutBufferSize,
190 &DefaultTimeOut);
191
192 RtlFreeUnicodeString(&NamedPipeName);
193
194 if (!NT_SUCCESS(Status))
195 {
196 DPRINT("NtCreateNamedPipe failed (Status %x)!\n", Status);
197 SetLastErrorByStatus (Status);
198 return(INVALID_HANDLE_VALUE);
199 }
200
201 return(PipeHandle);
202 }
203
204
205 BOOL STDCALL
206 WaitNamedPipeA(LPCSTR lpNamedPipeName,
207 DWORD nTimeOut)
208 {
209 BOOL r;
210 UNICODE_STRING NameU;
211 ANSI_STRING NameA;
212
213 RtlInitAnsiString(&NameA, (LPSTR)lpNamedPipeName);
214 RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE);
215
216 r = WaitNamedPipeW(NameU.Buffer, nTimeOut);
217
218 RtlFreeUnicodeString(&NameU);
219
220 return(r);
221 }
222
223
224 BOOL STDCALL
225 WaitNamedPipeW(LPCWSTR lpNamedPipeName,
226 DWORD nTimeOut)
227 {
228 UNICODE_STRING NamedPipeName;
229 BOOL r;
230 NTSTATUS Status;
231 OBJECT_ATTRIBUTES ObjectAttributes;
232 NPFS_WAIT_PIPE WaitPipe;
233 HANDLE FileHandle;
234 IO_STATUS_BLOCK Iosb;
235
236 r = RtlDosPathNameToNtPathName_U((LPWSTR)lpNamedPipeName,
237 &NamedPipeName,
238 NULL,
239 NULL);
240
241 if (!r)
242 {
243 return(FALSE);
244 }
245
246 InitializeObjectAttributes(&ObjectAttributes,
247 &NamedPipeName,
248 OBJ_CASE_INSENSITIVE,
249 NULL,
250 NULL);
251 Status = NtOpenFile(&FileHandle,
252 FILE_GENERIC_READ,
253 &ObjectAttributes,
254 &Iosb,
255 0,
256 FILE_SYNCHRONOUS_IO_ALERT);
257 if (!NT_SUCCESS(Status))
258 {
259 SetLastErrorByStatus (Status);
260 return(FALSE);
261 }
262
263 WaitPipe.Timeout.QuadPart = nTimeOut * -10000;
264
265 Status = NtFsControlFile(FileHandle,
266 NULL,
267 NULL,
268 NULL,
269 &Iosb,
270 FSCTL_PIPE_WAIT,
271 &WaitPipe,
272 sizeof(WaitPipe),
273 NULL,
274 0);
275 NtClose(FileHandle);
276 if (!NT_SUCCESS(Status))
277 {
278 SetLastErrorByStatus (Status);
279 return(FALSE);
280 }
281
282 return(TRUE);
283 }
284
285
286 BOOL STDCALL
287 ConnectNamedPipe(HANDLE hNamedPipe,
288 LPOVERLAPPED lpOverlapped)
289 {
290 PIO_STATUS_BLOCK IoStatusBlock;
291 IO_STATUS_BLOCK Iosb;
292 HANDLE hEvent;
293 NTSTATUS Status;
294
295 if (lpOverlapped != NULL)
296 {
297 lpOverlapped->Internal = STATUS_PENDING;
298 hEvent = lpOverlapped->hEvent;
299 IoStatusBlock = (PIO_STATUS_BLOCK)lpOverlapped;
300 }
301 else
302 {
303 IoStatusBlock = &Iosb;
304 hEvent = NULL;
305 }
306
307 Status = NtFsControlFile(hNamedPipe,
308 hEvent,
309 NULL,
310 NULL,
311 IoStatusBlock,
312 FSCTL_PIPE_LISTEN,
313 NULL,
314 0,
315 NULL,
316 0);
317 if ((lpOverlapped == NULL) && (Status == STATUS_PENDING))
318 {
319 Status = NtWaitForSingleObject(hNamedPipe,
320 FALSE,
321 NULL);
322 if (!NT_SUCCESS(Status))
323 {
324 SetLastErrorByStatus(Status);
325 return(FALSE);
326 }
327 Status = Iosb.Status;
328 }
329 if ((!NT_SUCCESS(Status) && Status != STATUS_PIPE_CONNECTED) ||
330 (Status == STATUS_PENDING))
331 {
332 SetLastErrorByStatus(Status);
333 return(FALSE);
334 }
335 return(TRUE);
336 }
337
338
339 BOOL STDCALL
340 SetNamedPipeHandleState(HANDLE hNamedPipe,
341 LPDWORD lpMode,
342 LPDWORD lpMaxCollectionCount,
343 LPDWORD lpCollectDataTimeout)
344 {
345 NPFS_GET_STATE GetState;
346 NPFS_SET_STATE SetState;
347 IO_STATUS_BLOCK Iosb;
348 NTSTATUS Status;
349
350 Status = NtFsControlFile(hNamedPipe,
351 NULL,
352 NULL,
353 NULL,
354 &Iosb,
355 FSCTL_PIPE_GET_STATE,
356 NULL,
357 0,
358 &GetState,
359 sizeof(NPFS_GET_STATE));
360 if (Status == STATUS_PENDING)
361 {
362 Status = NtWaitForSingleObject(hNamedPipe,
363 FALSE,
364 NULL);
365 if (!NT_SUCCESS(Status))
366 {
367 SetLastErrorByStatus(Status);
368 return(FALSE);
369 }
370 }
371
372 if (lpMode != NULL)
373 {
374 if ((*lpMode) & PIPE_READMODE_MESSAGE)
375 {
376 SetState.ReadModeMessage = TRUE;
377 }
378 else
379 {
380 SetState.ReadModeMessage = FALSE;
381 }
382 if ((*lpMode) & PIPE_NOWAIT)
383 {
384 SetState.NonBlocking = TRUE;
385 }
386 else
387 {
388 SetState.NonBlocking = FALSE;
389 }
390 SetState.WriteModeMessage = GetState.WriteModeMessage;
391 }
392 else
393 {
394 SetState.ReadModeMessage = GetState.ReadModeMessage;
395 SetState.WriteModeMessage = GetState.WriteModeMessage;
396 SetState.NonBlocking = SetState.NonBlocking;
397 }
398
399 if (lpMaxCollectionCount != NULL)
400 {
401 SetState.InBufferSize = *lpMaxCollectionCount;
402 }
403 else
404 {
405 SetState.InBufferSize = GetState.InBufferSize;
406 }
407
408 SetState.OutBufferSize = GetState.OutBufferSize;
409
410 if (lpCollectDataTimeout != NULL)
411 {
412 SetState.Timeout.QuadPart = (*lpCollectDataTimeout) * -10000;
413 }
414 else
415 {
416 SetState.Timeout = GetState.Timeout;
417 }
418
419 Status = NtFsControlFile(hNamedPipe,
420 NULL,
421 NULL,
422 NULL,
423 &Iosb,
424 FSCTL_PIPE_SET_STATE,
425 &SetState,
426 sizeof(NPFS_SET_STATE),
427 NULL,
428 0);
429 if (Status == STATUS_PENDING)
430 {
431 Status = NtWaitForSingleObject(hNamedPipe,
432 FALSE,
433 NULL);
434 if (!NT_SUCCESS(Status))
435 {
436 SetLastErrorByStatus(Status);
437 return(FALSE);
438 }
439 }
440
441 return(TRUE);
442 }
443
444
445 BOOL STDCALL
446 CallNamedPipeA(LPCSTR lpNamedPipeName,
447 LPVOID lpInBuffer,
448 DWORD nInBufferSize,
449 LPVOID lpOutBuffer,
450 DWORD nOutBufferSize,
451 LPDWORD lpBytesRead,
452 DWORD nTimeOut)
453 {
454 UNICODE_STRING PipeName;
455 BOOL Result;
456
457 RtlCreateUnicodeStringFromAsciiz(&PipeName,
458 (LPSTR)lpNamedPipeName);
459
460 Result = CallNamedPipeW(PipeName.Buffer,
461 lpInBuffer,
462 nInBufferSize,
463 lpOutBuffer,
464 nOutBufferSize,
465 lpBytesRead,
466 nTimeOut);
467
468 RtlFreeUnicodeString(&PipeName);
469
470 return(Result);
471 }
472
473
474 BOOL STDCALL
475 CallNamedPipeW(LPCWSTR lpNamedPipeName,
476 LPVOID lpInBuffer,
477 DWORD nInBufferSize,
478 LPVOID lpOutBuffer,
479 DWORD nOutBufferSize,
480 LPDWORD lpBytesRead,
481 DWORD nTimeOut)
482 {
483 HANDLE hPipe = INVALID_HANDLE_VALUE;
484 BOOL bRetry = TRUE;
485 BOOL bError = FALSE;
486 DWORD dwPipeMode;
487
488 while (TRUE)
489 {
490 hPipe = CreateFileW(lpNamedPipeName,
491 GENERIC_READ | GENERIC_WRITE,
492 FILE_SHARE_READ | FILE_SHARE_WRITE,
493 NULL,
494 OPEN_EXISTING,
495 FILE_ATTRIBUTE_NORMAL,
496 NULL);
497 if (hPipe != INVALID_HANDLE_VALUE)
498 break;
499
500 if (bRetry == FALSE)
501 return(FALSE);
502
503 WaitNamedPipeW(lpNamedPipeName,
504 nTimeOut);
505
506 bRetry = FALSE;
507 }
508
509 dwPipeMode = PIPE_READMODE_MESSAGE;
510 bError = SetNamedPipeHandleState(hPipe,
511 &dwPipeMode,
512 NULL,
513 NULL);
514 if (!bError)
515 {
516 CloseHandle(hPipe);
517 return(FALSE);
518 }
519
520 bError = TransactNamedPipe(hPipe,
521 lpInBuffer,
522 nInBufferSize,
523 lpOutBuffer,
524 nOutBufferSize,
525 lpBytesRead,
526 NULL);
527 CloseHandle(hPipe);
528
529 return(bError);
530 }
531
532
533 BOOL STDCALL
534 DisconnectNamedPipe(HANDLE hNamedPipe)
535 {
536 IO_STATUS_BLOCK Iosb;
537 NTSTATUS Status;
538
539 Status = NtFsControlFile(hNamedPipe,
540 NULL,
541 NULL,
542 NULL,
543 &Iosb,
544 FSCTL_PIPE_DISCONNECT,
545 NULL,
546 0,
547 NULL,
548 0);
549 if (Status == STATUS_PENDING)
550 {
551 Status = NtWaitForSingleObject(hNamedPipe,
552 FALSE,
553 NULL);
554 if (!NT_SUCCESS(Status))
555 {
556 SetLastErrorByStatus(Status);
557 return(FALSE);
558 }
559 }
560
561 if (!NT_SUCCESS(Status))
562 {
563 SetLastErrorByStatus(Status);
564 return(FALSE);
565 }
566 return(TRUE);
567 }
568
569
570 WINBOOL STDCALL
571 GetNamedPipeHandleStateW(HANDLE hNamedPipe,
572 LPDWORD lpState,
573 LPDWORD lpCurInstances,
574 LPDWORD lpMaxCollectionCount,
575 LPDWORD lpCollectDataTimeout,
576 LPWSTR lpUserName,
577 DWORD nMaxUserNameSize)
578 {
579 FILE_PIPE_LOCAL_INFORMATION LocalInfo;
580 FILE_PIPE_INFORMATION PipeInfo;
581 IO_STATUS_BLOCK StatusBlock;
582 NTSTATUS Status;
583
584 if (lpState != NULL)
585 {
586 Status = NtQueryInformationFile(hNamedPipe,
587 &StatusBlock,
588 &PipeInfo,
589 sizeof(FILE_PIPE_INFORMATION),
590 FilePipeInformation);
591 if (!NT_SUCCESS(Status))
592 {
593 SetLastErrorByStatus(Status);
594 return(FALSE);
595 }
596 *lpState = 0; /* FIXME */
597 }
598
599 if (lpCurInstances != NULL)
600 {
601 Status = NtQueryInformationFile(hNamedPipe,
602 &StatusBlock,
603 &LocalInfo,
604 sizeof(FILE_PIPE_LOCAL_INFORMATION),
605 FilePipeLocalInformation);
606 if (!NT_SUCCESS(Status))
607 {
608 SetLastErrorByStatus(Status);
609 return(FALSE);
610 }
611 *lpCurInstances = min(LocalInfo.CurrentInstances, 255);
612 }
613
614
615 /* FIXME: retrieve remaining information */
616
617
618 return(TRUE);
619 }
620
621
622 WINBOOL STDCALL
623 GetNamedPipeHandleStateA(HANDLE hNamedPipe,
624 LPDWORD lpState,
625 LPDWORD lpCurInstances,
626 LPDWORD lpMaxCollectionCount,
627 LPDWORD lpCollectDataTimeout,
628 LPSTR lpUserName,
629 DWORD nMaxUserNameSize)
630 {
631 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
632 return FALSE;
633 }
634
635
636 WINBOOL STDCALL
637 GetNamedPipeInfo(HANDLE hNamedPipe,
638 LPDWORD lpFlags,
639 LPDWORD lpOutBufferSize,
640 LPDWORD lpInBufferSize,
641 LPDWORD lpMaxInstances)
642 {
643 FILE_PIPE_LOCAL_INFORMATION PipeLocalInformation;
644 IO_STATUS_BLOCK StatusBlock;
645 NTSTATUS Status;
646
647 Status = NtQueryInformationFile(hNamedPipe,
648 &StatusBlock,
649 &PipeLocalInformation,
650 sizeof(FILE_PIPE_LOCAL_INFORMATION),
651 FilePipeLocalInformation);
652 if (!NT_SUCCESS(Status))
653 {
654 SetLastErrorByStatus(Status);
655 return(FALSE);
656 }
657
658 if (lpFlags != NULL)
659 {
660 *lpFlags = (PipeLocalInformation.NamedPipeEnd == FILE_PIPE_SERVER_END) ? PIPE_SERVER_END : PIPE_CLIENT_END;
661 *lpFlags |= (PipeLocalInformation.NamedPipeType == 1) ? PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE;
662 }
663
664 if (lpOutBufferSize != NULL)
665 *lpOutBufferSize = PipeLocalInformation.OutboundQuota;
666
667 if (lpInBufferSize != NULL)
668 *lpInBufferSize = PipeLocalInformation.InboundQuota;
669
670 if (lpMaxInstances != NULL)
671 {
672 if (PipeLocalInformation.MaximumInstances >= 255)
673 *lpMaxInstances = PIPE_UNLIMITED_INSTANCES;
674 else
675 *lpMaxInstances = PipeLocalInformation.MaximumInstances;
676 }
677
678 return(TRUE);
679 }
680
681
682 BOOL STDCALL
683 PeekNamedPipe(HANDLE hNamedPipe,
684 LPVOID lpBuffer,
685 DWORD nBufferSize,
686 LPDWORD lpBytesRead,
687 LPDWORD lpTotalBytesAvail,
688 LPDWORD lpBytesLeftThisMessage)
689 {
690 PFILE_PIPE_PEEK_BUFFER Buffer;
691 IO_STATUS_BLOCK Iosb;
692 ULONG BufferSize;
693 NTSTATUS Status;
694
695 BufferSize = nBufferSize + sizeof(FILE_PIPE_PEEK_BUFFER);
696 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
697 0,
698 BufferSize);
699
700 Status = NtFsControlFile(hNamedPipe,
701 NULL,
702 NULL,
703 NULL,
704 &Iosb,
705 FSCTL_PIPE_PEEK,
706 NULL,
707 0,
708 Buffer,
709 BufferSize);
710 if (Status == STATUS_PENDING)
711 {
712 Status = NtWaitForSingleObject(hNamedPipe,
713 FALSE,
714 NULL);
715 if (NT_SUCCESS(Status))
716 Status = Iosb.Status;
717 }
718
719 if (Status == STATUS_BUFFER_OVERFLOW)
720 {
721 Status = STATUS_SUCCESS;
722 }
723
724 if (!NT_SUCCESS(Status))
725 {
726 RtlFreeHeap(RtlGetProcessHeap(),
727 0,
728 Buffer);
729 SetLastErrorByStatus(Status);
730 return(FALSE);
731 }
732
733 if (lpTotalBytesAvail != NULL)
734 {
735 *lpTotalBytesAvail = Buffer->ReadDataAvailable;
736 }
737
738 if (lpBytesRead != NULL)
739 {
740 *lpBytesRead = Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER);
741 }
742
743 if (lpBytesLeftThisMessage != NULL)
744 {
745 *lpBytesLeftThisMessage = Buffer->MessageLength -
746 (Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER));
747 }
748
749 if (lpBuffer != NULL)
750 {
751 memcpy(lpBuffer, Buffer->Data,
752 min(nBufferSize, Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER)));
753 }
754
755 RtlFreeHeap(RtlGetProcessHeap(),
756 0,
757 Buffer);
758
759 return(TRUE);
760 }
761
762
763 BOOL STDCALL
764 TransactNamedPipe(HANDLE hNamedPipe,
765 LPVOID lpInBuffer,
766 DWORD nInBufferSize,
767 LPVOID lpOutBuffer,
768 DWORD nOutBufferSize,
769 LPDWORD lpBytesRead,
770 LPOVERLAPPED lpOverlapped)
771 {
772 IO_STATUS_BLOCK IoStatusBlock;
773 NTSTATUS Status;
774
775 if (lpOverlapped == NULL)
776 {
777 Status = NtFsControlFile(hNamedPipe,
778 NULL,
779 NULL,
780 NULL,
781 &IoStatusBlock,
782 FSCTL_PIPE_TRANSCEIVE,
783 lpInBuffer,
784 nInBufferSize,
785 lpOutBuffer,
786 nOutBufferSize);
787 if (Status == STATUS_PENDING)
788 {
789 NtWaitForSingleObject(hNamedPipe,
790 0,
791 FALSE);
792 Status = IoStatusBlock.Status;
793 }
794 if (NT_SUCCESS(Status))
795 {
796 *lpBytesRead = IoStatusBlock.Information;
797 }
798 }
799 else
800 {
801 lpOverlapped->Internal = STATUS_PENDING;
802
803 Status = NtFsControlFile(hNamedPipe,
804 lpOverlapped->hEvent,
805 NULL,
806 NULL,
807 (PIO_STATUS_BLOCK)lpOverlapped,
808 FSCTL_PIPE_TRANSCEIVE,
809 lpInBuffer,
810 nInBufferSize,
811 lpOutBuffer,
812 nOutBufferSize);
813 }
814
815 if (!NT_SUCCESS(Status))
816 {
817 SetLastErrorByStatus(Status);
818 return(FALSE);
819 }
820
821 return(TRUE);
822 }
823
824 /* EOF */