[KERNEL32] WaitNamedPipeW: Free Unicode buffer when leaving the function
[reactos.git] / reactos / dll / win32 / kernel32 / file / npipe.c
index 14c6d50..55aeed9 100644 (file)
 /* INCLUDES *****************************************************************/
 
 #include <k32.h>
+#include <wine/debug.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(kernel32file);
 
-#define NDEBUG
 //#define USING_PROPER_NPFS_WAIT_SEMANTICS
-#include "../include/debug.h"
 
 /* FUNCTIONS ****************************************************************/
 
@@ -54,7 +55,7 @@ CreateNamedPipeA(LPCSTR lpName,
  * @implemented
  */
 HANDLE
-STDCALL
+WINAPI
 CreateNamedPipeW(LPCWSTR lpName,
                  DWORD dwOpenMode,
                  DWORD dwPipeMode,
@@ -103,8 +104,8 @@ CreateNamedPipeW(LPCWSTR lpName,
         return INVALID_HANDLE_VALUE;
     }
 
-    DPRINT("Pipe name: %wZ\n", &NamedPipeName);
-    DPRINT("Pipe name: %S\n", NamedPipeName.Buffer);
+    TRACE("Pipe name: %wZ\n", &NamedPipeName);
+    TRACE("Pipe name: %S\n", NamedPipeName.Buffer);
 
     /* Always case insensitive, check if we got extra attributes */
     Attributes = OBJ_CASE_INSENSITIVE;
@@ -141,7 +142,7 @@ CreateNamedPipeW(LPCWSTR lpName,
         CreateOptions |= FILE_SYNCHRONOUS_IO_NONALERT;
     }
 
-    /* Handle all open modes */ 
+    /* Handle all open modes */
     if (dwOpenMode & PIPE_ACCESS_OUTBOUND)
     {
         ShareAccess |= FILE_SHARE_READ;
@@ -228,7 +229,7 @@ CreateNamedPipeW(LPCWSTR lpName,
     if (!NT_SUCCESS(Status))
     {
         /* Failed to create it */
-        DPRINT1("NtCreateNamedPipe failed (Status %x)!\n", Status);
+        WARN("NtCreateNamedPipe failed (Status %x)!\n", Status);
         SetLastErrorByStatus (Status);
         return INVALID_HANDLE_VALUE;
     }
@@ -250,7 +251,7 @@ WaitNamedPipeA(LPCSTR lpNamedPipeName,
     UNICODE_STRING NameU;
 
     /* Convert the name to Unicode */
-    Basep8BitStringToLiveUnicodeString(&NameU, lpNamedPipeName);
+    Basep8BitStringToHeapUnicodeString(&NameU, lpNamedPipeName);
 
     /* Call the Unicode API */
     r = WaitNamedPipeW(NameU.Buffer, nTimeOut);
@@ -268,8 +269,8 @@ WaitNamedPipeA(LPCSTR lpNamedPipeName,
  * Microsoft's NPFS.SYS. The main difference is that:
  *      - This code actually respects the timeout instead of ignoring it!
  *      - This code validates and creates the proper names for both UNC and local pipes
- *      - On NT, you open the *root* pipe directory (either \DosDevices\Pipe or 
- *        \DosDevices\Unc\Server\Pipe) and then send the pipe to wait on in the 
+ *      - On NT, you open the *root* pipe directory (either \DosDevices\Pipe or
+ *        \DosDevices\Unc\Server\Pipe) and then send the pipe to wait on in the
  *        FILE_PIPE_WAIT_FOR_BUFFER structure.
  */
 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
@@ -294,7 +295,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
     PFILE_PIPE_WAIT_FOR_BUFFER WaitPipeInfo;
 
     /* Start by making a unicode string of the name */
-    DPRINT("Sent path: %S\n", lpNamedPipeName);
+    TRACE("Sent path: %S\n", lpNamedPipeName);
     RtlCreateUnicodeString(&NamedPipeName, lpNamedPipeName);
     NameLength = NamedPipeName.Length / sizeof(WCHAR);
 
@@ -308,7 +309,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
     /* Find the path type of the name we were given */
     NewName = NamedPipeName;
     Type = RtlDetermineDosPathNameType_U(lpNamedPipeName);
+
     /* Check if this was a device path, ie : "\\.\pipe\name" */
     if (Type == RtlPathTypeLocalDevice)
     {
@@ -321,7 +322,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
         NewName.Length -= 9 * sizeof(WCHAR);
 
         /* Initialize the Dos Devices name */
-        DPRINT("NewName: %wZ\n", &NewName);
+        TRACE("NewName: %wZ\n", &NewName);
         RtlInitUnicodeString(&DevicePath, L"\\DosDevices\\pipe\\");
     }
     else if (Type == RtlPathTypeRootLocalDevice)
@@ -348,7 +349,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
         else
         {
             /* The name is invalid */
-            DPRINT1("Invalid name!\n");
+            WARN("Invalid name!\n");
             SetLastErrorByStatus(STATUS_OBJECT_PATH_SYNTAX_BAD);
             return FALSE;
         }
@@ -357,7 +358,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
     }
     else
     {
-        DPRINT1("Invalid path type\n");
+        WARN("Invalid path type\n");
         SetLastErrorByStatus(STATUS_OBJECT_PATH_SYNTAX_BAD);
         return FALSE;
     }
@@ -373,7 +374,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
     }
 
     /* Initialize the object attributes */
-    DPRINT("Opening: %wZ\n", &DevicePath);
+    TRACE("Opening: %wZ\n", &DevicePath);
     InitializeObjectAttributes(&ObjectAttributes,
                                &DevicePath,
                                OBJ_CASE_INSENSITIVE,
@@ -390,7 +391,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
     if (!NT_SUCCESS(Status))
     {
         /* Fail; couldn't open */
-        DPRINT1("Status: %lx\n", Status);
+        WARN("Status: %lx\n", Status);
         SetLastErrorByStatus(Status);
         RtlFreeUnicodeString(&NamedPipeName);
         RtlFreeHeap(RtlGetProcessHeap(), 0, WaitPipeInfo);
@@ -419,7 +420,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
         }
 
         /* In both cases, we do have a timeout */
-        WaitPipeInfo->TimeoutSpecified = FALSE;
+        WaitPipeInfo->TimeoutSpecified = TRUE;
     }
 
     /* Set the length and copy the name */
@@ -449,7 +450,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
     if (!NT_SUCCESS(Status))
     {
         /* Failure to wait on the pipe */
-        DPRINT1("Status: %lx\n", Status);
+        WARN("Status: %lx\n", Status);
         SetLastErrorByStatus (Status);
         return FALSE;
      }
@@ -495,10 +496,34 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
     if (!NT_SUCCESS(Status))
     {
         SetLastErrorByStatus(Status);
+        RtlFreeUnicodeString(&NamedPipeName);
         return FALSE;
     }
 
-    WaitPipe.Timeout.QuadPart = nTimeOut * -10000LL;
+    /* Check what timeout we got */
+    if (nTimeOut == NMPWAIT_USE_DEFAULT_WAIT)
+    {
+        /* Don't use a timeout */
+        WaitPipe.TimeoutSpecified = FALSE;
+    }
+    else
+    {
+        /* Check if we should wait forever */
+        if (nTimeOut == NMPWAIT_WAIT_FOREVER)
+        {
+            /* Set the max */
+            WaitPipe.Timeout.LowPart = 0;
+            WaitPipe.Timeout.HighPart = 0x80000000;
+        }
+        else
+        {
+            /* Convert to NT format */
+            WaitPipe.Timeout.QuadPart = UInt32x32To64(-10000, nTimeOut);
+        }
+
+        /* In both cases, we do have a timeout */
+        WaitPipe.TimeoutSpecified = TRUE;
+    }
 
     Status = NtFsControlFile(FileHandle,
                              NULL,
@@ -514,9 +539,11 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
     if (!NT_SUCCESS(Status))
     {
         SetLastErrorByStatus(Status);
+        RtlFreeUnicodeString(&NamedPipeName);
         return FALSE;
     }
 
+    RtlFreeUnicodeString(&NamedPipeName);
     return TRUE;
 }
 #endif
@@ -928,7 +955,7 @@ GetNamedPipeHandleStateA(HANDLE hNamedPipe,
                          LPSTR lpUserName,
                          DWORD nMaxUserNameSize)
 {
-    UNICODE_STRING UserNameW = {0};
+    UNICODE_STRING UserNameW = { 0, 0, NULL };
     ANSI_STRING UserNameA;
     BOOL Ret;
 
@@ -1045,7 +1072,7 @@ PeekNamedPipe(HANDLE hNamedPipe,
     NTSTATUS Status;
 
     /* Calculate the buffer space that we'll need and allocate it */
-    BufferSize = nBufferSize + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]);
+    BufferSize = nBufferSize + sizeof(FILE_PIPE_PEEK_BUFFER);
     Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
     if (Buffer == NULL)
     {
@@ -1091,7 +1118,7 @@ PeekNamedPipe(HANDLE hNamedPipe,
 
     /* Calculate the bytes returned, minus our structure overhead */
     BytesRead = (ULONG)(Iosb.Information -
-                        FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))
+                        FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]));
 
     /* Check if caller requested bytes read */
     if (lpBytesRead)