[KERNEL32]
[reactos.git] / reactos / dll / win32 / kernel32 / client / file / npipe.c
index 35410a1..6f7c061 100644 (file)
@@ -7,7 +7,7 @@
  *                  Ariadne ( ariadne@xs4all.nl)
  */
 
-/* INCLUDES *****************************************************************/
+/* INCLUDES *******************************************************************/
 
 #include <k32.h>
 #define NDEBUG
@@ -16,7 +16,114 @@ DEBUG_CHANNEL(kernel32file);
 
 //#define USING_PROPER_NPFS_WAIT_SEMANTICS
 
-/* FUNCTIONS ****************************************************************/
+/* GLOBALS ********************************************************************/
+
+LONG ProcessPipeId;
+
+/* FUNCTIONS ******************************************************************/
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+CreatePipe(PHANDLE hReadPipe,
+           PHANDLE hWritePipe,
+           LPSECURITY_ATTRIBUTES lpPipeAttributes,
+           DWORD nSize)
+{
+    WCHAR Buffer[64];
+    UNICODE_STRING PipeName;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK StatusBlock;
+    LARGE_INTEGER DefaultTimeout;
+    NTSTATUS Status;
+    HANDLE ReadPipeHandle;
+    HANDLE WritePipeHandle;
+    LONG PipeId;
+    ULONG Attributes;
+    PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
+
+    /* Set the timeout to 120 seconds */
+    DefaultTimeout.QuadPart = -1200000000;
+
+    /* Use default buffer size if desired */
+    if (!nSize) nSize = 0x1000;
+
+    /* Increase the Pipe ID */
+    PipeId = InterlockedIncrement(&ProcessPipeId);
+
+    /* Create the pipe name */
+    swprintf(Buffer,
+             L"\\Device\\NamedPipe\\Win32Pipes.%08x.%08x",
+             NtCurrentTeb()->ClientId.UniqueProcess,
+             PipeId);
+    RtlInitUnicodeString(&PipeName, Buffer);
+
+    /* Always use case insensitive */
+    Attributes = OBJ_CASE_INSENSITIVE;
+
+    /* Check if we got attributes */
+    if (lpPipeAttributes)
+    {
+        /* Use the attributes' SD instead */
+        SecurityDescriptor = lpPipeAttributes->lpSecurityDescriptor;
+
+        /* Set OBJ_INHERIT if requested */
+        if (lpPipeAttributes->bInheritHandle) Attributes |= OBJ_INHERIT;
+    }
+
+    /* Initialize the attributes */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &PipeName,
+                               Attributes,
+                               NULL,
+                               SecurityDescriptor);
+
+    /* Create the named pipe */
+    Status = NtCreateNamedPipeFile(&ReadPipeHandle,
+                                   GENERIC_READ |FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
+                                   &ObjectAttributes,
+                                   &StatusBlock,
+                                   FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                   FILE_CREATE,
+                                   FILE_SYNCHRONOUS_IO_NONALERT,
+                                   FILE_PIPE_BYTE_STREAM_TYPE,
+                                   FILE_PIPE_BYTE_STREAM_MODE,
+                                   FILE_PIPE_QUEUE_OPERATION,
+                                   1,
+                                   nSize,
+                                   nSize,
+                                   &DefaultTimeout);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Convert error and fail */
+        WARN("Status: %lx\n", Status);
+        BaseSetLastNTError(Status);
+        return FALSE;
+    }
+
+    /* Now try opening it for write access */
+    Status = NtOpenFile(&WritePipeHandle,
+                        FILE_GENERIC_WRITE | SYNCHRONIZE,
+                        &ObjectAttributes,
+                        &StatusBlock,
+                        FILE_SHARE_READ,
+                        FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Convert error and fail */
+        WARN("Status: %lx\n", Status);
+        NtClose(ReadPipeHandle);
+        BaseSetLastNTError(Status);
+        return FALSE;
+    }
+
+    /* Return both handles */
+    *hReadPipe = ReadPipeHandle;
+    *hWritePipe = WritePipeHandle;
+    return TRUE;
+}
 
 /*
  * @implemented
@@ -1066,7 +1173,7 @@ PeekNamedPipe(HANDLE hNamedPipe,
     NTSTATUS Status;
 
     /* Calculate the buffer space that we'll need and allocate it */
-    BufferSize = nBufferSize + sizeof(FILE_PIPE_PEEK_BUFFER);
+    BufferSize = FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[nBufferSize]);
     Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
     if (Buffer == NULL)
     {
@@ -1108,11 +1215,15 @@ PeekNamedPipe(HANDLE hNamedPipe,
 
     /* Check if caller requested bytes available */
     if (lpTotalBytesAvail)
+    {
+        /* Return bytes available */
         *lpTotalBytesAvail = Buffer->ReadDataAvailable;
+    }
 
     /* Calculate the bytes returned, minus our structure overhead */
     BytesRead = (ULONG)(Iosb.Information -
                         FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]));
+    ASSERT(BytesRead <= nBufferSize);
 
     /* Check if caller requested bytes read */
     if (lpBytesRead)