[KERNEL32] Fix MSVC build
[reactos.git] / dll / win32 / kernel32 / client / file / npipe.c
index 82ac4b5..a142cf4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Win32 Kernel Library
- * FILE:            lib/kernel32/file/npipe.c
+ * FILE:            dll/win32/kernel32/client/file/npipe.c
  * PURPOSE:         Named Pipe Functions
  * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)
  *                  Ariadne ( ariadne@xs4all.nl)
@@ -20,6 +20,95 @@ LONG ProcessPipeId;
 
 /* FUNCTIONS ******************************************************************/
 
+/*
+ * @implemented
+ */
+static
+BOOL
+NpGetUserNamep(HANDLE hNamedPipe,
+               LPWSTR lpUserName,
+               DWORD nMaxUserNameSize)
+{
+    BOOL Ret;
+    HANDLE hToken;
+    HMODULE hAdvapi;
+    NTSTATUS Status;
+    BOOL (WINAPI *pRevertToSelf)(void);
+    BOOL (WINAPI *pGetUserNameW)(LPWSTR lpBuffer, LPDWORD lpnSize);
+    BOOL (WINAPI *pImpersonateNamedPipeClient)(HANDLE hNamedPipe);
+
+    /* Open advapi, we'll funcs from it */
+    hAdvapi = LoadLibraryW(L"advapi32.dll");
+    if (hAdvapi == NULL)
+    {
+        return FALSE;
+    }
+
+    /* Import the three required functions */
+    pRevertToSelf = (BOOL (WINAPI *)(void))GetProcAddress(hAdvapi, "RevertToSelf");
+    pGetUserNameW = (BOOL (WINAPI *)(LPWSTR, LPDWORD))GetProcAddress(hAdvapi, "GetUserNameW");
+    pImpersonateNamedPipeClient = (BOOL (WINAPI *)(HANDLE))GetProcAddress(hAdvapi, "ImpersonateNamedPipeClient");
+    /* If any couldn't be found, fail */
+    if (pRevertToSelf == NULL || pGetUserNameW == NULL || pImpersonateNamedPipeClient == NULL)
+    {
+        FreeLibrary(hAdvapi);
+        return FALSE;
+    }
+
+    /* Now, open the thread token for impersonation */
+    Status = NtOpenThreadToken(NtCurrentThread(), TOKEN_IMPERSONATE, TRUE, &hToken);
+    /* Try to impersonate the pipe client */
+    if (pImpersonateNamedPipeClient(hNamedPipe))
+    {
+        DWORD lpnSize;
+
+        /* It worked, get the user name */
+        lpnSize = nMaxUserNameSize;
+        Ret = pGetUserNameW(lpUserName, &lpnSize);
+        /* Failed to get the thread token? Revert to self */
+        if (!NT_SUCCESS(Status))
+        {
+            pRevertToSelf();
+
+            FreeLibrary(hAdvapi);
+            return Ret;
+        }
+
+        /* Restore the thread token */
+        Status = NtSetInformationThread(NtCurrentThread(), ThreadImpersonationToken,
+                                        &hToken, sizeof(HANDLE));
+        /* We cannot fail closing the thread token! */
+        if (!CloseHandle(hToken))
+        {
+            ASSERT(FALSE);
+        }
+
+        /* Set last error if it failed */
+        if (!NT_SUCCESS(Status))
+        {
+            BaseSetLastNTError(Status);
+        }
+    }
+    else
+    {
+        /* If opening the thread token succeed, close it */
+        if (NT_SUCCESS(Status))
+        {
+            /* We cannot fail closing it! */
+            if (!CloseHandle(hToken))
+            {
+                ASSERT(FALSE);
+            }
+        }
+
+        Ret = FALSE;
+    }
+
+    FreeLibrary(hAdvapi);
+    return Ret;
+}
+
+
 /*
  * @implemented
  */
@@ -287,7 +376,7 @@ CreateNamedPipeW(LPCWSTR lpName,
     if (nDefaultTimeOut)
     {
         /* Convert the time to NT format */
-        DefaultTimeOut.QuadPart = UInt32x32To64(nDefaultTimeOut, -10000);
+        DefaultTimeOut.QuadPart = nDefaultTimeOut * -10000LL;
     }
     else
     {
@@ -344,17 +433,18 @@ WINAPI
 WaitNamedPipeA(LPCSTR lpNamedPipeName,
                DWORD nTimeOut)
 {
-    BOOL r;
+    BOOL r = FALSE;
     UNICODE_STRING NameU;
 
     /* Convert the name to Unicode */
-    Basep8BitStringToDynamicUnicodeString(&NameU, lpNamedPipeName);
-
-    /* Call the Unicode API */
-    r = WaitNamedPipeW(NameU.Buffer, nTimeOut);
+    if (Basep8BitStringToDynamicUnicodeString(&NameU, lpNamedPipeName))
+    {
+        /* Call the Unicode API */
+        r = WaitNamedPipeW(NameU.Buffer, nTimeOut);
 
-    /* Free the Unicode string */
-    RtlFreeUnicodeString(&NameU);
+        /* Free the Unicode string */
+        RtlFreeUnicodeString(&NameU);
+    }
 
     /* Return result */
     return r;
@@ -517,7 +607,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
         else
         {
             /* Convert to NT format */
-            WaitPipeInfo->Timeout.QuadPart = UInt32x32To64(-10000, nTimeOut);
+            WaitPipeInfo->Timeout.QuadPart = nTimeOut * -10000LL;
         }
 
         /* In both cases, we do have a timeout */
@@ -699,8 +789,7 @@ SetNamedPipeHandleState(HANDLE hNamedPipe,
         if (lpCollectDataTimeout)
         {
             /* Convert it to Quad */
-            RemoteSettings.CollectDataTime.QuadPart =
-                -(LONGLONG)UInt32x32To64(10000, *lpCollectDataTimeout);
+            RemoteSettings.CollectDataTime.QuadPart = *lpCollectDataTimeout * -10000LL;
         }
 
         /* Tell the driver to change them */
@@ -935,18 +1024,28 @@ GetNamedPipeHandleStateW(HANDLE hNamedPipe,
             *lpMaxCollectionCount = RemoteInfo.MaximumCollectionCount;
         }
 
-        if(lpCollectDataTimeout != NULL)
+        if (lpCollectDataTimeout != NULL)
         {
-            /* FIXME */
-           *lpCollectDataTimeout = 0;
+            LARGE_INTEGER CollectDataTime;
+
+            /* Convert time and return it */
+            RemoteInfo.CollectDataTime.QuadPart *= -1;
+            CollectDataTime = RtlExtendedLargeIntegerDivide(RemoteInfo.CollectDataTime, 10000, NULL);
+            /* In case of overflow, just return MAX - 1 */
+            if (CollectDataTime.HighPart != 0)
+            {
+                *lpCollectDataTimeout = -2;
+            }
+            else
+            {
+                *lpCollectDataTimeout = CollectDataTime.LowPart;
+            }
         }
     }
 
     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 NpGetUserNamep(hNamedPipe, lpUserName, nMaxUserNameSize);
     }
 
     return TRUE;