-/* $Id: npipe.c,v 1.15 2003/07/10 18:50:51 chorns Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
#include <k32.h>
-
#define NDEBUG
-#include <kernel32/kernel32.h>
+#include "../include/debug.h"
/* FUNCTIONS ****************************************************************/
ACCESS_MASK DesiredAccess;
ULONG CreateOptions;
ULONG CreateDisposition;
- BOOLEAN WriteModeMessage;
- BOOLEAN ReadModeMessage;
- BOOLEAN NonBlocking;
+ ULONG WriteModeMessage;
+ ULONG ReadModeMessage;
+ ULONG NonBlocking;
IO_STATUS_BLOCK Iosb;
- ULONG ShareAccess;
+ ULONG ShareAccess, Attributes;
LARGE_INTEGER DefaultTimeOut;
-
+ PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
+
Result = RtlDosPathNameToNtPathName_U((LPWSTR)lpName,
&NamedPipeName,
NULL,
SetLastError(ERROR_PATH_NOT_FOUND);
return(INVALID_HANDLE_VALUE);
}
-
+
DPRINT("Pipe name: %wZ\n", &NamedPipeName);
DPRINT("Pipe name: %S\n", NamedPipeName.Buffer);
-
+
+ Attributes = OBJ_CASE_INSENSITIVE;
+ if(lpSecurityAttributes)
+ {
+ SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
+ if(lpSecurityAttributes->bInheritHandle)
+ Attributes |= OBJ_INHERIT;
+ }
+
InitializeObjectAttributes(&ObjectAttributes,
&NamedPipeName,
- OBJ_CASE_INSENSITIVE,
+ Attributes,
NULL,
- NULL);
-
+ SecurityDescriptor);
+
DesiredAccess = 0;
-
ShareAccess = 0;
-
CreateDisposition = FILE_OPEN_IF;
-
CreateOptions = 0;
if (dwOpenMode & FILE_FLAG_WRITE_THROUGH)
{
CreateOptions = CreateOptions | FILE_WRITE_THROUGH;
}
- if (dwOpenMode & FILE_FLAG_OVERLAPPED)
+ if (!(dwOpenMode & FILE_FLAG_OVERLAPPED))
{
- CreateOptions = CreateOptions | FILE_SYNCHRONOUS_IO_ALERT;
+ CreateOptions = CreateOptions | FILE_SYNCHRONOUS_IO_NONALERT;
}
if (dwOpenMode & PIPE_ACCESS_DUPLEX)
{
CreateOptions = CreateOptions | FILE_PIPE_FULL_DUPLEX;
+ DesiredAccess |= (FILE_GENERIC_READ | FILE_GENERIC_WRITE);
}
else if (dwOpenMode & PIPE_ACCESS_INBOUND)
{
CreateOptions = CreateOptions | FILE_PIPE_INBOUND;
+ DesiredAccess |= FILE_GENERIC_READ;
}
else if (dwOpenMode & PIPE_ACCESS_OUTBOUND)
{
CreateOptions = CreateOptions | FILE_PIPE_OUTBOUND;
+ DesiredAccess |= FILE_GENERIC_WRITE;
}
-
+
if (dwPipeMode & PIPE_TYPE_BYTE)
{
- WriteModeMessage = FALSE;
+ WriteModeMessage = FILE_PIPE_BYTE_STREAM_MODE;
}
else if (dwPipeMode & PIPE_TYPE_MESSAGE)
{
- WriteModeMessage = TRUE;
+ WriteModeMessage = FILE_PIPE_MESSAGE_MODE;
}
else
{
- WriteModeMessage = FALSE;
+ WriteModeMessage = FILE_PIPE_BYTE_STREAM_MODE;
}
-
+
if (dwPipeMode & PIPE_READMODE_BYTE)
{
- ReadModeMessage = FALSE;
+ ReadModeMessage = FILE_PIPE_BYTE_STREAM_MODE;
}
else if (dwPipeMode & PIPE_READMODE_MESSAGE)
{
- ReadModeMessage = TRUE;
+ ReadModeMessage = FILE_PIPE_MESSAGE_MODE;
}
else
{
- ReadModeMessage = FALSE;
+ ReadModeMessage = FILE_PIPE_BYTE_STREAM_MODE;
}
-
+
if (dwPipeMode & PIPE_WAIT)
{
- NonBlocking = FALSE;
+ NonBlocking = FILE_PIPE_QUEUE_OPERATION;
}
else if (dwPipeMode & PIPE_NOWAIT)
{
- NonBlocking = TRUE;
+ NonBlocking = FILE_PIPE_COMPLETE_OPERATION;
}
else
{
- NonBlocking = FALSE;
+ NonBlocking = FILE_PIPE_QUEUE_OPERATION;
}
-
+
if (nMaxInstances >= PIPE_UNLIMITED_INSTANCES)
{
nMaxInstances = ULONG_MAX;
}
-
+
DefaultTimeOut.QuadPart = nDefaultTimeOut * -10000;
-
+
Status = NtCreateNamedPipeFile(&PipeHandle,
DesiredAccess,
&ObjectAttributes,
nInBufferSize,
nOutBufferSize,
&DefaultTimeOut);
-
+
RtlFreeUnicodeString(&NamedPipeName);
-
+
if (!NT_SUCCESS(Status))
{
DPRINT("NtCreateNamedPipe failed (Status %x)!\n", Status);
SetLastErrorByStatus (Status);
- return(INVALID_HANDLE_VALUE);
+ return INVALID_HANDLE_VALUE;
}
-
- return(PipeHandle);
+
+ return PipeHandle;
}
&NamedPipeName,
NULL,
NULL);
-
if (!r)
{
return(FALSE);
FILE_GENERIC_READ,
&ObjectAttributes,
&Iosb,
- 0,
- FILE_SYNCHRONOUS_IO_ALERT);
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus (Status);
0,
NULL,
0);
+ if ((lpOverlapped != NULL) && (Status == STATUS_PENDING))
+ return TRUE;
+
if ((lpOverlapped == NULL) && (Status == STATUS_PENDING))
{
Status = NtWaitForSingleObject(hNamedPipe,
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
- return(FALSE);
+ return FALSE;
}
Status = Iosb.Status;
}
+
if ((!NT_SUCCESS(Status) && Status != STATUS_PIPE_CONNECTED) ||
(Status == STATUS_PENDING))
{
SetLastErrorByStatus(Status);
- return(FALSE);
+ return FALSE;
}
- return(TRUE);
+
+ return TRUE;
}
/*
* @unimplemented
*/
-WINBOOL STDCALL
+BOOL STDCALL
GetNamedPipeHandleStateW(HANDLE hNamedPipe,
LPDWORD lpState,
LPDWORD lpCurInstances,
LPWSTR lpUserName,
DWORD nMaxUserNameSize)
{
- FILE_PIPE_LOCAL_INFORMATION LocalInfo;
- FILE_PIPE_INFORMATION PipeInfo;
IO_STATUS_BLOCK StatusBlock;
NTSTATUS Status;
if (lpState != NULL)
+ {
+ FILE_PIPE_INFORMATION PipeInfo;
+
+ Status = NtQueryInformationFile(hNamedPipe,
+ &StatusBlock,
+ &PipeInfo,
+ sizeof(FILE_PIPE_INFORMATION),
+ FilePipeInformation);
+ if (!NT_SUCCESS(Status))
{
- Status = NtQueryInformationFile(hNamedPipe,
- &StatusBlock,
- &PipeInfo,
- sizeof(FILE_PIPE_INFORMATION),
- FilePipeInformation);
- if (!NT_SUCCESS(Status))
- {
- SetLastErrorByStatus(Status);
- return(FALSE);
- }
- *lpState = 0; /* FIXME */
+ SetLastErrorByStatus(Status);
+ return FALSE;
}
- if (lpCurInstances != NULL)
+ *lpState = ((PipeInfo.CompletionMode != FILE_PIPE_QUEUE_OPERATION) ? PIPE_NOWAIT : PIPE_WAIT);
+ *lpState |= ((PipeInfo.ReadMode != FILE_PIPE_BYTE_STREAM_MODE) ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE);
+ }
+
+ if(lpCurInstances != NULL)
+ {
+ FILE_PIPE_LOCAL_INFORMATION LocalInfo;
+
+ Status = NtQueryInformationFile(hNamedPipe,
+ &StatusBlock,
+ &LocalInfo,
+ sizeof(FILE_PIPE_LOCAL_INFORMATION),
+ FilePipeLocalInformation);
+ if(!NT_SUCCESS(Status))
{
- Status = NtQueryInformationFile(hNamedPipe,
- &StatusBlock,
- &LocalInfo,
- sizeof(FILE_PIPE_LOCAL_INFORMATION),
- FilePipeLocalInformation);
- if (!NT_SUCCESS(Status))
- {
- SetLastErrorByStatus(Status);
- return(FALSE);
- }
- *lpCurInstances = min(LocalInfo.CurrentInstances, 255);
+ SetLastErrorByStatus(Status);
+ return FALSE;
}
+ *lpCurInstances = min(LocalInfo.CurrentInstances, PIPE_UNLIMITED_INSTANCES);
+ }
+
+ if(lpMaxCollectionCount != NULL || lpCollectDataTimeout != NULL)
+ {
+ FILE_PIPE_REMOTE_INFORMATION RemoteInfo;
+
+ Status = NtQueryInformationFile(hNamedPipe,
+ &StatusBlock,
+ &RemoteInfo,
+ sizeof(FILE_PIPE_REMOTE_INFORMATION),
+ FilePipeRemoteInformation);
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
- /* FIXME: retrieve remaining information */
-
-
- return(TRUE);
+ if(lpMaxCollectionCount != NULL)
+ {
+ *lpMaxCollectionCount = RemoteInfo.MaximumCollectionCount;
+ }
+
+ if(lpCollectDataTimeout != NULL)
+ {
+ /* FIXME */
+ *lpCollectDataTimeout = 0;
+ }
+ }
+
+ if(lpUserName != NULL)
+ {
+ /* FIXME - open the thread token, call ImpersonateNamedPipeClient() and
+ retreive the user name with GetUserName(), revert the impersonation
+ and finally restore the thread token */
+ }
+
+ return TRUE;
}
/*
- * @unimplemented
+ * @implemented
*/
-WINBOOL STDCALL
+BOOL STDCALL
GetNamedPipeHandleStateA(HANDLE hNamedPipe,
LPDWORD lpState,
LPDWORD lpCurInstances,
LPSTR lpUserName,
DWORD nMaxUserNameSize)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ UNICODE_STRING UserNameW;
+ ANSI_STRING UserNameA;
+ BOOL Ret;
+
+ if(lpUserName != NULL)
+ {
+ UserNameW.Length = 0;
+ UserNameW.MaximumLength = nMaxUserNameSize * sizeof(WCHAR);
+ UserNameW.Buffer = HeapAlloc(GetCurrentProcess(), 0, UserNameW.MaximumLength);
+
+ UserNameA.Buffer = lpUserName;
+ UserNameA.Length = 0;
+ UserNameA.MaximumLength = nMaxUserNameSize;
+ }
+
+ Ret = GetNamedPipeHandleStateW(hNamedPipe,
+ lpState,
+ lpCurInstances,
+ lpMaxCollectionCount,
+ lpCollectDataTimeout,
+ UserNameW.Buffer,
+ nMaxUserNameSize);
+
+ if(Ret && lpUserName != NULL)
+ {
+ NTSTATUS Status = RtlUnicodeStringToAnsiString(&UserNameA, &UserNameW, FALSE);
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ Ret = FALSE;
+ }
+ }
+
+ if(UserNameW.Buffer != NULL)
+ {
+ HeapFree(GetCurrentProcess(), 0, UserNameW.Buffer);
+ }
+
+ return Ret;
}
/*
* @implemented
*/
-WINBOOL STDCALL
+BOOL STDCALL
GetNamedPipeInfo(HANDLE hNamedPipe,
LPDWORD lpFlags,
LPDWORD lpOutBufferSize,