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)
11 /* INCLUDES *****************************************************************/
16 #include "../include/debug.h"
18 /* FUNCTIONS ****************************************************************/
24 CreateNamedPipeA(LPCSTR lpName
,
30 DWORD nDefaultTimeOut
,
31 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
33 HANDLE NamedPipeHandle
;
37 RtlInitAnsiString(&NameA
, (LPSTR
)lpName
);
38 RtlAnsiStringToUnicodeString(&NameU
, &NameA
, TRUE
);
40 NamedPipeHandle
= CreateNamedPipeW(NameU
.Buffer
,
47 lpSecurityAttributes
);
49 RtlFreeUnicodeString(&NameU
);
51 return(NamedPipeHandle
);
59 CreateNamedPipeW(LPCWSTR lpName
,
65 DWORD nDefaultTimeOut
,
66 LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
68 UNICODE_STRING NamedPipeName
;
71 OBJECT_ATTRIBUTES ObjectAttributes
;
73 ACCESS_MASK DesiredAccess
;
75 ULONG WriteModeMessage
;
76 ULONG ReadModeMessage
;
79 ULONG ShareAccess
, Attributes
;
80 LARGE_INTEGER DefaultTimeOut
;
81 PSECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
83 if (nMaxInstances
== 0 || nMaxInstances
> PIPE_UNLIMITED_INSTANCES
)
85 SetLastError(ERROR_INVALID_PARAMETER
);
86 return INVALID_HANDLE_VALUE
;
89 Result
= RtlDosPathNameToNtPathName_U((LPWSTR
)lpName
,
95 SetLastError(ERROR_PATH_NOT_FOUND
);
96 return(INVALID_HANDLE_VALUE
);
99 DPRINT("Pipe name: %wZ\n", &NamedPipeName
);
100 DPRINT("Pipe name: %S\n", NamedPipeName
.Buffer
);
102 Attributes
= OBJ_CASE_INSENSITIVE
;
103 if(lpSecurityAttributes
)
105 SecurityDescriptor
= lpSecurityAttributes
->lpSecurityDescriptor
;
106 if(lpSecurityAttributes
->bInheritHandle
)
107 Attributes
|= OBJ_INHERIT
;
110 InitializeObjectAttributes(&ObjectAttributes
,
116 DesiredAccess
= SYNCHRONIZE
| (dwOpenMode
& (WRITE_DAC
| WRITE_OWNER
| ACCESS_SYSTEM_SECURITY
));
120 if (dwOpenMode
& FILE_FLAG_WRITE_THROUGH
)
121 CreateOptions
= CreateOptions
| FILE_WRITE_THROUGH
;
123 if (!(dwOpenMode
& FILE_FLAG_OVERLAPPED
))
124 CreateOptions
= CreateOptions
| FILE_SYNCHRONOUS_IO_NONALERT
;
126 if (dwOpenMode
& PIPE_ACCESS_OUTBOUND
)
128 ShareAccess
|= FILE_SHARE_READ
;
129 DesiredAccess
|= GENERIC_WRITE
;
131 if (dwOpenMode
& PIPE_ACCESS_INBOUND
)
133 ShareAccess
|= FILE_SHARE_WRITE
;
134 DesiredAccess
|= GENERIC_READ
;
136 if (dwPipeMode
& PIPE_TYPE_MESSAGE
)
137 WriteModeMessage
= FILE_PIPE_MESSAGE_MODE
;
139 WriteModeMessage
= FILE_PIPE_BYTE_STREAM_MODE
;
141 if (dwPipeMode
& PIPE_READMODE_MESSAGE
)
142 ReadModeMessage
= FILE_PIPE_MESSAGE_MODE
;
144 ReadModeMessage
= FILE_PIPE_BYTE_STREAM_MODE
;
146 if (dwPipeMode
& PIPE_NOWAIT
)
147 NonBlocking
= FILE_PIPE_COMPLETE_OPERATION
;
149 NonBlocking
= FILE_PIPE_QUEUE_OPERATION
;
151 DefaultTimeOut
.QuadPart
= nDefaultTimeOut
* -10000LL;
153 Status
= NtCreateNamedPipeFile(&PipeHandle
,
168 RtlFreeUnicodeString(&NamedPipeName
);
170 if (!NT_SUCCESS(Status
))
172 DPRINT("NtCreateNamedPipe failed (Status %x)!\n", Status
);
173 SetLastErrorByStatus (Status
);
174 return INVALID_HANDLE_VALUE
;
185 WaitNamedPipeA(LPCSTR lpNamedPipeName
,
189 UNICODE_STRING NameU
;
192 RtlInitAnsiString(&NameA
, (LPSTR
)lpNamedPipeName
);
193 RtlAnsiStringToUnicodeString(&NameU
, &NameA
, TRUE
);
195 r
= WaitNamedPipeW(NameU
.Buffer
, nTimeOut
);
197 RtlFreeUnicodeString(&NameU
);
203 * When NPFS will work properly, use this code instead. It is compatible with
204 * Microsoft's NPFS.SYS. The main difference is that:
205 * - This code actually respects the timeout instead of ignoring it!
206 * - This code validates and creates the proper names for both UNC and local pipes
207 * - On NT, you open the *root* pipe directory (either \DosDevices\Pipe or
208 * \DosDevices\Unc\Server\Pipe) and then send the pipe to wait on in the
209 * FILE_PIPE_WAIT_FOR_BUFFER structure.
211 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
217 WaitNamedPipeW(LPCWSTR lpNamedPipeName
,
220 UNICODE_STRING NamedPipeName
, NewName
, DevicePath
, PipePrefix
;
225 OBJECT_ATTRIBUTES ObjectAttributes
;
228 IO_STATUS_BLOCK IoStatusBlock
;
229 ULONG WaitPipeInfoSize
;
230 PFILE_PIPE_WAIT_FOR_BUFFER WaitPipeInfo
;
232 /* Start by making a unicode string of the name */
233 DPRINT("Sent path: %S\n", lpNamedPipeName
);
234 RtlCreateUnicodeString(&NamedPipeName
, lpNamedPipeName
);
235 NameLength
= NamedPipeName
.Length
/ sizeof(WCHAR
);
237 /* All slashes must become backslashes */
238 for (i
= 0; i
< NameLength
; i
++)
240 /* Check and convert */
241 if (NamedPipeName
.Buffer
[i
] == L
'/') NamedPipeName
.Buffer
[i
] = L
'\\';
244 /* Find the path type of the name we were given */
245 NewName
= NamedPipeName
;
246 Type
= RtlDetermineDosPathNameType_U(lpNamedPipeName
);
248 /* Check if this was a device path, ie : "\\.\pipe\name" */
249 if (Type
== DEVICE_PATH
)
251 /* Make sure it's a valid prefix */
252 RtlInitUnicodeString(&PipePrefix
, L
"\\\\.\\pipe\\");
253 RtlPrefixString((PANSI_STRING
)&PipePrefix
, (PANSI_STRING
)&NewName
, TRUE
);
257 NewName
.Length
-= 9 * sizeof(WCHAR
);
259 /* Initialize the Dos Devices name */
260 DPRINT("NewName: %wZ\n", &NewName
);
261 RtlInitUnicodeString(&DevicePath
, L
"\\DosDevices\\pipe\\");
263 else if (Type
== UNC_PATH
)
265 /* The path is \\server\\pipe\name; find the pipename itself */
266 p
= &NewName
.Buffer
[2];
268 /* First loop to get past the server name */
271 /* Check if this is a backslash */
272 if (*p
== L
'\\') break;
278 /* Now make sure the full name contains "pipe\" */
279 if ((*p
) && !(_wcsnicmp(p
+ 1, L
"pipe\\", sizeof("pipe\\"))))
281 /* Get to the pipe name itself now */
282 p
+= sizeof("pipe\\") - 1;
286 /* The name is invalid */
287 DPRINT1("Invalid name!\n");
288 SetLastErrorByStatus(STATUS_OBJECT_PATH_SYNTAX_BAD
);
292 /* FIXME: Open \DosDevices\Unc\Server\Pipe\Name */
296 DPRINT1("Invalid path type\n");
297 SetLastErrorByStatus(STATUS_OBJECT_PATH_SYNTAX_BAD
);
301 /* Initialize the object attributes */
302 DPRINT("Opening: %wZ\n", &DevicePath
);
303 InitializeObjectAttributes(&ObjectAttributes
,
305 OBJ_CASE_INSENSITIVE
,
310 Status
= NtOpenFile(&FileHandle
,
311 FILE_READ_ATTRIBUTES
| SYNCHRONIZE
,
314 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
315 FILE_SYNCHRONOUS_IO_NONALERT
);
316 if (!NT_SUCCESS(Status
))
318 /* Fail; couldn't open */
319 DPRINT1("Status: %lx\n", Status
);
320 SetLastErrorByStatus(Status
);
321 RtlFreeUnicodeString(&NamedPipeName
);
325 /* Now calculate the total length of the structure and allocate it */
326 WaitPipeInfoSize
= FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER
, Name
[0]) +
328 WaitPipeInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, WaitPipeInfoSize
);
330 /* Check what timeout we got */
331 if (nTimeOut
== NMPWAIT_USE_DEFAULT_WAIT
)
333 /* Don't use a timeout */
334 WaitPipeInfo
->TimeoutSpecified
= FALSE
;
338 /* Check if we should wait forever */
339 if (nTimeOut
== NMPWAIT_WAIT_FOREVER
)
342 WaitPipeInfo
->Timeout
.LowPart
= 0;
343 WaitPipeInfo
->Timeout
.HighPart
= 0x80000000;
347 /* Convert to NT format */
348 WaitPipeInfo
->Timeout
.QuadPart
= UInt32x32To64(-10000, nTimeOut
);
351 /* In both cases, we do have a timeout */
352 WaitPipeInfo
->TimeoutSpecified
= FALSE
;
355 /* Set the length and copy the name */
356 WaitPipeInfo
->NameLength
= NewName
.Length
;
357 RtlCopyMemory(WaitPipeInfo
->Name
, NewName
.Buffer
, NewName
.Length
);
359 /* Get rid of the full name */
360 RtlFreeUnicodeString(&NamedPipeName
);
362 /* Let NPFS know of our request */
363 Status
= NtFsControlFile(FileHandle
,
374 /* Free our pipe info data and close the handle */
375 RtlFreeHeap(RtlGetProcessHeap(), 0, WaitPipeInfo
);
378 /* Check the status */
379 if (!NT_SUCCESS(Status
))
381 /* Failure to wait on the pipe */
382 DPRINT1("Status: %lx\n", Status
);
383 SetLastErrorByStatus (Status
);
395 WaitNamedPipeW(LPCWSTR lpNamedPipeName
,
398 UNICODE_STRING NamedPipeName
;
401 OBJECT_ATTRIBUTES ObjectAttributes
;
402 FILE_PIPE_WAIT_FOR_BUFFER WaitPipe
;
404 IO_STATUS_BLOCK Iosb
;
406 r
= RtlDosPathNameToNtPathName_U((LPWSTR
)lpNamedPipeName
,
415 InitializeObjectAttributes(&ObjectAttributes
,
417 OBJ_CASE_INSENSITIVE
,
420 Status
= NtOpenFile(&FileHandle
,
421 FILE_READ_ATTRIBUTES
| SYNCHRONIZE
,
424 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
425 FILE_SYNCHRONOUS_IO_NONALERT
);
426 if (!NT_SUCCESS(Status
))
428 SetLastErrorByStatus (Status
);
432 WaitPipe
.Timeout
.QuadPart
= nTimeOut
* -10000LL;
434 Status
= NtFsControlFile(FileHandle
,
445 if (!NT_SUCCESS(Status
))
447 SetLastErrorByStatus (Status
);
459 ConnectNamedPipe(IN HANDLE hNamedPipe
,
460 IN LPOVERLAPPED lpOverlapped
)
464 if (lpOverlapped
!= NULL
)
468 lpOverlapped
->Internal
= STATUS_PENDING
;
469 ApcContext
= (((ULONG_PTR
)lpOverlapped
->hEvent
& 0x1) ? NULL
: lpOverlapped
);
471 Status
= NtFsControlFile(hNamedPipe
,
472 lpOverlapped
->hEvent
,
475 (PIO_STATUS_BLOCK
)lpOverlapped
,
482 /* return FALSE in case of failure and pending operations! */
483 if (!NT_SUCCESS(Status
) || Status
== STATUS_PENDING
)
485 SetLastErrorByStatus(Status
);
491 IO_STATUS_BLOCK Iosb
;
493 Status
= NtFsControlFile(hNamedPipe
,
504 /* wait in case operation is pending */
505 if (Status
== STATUS_PENDING
)
507 Status
= NtWaitForSingleObject(hNamedPipe
,
510 if (NT_SUCCESS(Status
))
512 Status
= Iosb
.Status
;
516 if (!NT_SUCCESS(Status
))
518 SetLastErrorByStatus(Status
);
531 SetNamedPipeHandleState(HANDLE hNamedPipe
,
533 LPDWORD lpMaxCollectionCount
,
534 LPDWORD lpCollectDataTimeout
)
536 IO_STATUS_BLOCK Iosb
;
539 /* Check if the Mode is being changed */
542 FILE_PIPE_INFORMATION Settings
;
544 /* Set the Completion Mode */
545 Settings
.CompletionMode
= (*lpMode
& PIPE_NOWAIT
) ?
546 FILE_PIPE_COMPLETE_OPERATION
: FILE_PIPE_QUEUE_OPERATION
;
548 /* Set the Read Mode */
549 Settings
.ReadMode
= (*lpMode
& PIPE_READMODE_MESSAGE
) ?
550 FILE_PIPE_MESSAGE_MODE
: FILE_PIPE_BYTE_STREAM_MODE
;
552 /* Send the changes to the Driver */
553 Status
= NtSetInformationFile(hNamedPipe
,
556 sizeof(FILE_PIPE_INFORMATION
),
557 FilePipeInformation
);
558 if (!NT_SUCCESS(Status
))
560 SetLastErrorByStatus(Status
);
565 /* Check if the Collection count or Timeout are being changed */
566 if (lpMaxCollectionCount
|| lpCollectDataTimeout
)
568 FILE_PIPE_REMOTE_INFORMATION RemoteSettings
;
570 /* Setting one without the other would delete it, so we read old one */
571 if (!lpMaxCollectionCount
|| !lpCollectDataTimeout
)
573 Status
= NtQueryInformationFile(hNamedPipe
,
576 sizeof(FILE_PIPE_REMOTE_INFORMATION
),
577 FilePipeRemoteInformation
);
579 if (!NT_SUCCESS(Status
))
581 SetLastErrorByStatus(Status
);
586 /* Now set the new settings */
587 RemoteSettings
.MaximumCollectionCount
= (lpMaxCollectionCount
) ?
588 *lpMaxCollectionCount
:
589 RemoteSettings
.MaximumCollectionCount
;
590 if (lpCollectDataTimeout
)
592 /* Convert it to Quad */
593 RemoteSettings
.CollectDataTime
.QuadPart
= -(LONGLONG
)
595 *lpCollectDataTimeout
);
598 /* Tell the driver to change them */
599 Status
= NtSetInformationFile(hNamedPipe
,
602 sizeof(FILE_PIPE_REMOTE_INFORMATION
),
603 FilePipeRemoteInformation
);
605 if (!NT_SUCCESS(Status
))
607 SetLastErrorByStatus(Status
);
620 CallNamedPipeA(LPCSTR lpNamedPipeName
,
624 DWORD nOutBufferSize
,
628 UNICODE_STRING PipeName
;
631 RtlCreateUnicodeStringFromAsciiz(&PipeName
,
632 (LPSTR
)lpNamedPipeName
);
634 Result
= CallNamedPipeW(PipeName
.Buffer
,
642 RtlFreeUnicodeString(&PipeName
);
652 CallNamedPipeW(LPCWSTR lpNamedPipeName
,
656 DWORD nOutBufferSize
,
660 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
667 hPipe
= CreateFileW(lpNamedPipeName
,
668 GENERIC_READ
| GENERIC_WRITE
,
669 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
672 FILE_ATTRIBUTE_NORMAL
,
674 if (hPipe
!= INVALID_HANDLE_VALUE
)
680 WaitNamedPipeW(lpNamedPipeName
,
686 dwPipeMode
= PIPE_READMODE_MESSAGE
;
687 bError
= SetNamedPipeHandleState(hPipe
,
697 bError
= TransactNamedPipe(hPipe
,
714 DisconnectNamedPipe(HANDLE hNamedPipe
)
716 IO_STATUS_BLOCK Iosb
;
719 Status
= NtFsControlFile(hNamedPipe
,
724 FSCTL_PIPE_DISCONNECT
,
729 if (Status
== STATUS_PENDING
)
731 Status
= NtWaitForSingleObject(hNamedPipe
,
734 if (!NT_SUCCESS(Status
))
736 SetLastErrorByStatus(Status
);
741 if (!NT_SUCCESS(Status
))
743 SetLastErrorByStatus(Status
);
754 GetNamedPipeHandleStateW(HANDLE hNamedPipe
,
756 LPDWORD lpCurInstances
,
757 LPDWORD lpMaxCollectionCount
,
758 LPDWORD lpCollectDataTimeout
,
760 DWORD nMaxUserNameSize
)
762 IO_STATUS_BLOCK StatusBlock
;
767 FILE_PIPE_INFORMATION PipeInfo
;
769 Status
= NtQueryInformationFile(hNamedPipe
,
772 sizeof(FILE_PIPE_INFORMATION
),
773 FilePipeInformation
);
774 if (!NT_SUCCESS(Status
))
776 SetLastErrorByStatus(Status
);
780 *lpState
= ((PipeInfo
.CompletionMode
!= FILE_PIPE_QUEUE_OPERATION
) ? PIPE_NOWAIT
: PIPE_WAIT
);
781 *lpState
|= ((PipeInfo
.ReadMode
!= FILE_PIPE_BYTE_STREAM_MODE
) ? PIPE_READMODE_MESSAGE
: PIPE_READMODE_BYTE
);
784 if(lpCurInstances
!= NULL
)
786 FILE_PIPE_LOCAL_INFORMATION LocalInfo
;
788 Status
= NtQueryInformationFile(hNamedPipe
,
791 sizeof(FILE_PIPE_LOCAL_INFORMATION
),
792 FilePipeLocalInformation
);
793 if(!NT_SUCCESS(Status
))
795 SetLastErrorByStatus(Status
);
799 *lpCurInstances
= min(LocalInfo
.CurrentInstances
, PIPE_UNLIMITED_INSTANCES
);
802 if(lpMaxCollectionCount
!= NULL
|| lpCollectDataTimeout
!= NULL
)
804 FILE_PIPE_REMOTE_INFORMATION RemoteInfo
;
806 Status
= NtQueryInformationFile(hNamedPipe
,
809 sizeof(FILE_PIPE_REMOTE_INFORMATION
),
810 FilePipeRemoteInformation
);
811 if(!NT_SUCCESS(Status
))
813 SetLastErrorByStatus(Status
);
817 if(lpMaxCollectionCount
!= NULL
)
819 *lpMaxCollectionCount
= RemoteInfo
.MaximumCollectionCount
;
822 if(lpCollectDataTimeout
!= NULL
)
825 *lpCollectDataTimeout
= 0;
829 if(lpUserName
!= NULL
)
831 /* FIXME - open the thread token, call ImpersonateNamedPipeClient() and
832 retreive the user name with GetUserName(), revert the impersonation
833 and finally restore the thread token */
844 GetNamedPipeHandleStateA(HANDLE hNamedPipe
,
846 LPDWORD lpCurInstances
,
847 LPDWORD lpMaxCollectionCount
,
848 LPDWORD lpCollectDataTimeout
,
850 DWORD nMaxUserNameSize
)
852 UNICODE_STRING UserNameW
;
853 ANSI_STRING UserNameA
;
856 if(lpUserName
!= NULL
)
858 UserNameW
.Length
= 0;
859 UserNameW
.MaximumLength
= nMaxUserNameSize
* sizeof(WCHAR
);
860 UserNameW
.Buffer
= HeapAlloc(GetCurrentProcess(), 0, UserNameW
.MaximumLength
);
862 UserNameA
.Buffer
= lpUserName
;
863 UserNameA
.Length
= 0;
864 UserNameA
.MaximumLength
= nMaxUserNameSize
;
867 Ret
= GetNamedPipeHandleStateW(hNamedPipe
,
870 lpMaxCollectionCount
,
871 lpCollectDataTimeout
,
875 if(Ret
&& lpUserName
!= NULL
)
877 NTSTATUS Status
= RtlUnicodeStringToAnsiString(&UserNameA
, &UserNameW
, FALSE
);
878 if(!NT_SUCCESS(Status
))
880 SetLastErrorByStatus(Status
);
885 if(UserNameW
.Buffer
!= NULL
)
887 HeapFree(GetCurrentProcess(), 0, UserNameW
.Buffer
);
898 GetNamedPipeInfo(HANDLE hNamedPipe
,
900 LPDWORD lpOutBufferSize
,
901 LPDWORD lpInBufferSize
,
902 LPDWORD lpMaxInstances
)
904 FILE_PIPE_LOCAL_INFORMATION PipeLocalInformation
;
905 IO_STATUS_BLOCK StatusBlock
;
908 Status
= NtQueryInformationFile(hNamedPipe
,
910 &PipeLocalInformation
,
911 sizeof(FILE_PIPE_LOCAL_INFORMATION
),
912 FilePipeLocalInformation
);
913 if (!NT_SUCCESS(Status
))
915 SetLastErrorByStatus(Status
);
921 *lpFlags
= (PipeLocalInformation
.NamedPipeEnd
== FILE_PIPE_SERVER_END
) ? PIPE_SERVER_END
: PIPE_CLIENT_END
;
922 *lpFlags
|= (PipeLocalInformation
.NamedPipeType
== 1) ? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
;
925 if (lpOutBufferSize
!= NULL
)
926 *lpOutBufferSize
= PipeLocalInformation
.OutboundQuota
;
928 if (lpInBufferSize
!= NULL
)
929 *lpInBufferSize
= PipeLocalInformation
.InboundQuota
;
931 if (lpMaxInstances
!= NULL
)
933 if (PipeLocalInformation
.MaximumInstances
>= 255)
934 *lpMaxInstances
= PIPE_UNLIMITED_INSTANCES
;
936 *lpMaxInstances
= PipeLocalInformation
.MaximumInstances
;
947 PeekNamedPipe(HANDLE hNamedPipe
,
951 LPDWORD lpTotalBytesAvail
,
952 LPDWORD lpBytesLeftThisMessage
)
954 PFILE_PIPE_PEEK_BUFFER Buffer
;
955 IO_STATUS_BLOCK Iosb
;
959 BufferSize
= nBufferSize
+ sizeof(FILE_PIPE_PEEK_BUFFER
);
960 Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
964 Status
= NtFsControlFile(hNamedPipe
,
974 if (Status
== STATUS_PENDING
)
976 Status
= NtWaitForSingleObject(hNamedPipe
,
979 if (NT_SUCCESS(Status
))
980 Status
= Iosb
.Status
;
983 if (Status
== STATUS_BUFFER_OVERFLOW
)
985 Status
= STATUS_SUCCESS
;
988 if (!NT_SUCCESS(Status
))
990 RtlFreeHeap(RtlGetProcessHeap(),
993 SetLastErrorByStatus(Status
);
997 if (lpTotalBytesAvail
!= NULL
)
999 *lpTotalBytesAvail
= Buffer
->ReadDataAvailable
;
1002 if (lpBytesRead
!= NULL
)
1004 *lpBytesRead
= Iosb
.Information
- sizeof(FILE_PIPE_PEEK_BUFFER
);
1007 if (lpBytesLeftThisMessage
!= NULL
)
1009 *lpBytesLeftThisMessage
= Buffer
->MessageLength
-
1010 (Iosb
.Information
- sizeof(FILE_PIPE_PEEK_BUFFER
));
1013 if (lpBuffer
!= NULL
)
1015 memcpy(lpBuffer
, Buffer
->Data
,
1016 min(nBufferSize
, Iosb
.Information
- sizeof(FILE_PIPE_PEEK_BUFFER
)));
1019 RtlFreeHeap(RtlGetProcessHeap(),
1031 TransactNamedPipe(IN HANDLE hNamedPipe
,
1032 IN LPVOID lpInBuffer
,
1033 IN DWORD nInBufferSize
,
1034 OUT LPVOID lpOutBuffer
,
1035 IN DWORD nOutBufferSize
,
1036 OUT LPDWORD lpBytesRead OPTIONAL
,
1037 IN LPOVERLAPPED lpOverlapped OPTIONAL
)
1041 if (lpBytesRead
!= NULL
)
1046 if (lpOverlapped
!= NULL
)
1050 ApcContext
= (((ULONG_PTR
)lpOverlapped
->hEvent
& 0x1) ? NULL
: lpOverlapped
);
1051 lpOverlapped
->Internal
= STATUS_PENDING
;
1053 Status
= NtFsControlFile(hNamedPipe
,
1054 lpOverlapped
->hEvent
,
1057 (PIO_STATUS_BLOCK
)lpOverlapped
,
1058 FSCTL_PIPE_TRANSCEIVE
,
1064 /* return FALSE in case of failure and pending operations! */
1065 if (!NT_SUCCESS(Status
) || Status
== STATUS_PENDING
)
1067 SetLastErrorByStatus(Status
);
1071 if (lpBytesRead
!= NULL
)
1073 *lpBytesRead
= lpOverlapped
->InternalHigh
;
1078 IO_STATUS_BLOCK Iosb
;
1080 Status
= NtFsControlFile(hNamedPipe
,
1085 FSCTL_PIPE_TRANSCEIVE
,
1091 /* wait in case operation is pending */
1092 if (Status
== STATUS_PENDING
)
1094 Status
= NtWaitForSingleObject(hNamedPipe
,
1097 if (NT_SUCCESS(Status
))
1099 Status
= Iosb
.Status
;
1103 if (NT_SUCCESS(Status
))
1105 /* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
1106 check that case either and crashes (only after the operation
1108 *lpBytesRead
= Iosb
.Information
;
1112 SetLastErrorByStatus(Status
);