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 *****************************************************************/
17 #include <kernel32/kernel32.h>
19 /* FUNCTIONS ****************************************************************/
25 CreateNamedPipeA(LPCSTR lpName,
31 DWORD nDefaultTimeOut,
32 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
34 HANDLE NamedPipeHandle;
38 RtlInitAnsiString(&NameA, (LPSTR)lpName);
39 RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE);
41 NamedPipeHandle = CreateNamedPipeW(NameU.Buffer,
48 lpSecurityAttributes);
50 RtlFreeUnicodeString(&NameU);
52 return(NamedPipeHandle);
60 CreateNamedPipeW(LPCWSTR lpName,
66 DWORD nDefaultTimeOut,
67 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
69 UNICODE_STRING NamedPipeName;
72 OBJECT_ATTRIBUTES ObjectAttributes;
74 ACCESS_MASK DesiredAccess;
76 ULONG CreateDisposition;
77 BOOLEAN WriteModeMessage;
78 BOOLEAN ReadModeMessage;
82 LARGE_INTEGER DefaultTimeOut;
84 Result = RtlDosPathNameToNtPathName_U((LPWSTR)lpName,
90 SetLastError(ERROR_PATH_NOT_FOUND);
91 return(INVALID_HANDLE_VALUE);
94 DPRINT("Pipe name: %wZ\n", &NamedPipeName);
95 DPRINT("Pipe name: %S\n", NamedPipeName.Buffer);
97 InitializeObjectAttributes(&ObjectAttributes,
107 CreateDisposition = FILE_OPEN_IF;
110 if (dwOpenMode & FILE_FLAG_WRITE_THROUGH)
112 CreateOptions = CreateOptions | FILE_WRITE_THROUGH;
114 if (dwOpenMode & FILE_FLAG_OVERLAPPED)
116 CreateOptions = CreateOptions | FILE_SYNCHRONOUS_IO_ALERT;
118 if (dwOpenMode & PIPE_ACCESS_DUPLEX)
120 CreateOptions = CreateOptions | FILE_PIPE_FULL_DUPLEX;
122 else if (dwOpenMode & PIPE_ACCESS_INBOUND)
124 CreateOptions = CreateOptions | FILE_PIPE_INBOUND;
126 else if (dwOpenMode & PIPE_ACCESS_OUTBOUND)
128 CreateOptions = CreateOptions | FILE_PIPE_OUTBOUND;
131 if (dwPipeMode & PIPE_TYPE_BYTE)
133 WriteModeMessage = FALSE;
135 else if (dwPipeMode & PIPE_TYPE_MESSAGE)
137 WriteModeMessage = TRUE;
141 WriteModeMessage = FALSE;
144 if (dwPipeMode & PIPE_READMODE_BYTE)
146 ReadModeMessage = FALSE;
148 else if (dwPipeMode & PIPE_READMODE_MESSAGE)
150 ReadModeMessage = TRUE;
154 ReadModeMessage = FALSE;
157 if (dwPipeMode & PIPE_WAIT)
161 else if (dwPipeMode & PIPE_NOWAIT)
170 if (nMaxInstances >= PIPE_UNLIMITED_INSTANCES)
172 nMaxInstances = ULONG_MAX;
175 DefaultTimeOut.QuadPart = nDefaultTimeOut * -10000;
177 Status = NtCreateNamedPipeFile(&PipeHandle,
192 RtlFreeUnicodeString(&NamedPipeName);
194 if (!NT_SUCCESS(Status))
196 DPRINT("NtCreateNamedPipe failed (Status %x)!\n", Status);
197 SetLastErrorByStatus (Status);
198 return(INVALID_HANDLE_VALUE);
209 WaitNamedPipeA(LPCSTR lpNamedPipeName,
213 UNICODE_STRING NameU;
216 RtlInitAnsiString(&NameA, (LPSTR)lpNamedPipeName);
217 RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE);
219 r = WaitNamedPipeW(NameU.Buffer, nTimeOut);
221 RtlFreeUnicodeString(&NameU);
231 WaitNamedPipeW(LPCWSTR lpNamedPipeName,
234 UNICODE_STRING NamedPipeName;
237 OBJECT_ATTRIBUTES ObjectAttributes;
238 NPFS_WAIT_PIPE WaitPipe;
240 IO_STATUS_BLOCK Iosb;
242 r = RtlDosPathNameToNtPathName_U((LPWSTR)lpNamedPipeName,
252 InitializeObjectAttributes(&ObjectAttributes,
254 OBJ_CASE_INSENSITIVE,
257 Status = NtOpenFile(&FileHandle,
262 FILE_SYNCHRONOUS_IO_ALERT);
263 if (!NT_SUCCESS(Status))
265 SetLastErrorByStatus (Status);
269 WaitPipe.Timeout.QuadPart = nTimeOut * -10000;
271 Status = NtFsControlFile(FileHandle,
282 if (!NT_SUCCESS(Status))
284 SetLastErrorByStatus (Status);
296 ConnectNamedPipe(HANDLE hNamedPipe,
297 LPOVERLAPPED lpOverlapped)
299 PIO_STATUS_BLOCK IoStatusBlock;
300 IO_STATUS_BLOCK Iosb;
304 if (lpOverlapped != NULL)
306 lpOverlapped->Internal = STATUS_PENDING;
307 hEvent = lpOverlapped->hEvent;
308 IoStatusBlock = (PIO_STATUS_BLOCK)lpOverlapped;
312 IoStatusBlock = &Iosb;
316 Status = NtFsControlFile(hNamedPipe,
326 if ((lpOverlapped == NULL) && (Status == STATUS_PENDING))
328 Status = NtWaitForSingleObject(hNamedPipe,
331 if (!NT_SUCCESS(Status))
333 SetLastErrorByStatus(Status);
336 Status = Iosb.Status;
338 if ((!NT_SUCCESS(Status) && Status != STATUS_PIPE_CONNECTED) ||
339 (Status == STATUS_PENDING))
341 SetLastErrorByStatus(Status);
352 SetNamedPipeHandleState(HANDLE hNamedPipe,
354 LPDWORD lpMaxCollectionCount,
355 LPDWORD lpCollectDataTimeout)
357 NPFS_GET_STATE GetState;
358 NPFS_SET_STATE SetState;
359 IO_STATUS_BLOCK Iosb;
362 Status = NtFsControlFile(hNamedPipe,
367 FSCTL_PIPE_GET_STATE,
371 sizeof(NPFS_GET_STATE));
372 if (Status == STATUS_PENDING)
374 Status = NtWaitForSingleObject(hNamedPipe,
377 if (!NT_SUCCESS(Status))
379 SetLastErrorByStatus(Status);
386 if ((*lpMode) & PIPE_READMODE_MESSAGE)
388 SetState.ReadModeMessage = TRUE;
392 SetState.ReadModeMessage = FALSE;
394 if ((*lpMode) & PIPE_NOWAIT)
396 SetState.NonBlocking = TRUE;
400 SetState.NonBlocking = FALSE;
402 SetState.WriteModeMessage = GetState.WriteModeMessage;
406 SetState.ReadModeMessage = GetState.ReadModeMessage;
407 SetState.WriteModeMessage = GetState.WriteModeMessage;
408 SetState.NonBlocking = SetState.NonBlocking;
411 if (lpMaxCollectionCount != NULL)
413 SetState.InBufferSize = *lpMaxCollectionCount;
417 SetState.InBufferSize = GetState.InBufferSize;
420 SetState.OutBufferSize = GetState.OutBufferSize;
422 if (lpCollectDataTimeout != NULL)
424 SetState.Timeout.QuadPart = (*lpCollectDataTimeout) * -10000;
428 SetState.Timeout = GetState.Timeout;
431 Status = NtFsControlFile(hNamedPipe,
436 FSCTL_PIPE_SET_STATE,
438 sizeof(NPFS_SET_STATE),
441 if (Status == STATUS_PENDING)
443 Status = NtWaitForSingleObject(hNamedPipe,
446 if (!NT_SUCCESS(Status))
448 SetLastErrorByStatus(Status);
461 CallNamedPipeA(LPCSTR lpNamedPipeName,
465 DWORD nOutBufferSize,
469 UNICODE_STRING PipeName;
472 RtlCreateUnicodeStringFromAsciiz(&PipeName,
473 (LPSTR)lpNamedPipeName);
475 Result = CallNamedPipeW(PipeName.Buffer,
483 RtlFreeUnicodeString(&PipeName);
493 CallNamedPipeW(LPCWSTR lpNamedPipeName,
497 DWORD nOutBufferSize,
501 HANDLE hPipe = INVALID_HANDLE_VALUE;
508 hPipe = CreateFileW(lpNamedPipeName,
509 GENERIC_READ | GENERIC_WRITE,
510 FILE_SHARE_READ | FILE_SHARE_WRITE,
513 FILE_ATTRIBUTE_NORMAL,
515 if (hPipe != INVALID_HANDLE_VALUE)
521 WaitNamedPipeW(lpNamedPipeName,
527 dwPipeMode = PIPE_READMODE_MESSAGE;
528 bError = SetNamedPipeHandleState(hPipe,
538 bError = TransactNamedPipe(hPipe,
555 DisconnectNamedPipe(HANDLE hNamedPipe)
557 IO_STATUS_BLOCK Iosb;
560 Status = NtFsControlFile(hNamedPipe,
565 FSCTL_PIPE_DISCONNECT,
570 if (Status == STATUS_PENDING)
572 Status = NtWaitForSingleObject(hNamedPipe,
575 if (!NT_SUCCESS(Status))
577 SetLastErrorByStatus(Status);
582 if (!NT_SUCCESS(Status))
584 SetLastErrorByStatus(Status);
595 GetNamedPipeHandleStateW(HANDLE hNamedPipe,
597 LPDWORD lpCurInstances,
598 LPDWORD lpMaxCollectionCount,
599 LPDWORD lpCollectDataTimeout,
601 DWORD nMaxUserNameSize)
603 FILE_PIPE_LOCAL_INFORMATION LocalInfo;
604 FILE_PIPE_INFORMATION PipeInfo;
605 IO_STATUS_BLOCK StatusBlock;
610 Status = NtQueryInformationFile(hNamedPipe,
613 sizeof(FILE_PIPE_INFORMATION),
614 FilePipeInformation);
615 if (!NT_SUCCESS(Status))
617 SetLastErrorByStatus(Status);
620 *lpState = 0; /* FIXME */
623 if (lpCurInstances != NULL)
625 Status = NtQueryInformationFile(hNamedPipe,
628 sizeof(FILE_PIPE_LOCAL_INFORMATION),
629 FilePipeLocalInformation);
630 if (!NT_SUCCESS(Status))
632 SetLastErrorByStatus(Status);
635 *lpCurInstances = min(LocalInfo.CurrentInstances, 255);
639 /* FIXME: retrieve remaining information */
650 GetNamedPipeHandleStateA(HANDLE hNamedPipe,
652 LPDWORD lpCurInstances,
653 LPDWORD lpMaxCollectionCount,
654 LPDWORD lpCollectDataTimeout,
656 DWORD nMaxUserNameSize)
658 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
667 GetNamedPipeInfo(HANDLE hNamedPipe,
669 LPDWORD lpOutBufferSize,
670 LPDWORD lpInBufferSize,
671 LPDWORD lpMaxInstances)
673 FILE_PIPE_LOCAL_INFORMATION PipeLocalInformation;
674 IO_STATUS_BLOCK StatusBlock;
677 Status = NtQueryInformationFile(hNamedPipe,
679 &PipeLocalInformation,
680 sizeof(FILE_PIPE_LOCAL_INFORMATION),
681 FilePipeLocalInformation);
682 if (!NT_SUCCESS(Status))
684 SetLastErrorByStatus(Status);
690 *lpFlags = (PipeLocalInformation.NamedPipeEnd == FILE_PIPE_SERVER_END) ? PIPE_SERVER_END : PIPE_CLIENT_END;
691 *lpFlags |= (PipeLocalInformation.NamedPipeType == 1) ? PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE;
694 if (lpOutBufferSize != NULL)
695 *lpOutBufferSize = PipeLocalInformation.OutboundQuota;
697 if (lpInBufferSize != NULL)
698 *lpInBufferSize = PipeLocalInformation.InboundQuota;
700 if (lpMaxInstances != NULL)
702 if (PipeLocalInformation.MaximumInstances >= 255)
703 *lpMaxInstances = PIPE_UNLIMITED_INSTANCES;
705 *lpMaxInstances = PipeLocalInformation.MaximumInstances;
716 PeekNamedPipe(HANDLE hNamedPipe,
720 LPDWORD lpTotalBytesAvail,
721 LPDWORD lpBytesLeftThisMessage)
723 PFILE_PIPE_PEEK_BUFFER Buffer;
724 IO_STATUS_BLOCK Iosb;
728 BufferSize = nBufferSize + sizeof(FILE_PIPE_PEEK_BUFFER);
729 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
733 Status = NtFsControlFile(hNamedPipe,
743 if (Status == STATUS_PENDING)
745 Status = NtWaitForSingleObject(hNamedPipe,
748 if (NT_SUCCESS(Status))
749 Status = Iosb.Status;
752 if (Status == STATUS_BUFFER_OVERFLOW)
754 Status = STATUS_SUCCESS;
757 if (!NT_SUCCESS(Status))
759 RtlFreeHeap(RtlGetProcessHeap(),
762 SetLastErrorByStatus(Status);
766 if (lpTotalBytesAvail != NULL)
768 *lpTotalBytesAvail = Buffer->ReadDataAvailable;
771 if (lpBytesRead != NULL)
773 *lpBytesRead = Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER);
776 if (lpBytesLeftThisMessage != NULL)
778 *lpBytesLeftThisMessage = Buffer->MessageLength -
779 (Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER));
782 if (lpBuffer != NULL)
784 memcpy(lpBuffer, Buffer->Data,
785 min(nBufferSize, Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER)));
788 RtlFreeHeap(RtlGetProcessHeap(),
800 TransactNamedPipe(HANDLE hNamedPipe,
804 DWORD nOutBufferSize,
806 LPOVERLAPPED lpOverlapped)
808 IO_STATUS_BLOCK IoStatusBlock;
811 if (lpOverlapped == NULL)
813 Status = NtFsControlFile(hNamedPipe,
818 FSCTL_PIPE_TRANSCEIVE,
823 if (Status == STATUS_PENDING)
825 NtWaitForSingleObject(hNamedPipe,
828 Status = IoStatusBlock.Status;
830 if (NT_SUCCESS(Status))
832 *lpBytesRead = IoStatusBlock.Information;
837 lpOverlapped->Internal = STATUS_PENDING;
839 Status = NtFsControlFile(hNamedPipe,
840 lpOverlapped->hEvent,
843 (PIO_STATUS_BLOCK)lpOverlapped,
844 FSCTL_PIPE_TRANSCEIVE,
851 if (!NT_SUCCESS(Status))
853 SetLastErrorByStatus(Status);