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 ****************************************************************/
22 CreateNamedPipeA(LPCSTR lpName,
28 DWORD nDefaultTimeOut,
29 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
31 HANDLE NamedPipeHandle;
35 RtlInitAnsiString(&NameA, (LPSTR)lpName);
36 RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE);
38 NamedPipeHandle = CreateNamedPipeW(NameU.Buffer,
45 lpSecurityAttributes);
47 RtlFreeUnicodeString(&NameU);
49 return(NamedPipeHandle);
54 CreateNamedPipeW(LPCWSTR lpName,
60 DWORD nDefaultTimeOut,
61 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
63 UNICODE_STRING NamedPipeName;
66 OBJECT_ATTRIBUTES ObjectAttributes;
68 ACCESS_MASK DesiredAccess;
70 ULONG CreateDisposition;
71 BOOLEAN WriteModeMessage;
72 BOOLEAN ReadModeMessage;
76 LARGE_INTEGER DefaultTimeOut;
78 Result = RtlDosPathNameToNtPathName_U((LPWSTR)lpName,
84 SetLastError(ERROR_PATH_NOT_FOUND);
85 return(INVALID_HANDLE_VALUE);
88 DPRINT("Pipe name: %wZ\n", &NamedPipeName);
89 DPRINT("Pipe name: %S\n", NamedPipeName.Buffer);
91 InitializeObjectAttributes(&ObjectAttributes,
101 CreateDisposition = FILE_OPEN_IF;
104 if (dwOpenMode & FILE_FLAG_WRITE_THROUGH)
106 CreateOptions = CreateOptions | FILE_WRITE_THROUGH;
108 if (dwOpenMode & FILE_FLAG_OVERLAPPED)
110 CreateOptions = CreateOptions | FILE_SYNCHRONOUS_IO_ALERT;
112 if (dwOpenMode & PIPE_ACCESS_DUPLEX)
114 CreateOptions = CreateOptions | FILE_PIPE_FULL_DUPLEX;
116 else if (dwOpenMode & PIPE_ACCESS_INBOUND)
118 CreateOptions = CreateOptions | FILE_PIPE_INBOUND;
120 else if (dwOpenMode & PIPE_ACCESS_OUTBOUND)
122 CreateOptions = CreateOptions | FILE_PIPE_OUTBOUND;
125 if (dwPipeMode & PIPE_TYPE_BYTE)
127 WriteModeMessage = FALSE;
129 else if (dwPipeMode & PIPE_TYPE_MESSAGE)
131 WriteModeMessage = TRUE;
135 WriteModeMessage = FALSE;
138 if (dwPipeMode & PIPE_READMODE_BYTE)
140 ReadModeMessage = FALSE;
142 else if (dwPipeMode & PIPE_READMODE_MESSAGE)
144 ReadModeMessage = TRUE;
148 ReadModeMessage = FALSE;
151 if (dwPipeMode & PIPE_WAIT)
155 else if (dwPipeMode & PIPE_NOWAIT)
164 if (nMaxInstances >= PIPE_UNLIMITED_INSTANCES)
166 nMaxInstances = ULONG_MAX;
169 DefaultTimeOut.QuadPart = nDefaultTimeOut * -10000;
171 Status = NtCreateNamedPipeFile(&PipeHandle,
186 RtlFreeUnicodeString(&NamedPipeName);
188 if (!NT_SUCCESS(Status))
190 DPRINT("NtCreateNamedPipe failed (Status %x)!\n", Status);
191 SetLastErrorByStatus (Status);
192 return(INVALID_HANDLE_VALUE);
200 WaitNamedPipeA(LPCSTR lpNamedPipeName,
204 UNICODE_STRING NameU;
207 RtlInitAnsiString(&NameA, (LPSTR)lpNamedPipeName);
208 RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE);
210 r = WaitNamedPipeW(NameU.Buffer, nTimeOut);
212 RtlFreeUnicodeString(&NameU);
219 WaitNamedPipeW(LPCWSTR lpNamedPipeName,
222 UNICODE_STRING NamedPipeName;
225 OBJECT_ATTRIBUTES ObjectAttributes;
226 NPFS_WAIT_PIPE WaitPipe;
228 IO_STATUS_BLOCK Iosb;
230 r = RtlDosPathNameToNtPathName_U((LPWSTR)lpNamedPipeName,
240 InitializeObjectAttributes(&ObjectAttributes,
242 OBJ_CASE_INSENSITIVE,
245 Status = NtOpenFile(&FileHandle,
250 FILE_SYNCHRONOUS_IO_ALERT);
251 if (!NT_SUCCESS(Status))
253 SetLastErrorByStatus (Status);
257 WaitPipe.Timeout.QuadPart = nTimeOut * -10000;
259 Status = NtFsControlFile(FileHandle,
270 if (!NT_SUCCESS(Status))
272 SetLastErrorByStatus (Status);
281 ConnectNamedPipe(HANDLE hNamedPipe,
282 LPOVERLAPPED lpOverlapped)
284 PIO_STATUS_BLOCK IoStatusBlock;
285 IO_STATUS_BLOCK Iosb;
289 if (lpOverlapped != NULL)
291 lpOverlapped->Internal = STATUS_PENDING;
292 hEvent = lpOverlapped->hEvent;
293 IoStatusBlock = (PIO_STATUS_BLOCK)lpOverlapped;
297 IoStatusBlock = &Iosb;
301 Status = NtFsControlFile(hNamedPipe,
311 if ((lpOverlapped == NULL) && (Status == STATUS_PENDING))
313 Status = NtWaitForSingleObject(hNamedPipe,
316 if (!NT_SUCCESS(Status))
318 SetLastErrorByStatus(Status);
321 Status = Iosb.Status;
323 if ((!NT_SUCCESS(Status) && Status != STATUS_PIPE_CONNECTED) ||
324 (Status == STATUS_PENDING))
326 SetLastErrorByStatus(Status);
334 SetNamedPipeHandleState(HANDLE hNamedPipe,
336 LPDWORD lpMaxCollectionCount,
337 LPDWORD lpCollectDataTimeout)
339 NPFS_GET_STATE GetState;
340 NPFS_SET_STATE SetState;
341 IO_STATUS_BLOCK Iosb;
344 Status = NtFsControlFile(hNamedPipe,
349 FSCTL_PIPE_GET_STATE,
353 sizeof(NPFS_GET_STATE));
354 if (Status == STATUS_PENDING)
356 Status = NtWaitForSingleObject(hNamedPipe,
359 if (!NT_SUCCESS(Status))
361 SetLastErrorByStatus(Status);
368 if ((*lpMode) & PIPE_READMODE_MESSAGE)
370 SetState.ReadModeMessage = TRUE;
374 SetState.ReadModeMessage = FALSE;
376 if ((*lpMode) & PIPE_NOWAIT)
378 SetState.NonBlocking = TRUE;
382 SetState.NonBlocking = FALSE;
384 SetState.WriteModeMessage = GetState.WriteModeMessage;
388 SetState.ReadModeMessage = GetState.ReadModeMessage;
389 SetState.WriteModeMessage = GetState.WriteModeMessage;
390 SetState.NonBlocking = SetState.NonBlocking;
393 if (lpMaxCollectionCount != NULL)
395 SetState.InBufferSize = *lpMaxCollectionCount;
399 SetState.InBufferSize = GetState.InBufferSize;
402 SetState.OutBufferSize = GetState.OutBufferSize;
404 if (lpCollectDataTimeout != NULL)
406 SetState.Timeout.QuadPart = (*lpCollectDataTimeout) * -10000;
410 SetState.Timeout = GetState.Timeout;
413 Status = NtFsControlFile(hNamedPipe,
418 FSCTL_PIPE_SET_STATE,
420 sizeof(NPFS_SET_STATE),
423 if (Status == STATUS_PENDING)
425 Status = NtWaitForSingleObject(hNamedPipe,
428 if (!NT_SUCCESS(Status))
430 SetLastErrorByStatus(Status);
440 CallNamedPipeA(LPCSTR lpNamedPipeName,
444 DWORD nOutBufferSize,
448 UNICODE_STRING PipeName;
451 RtlCreateUnicodeStringFromAsciiz(&PipeName,
452 (LPSTR)lpNamedPipeName);
454 Result = CallNamedPipeW(PipeName.Buffer,
462 RtlFreeUnicodeString(&PipeName);
469 CallNamedPipeW(LPCWSTR lpNamedPipeName,
473 DWORD nOutBufferSize,
477 HANDLE hPipe = INVALID_HANDLE_VALUE;
484 hPipe = CreateFileW(lpNamedPipeName,
485 GENERIC_READ | GENERIC_WRITE,
486 FILE_SHARE_READ | FILE_SHARE_WRITE,
489 FILE_ATTRIBUTE_NORMAL,
491 if (hPipe != INVALID_HANDLE_VALUE)
497 WaitNamedPipeW(lpNamedPipeName,
503 dwPipeMode = PIPE_READMODE_MESSAGE;
504 bError = SetNamedPipeHandleState(hPipe,
514 bError = TransactNamedPipe(hPipe,
528 DisconnectNamedPipe(HANDLE hNamedPipe)
530 IO_STATUS_BLOCK Iosb;
533 Status = NtFsControlFile(hNamedPipe,
538 FSCTL_PIPE_DISCONNECT,
543 if (Status == STATUS_PENDING)
545 Status = NtWaitForSingleObject(hNamedPipe,
548 if (!NT_SUCCESS(Status))
550 SetLastErrorByStatus(Status);
555 if (!NT_SUCCESS(Status))
557 SetLastErrorByStatus(Status);
565 GetNamedPipeHandleStateW(HANDLE hNamedPipe,
567 LPDWORD lpCurInstances,
568 LPDWORD lpMaxCollectionCount,
569 LPDWORD lpCollectDataTimeout,
571 DWORD nMaxUserNameSize)
573 FILE_PIPE_LOCAL_INFORMATION LocalInfo;
574 FILE_PIPE_INFORMATION PipeInfo;
575 IO_STATUS_BLOCK StatusBlock;
580 Status = NtQueryInformationFile(hNamedPipe,
583 sizeof(FILE_PIPE_INFORMATION),
584 FilePipeInformation);
585 if (!NT_SUCCESS(Status))
587 SetLastErrorByStatus(Status);
590 *lpState = 0; /* FIXME */
593 if (lpCurInstances != NULL)
595 Status = NtQueryInformationFile(hNamedPipe,
598 sizeof(FILE_PIPE_LOCAL_INFORMATION),
599 FilePipeLocalInformation);
600 if (!NT_SUCCESS(Status))
602 SetLastErrorByStatus(Status);
605 *lpCurInstances = min(LocalInfo.CurrentInstances, 255);
609 /* FIXME: retrieve remaining information */
617 GetNamedPipeHandleStateA(HANDLE hNamedPipe,
619 LPDWORD lpCurInstances,
620 LPDWORD lpMaxCollectionCount,
621 LPDWORD lpCollectDataTimeout,
623 DWORD nMaxUserNameSize)
625 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
631 GetNamedPipeInfo(HANDLE hNamedPipe,
633 LPDWORD lpOutBufferSize,
634 LPDWORD lpInBufferSize,
635 LPDWORD lpMaxInstances)
637 FILE_PIPE_LOCAL_INFORMATION PipeLocalInformation;
638 IO_STATUS_BLOCK StatusBlock;
641 Status = NtQueryInformationFile(hNamedPipe,
643 &PipeLocalInformation,
644 sizeof(FILE_PIPE_LOCAL_INFORMATION),
645 FilePipeLocalInformation);
646 if (!NT_SUCCESS(Status))
648 SetLastErrorByStatus(Status);
654 *lpFlags = (PipeLocalInformation.NamedPipeEnd == FILE_PIPE_SERVER_END) ? PIPE_SERVER_END : PIPE_CLIENT_END;
655 *lpFlags |= (PipeLocalInformation.NamedPipeType == 1) ? PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE;
658 if (lpOutBufferSize != NULL)
659 *lpOutBufferSize = PipeLocalInformation.OutboundQuota;
661 if (lpInBufferSize != NULL)
662 *lpInBufferSize = PipeLocalInformation.InboundQuota;
664 if (lpMaxInstances != NULL)
666 if (PipeLocalInformation.MaximumInstances >= 255)
667 *lpMaxInstances = PIPE_UNLIMITED_INSTANCES;
669 *lpMaxInstances = PipeLocalInformation.MaximumInstances;
677 PeekNamedPipe(HANDLE hNamedPipe,
681 LPDWORD lpTotalBytesAvail,
682 LPDWORD lpBytesLeftThisMessage)
684 PFILE_PIPE_PEEK_BUFFER Buffer;
685 IO_STATUS_BLOCK Iosb;
689 BufferSize = nBufferSize + sizeof(FILE_PIPE_PEEK_BUFFER);
690 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
694 Status = NtFsControlFile(hNamedPipe,
704 if (Status == STATUS_PENDING)
706 Status = NtWaitForSingleObject(hNamedPipe,
709 if (NT_SUCCESS(Status))
710 Status = Iosb.Status;
713 if (Status == STATUS_BUFFER_OVERFLOW)
715 Status = STATUS_SUCCESS;
718 if (!NT_SUCCESS(Status))
720 RtlFreeHeap(RtlGetProcessHeap(),
723 SetLastErrorByStatus(Status);
727 if (lpTotalBytesAvail != NULL)
729 *lpTotalBytesAvail = Buffer->ReadDataAvailable;
732 if (lpBytesRead != NULL)
734 *lpBytesRead = Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER);
737 if (lpBytesLeftThisMessage != NULL)
739 *lpBytesLeftThisMessage = Buffer->MessageLength -
740 (Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER));
743 if (lpBuffer != NULL)
745 memcpy(lpBuffer, Buffer->Data,
746 min(nBufferSize, Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER)));
749 RtlFreeHeap(RtlGetProcessHeap(),
758 TransactNamedPipe(HANDLE hNamedPipe,
762 DWORD nOutBufferSize,
764 LPOVERLAPPED lpOverlapped)
766 IO_STATUS_BLOCK IoStatusBlock;
769 if (lpOverlapped == NULL)
771 Status = NtFsControlFile(hNamedPipe,
776 FSCTL_PIPE_TRANSCEIVE,
781 if (Status == STATUS_PENDING)
783 NtWaitForSingleObject(hNamedPipe,
786 Status = IoStatusBlock.Status;
788 if (NT_SUCCESS(Status))
790 *lpBytesRead = IoStatusBlock.Information;
795 lpOverlapped->Internal = STATUS_PENDING;
797 Status = NtFsControlFile(hNamedPipe,
798 lpOverlapped->hEvent,
801 (PIO_STATUS_BLOCK)lpOverlapped,
802 FSCTL_PIPE_TRANSCEIVE,
809 if (!NT_SUCCESS(Status))
811 SetLastErrorByStatus(Status);