https://git.reactos.org/?p=reactos.git;a=commitdiff;h=34c39a1336e1cf000b0159bd47f59ee1b1e9def4

commit 34c39a1336e1cf000b0159bd47f59ee1b1e9def4
Author: Pierre Schweitzer <[email protected]>
AuthorDate: Mon Oct 23 17:08:50 2017 +0200

    [KERNEL32] Implement NpGetUserNamep()
---
 dll/win32/kernel32/client/file/npipe.c | 85 ++++++++++++++++++++++++++++++++--
 1 file changed, 80 insertions(+), 5 deletions(-)

diff --git a/dll/win32/kernel32/client/file/npipe.c 
b/dll/win32/kernel32/client/file/npipe.c
index 3ed0c555e3..b39982e205 100644
--- a/dll/win32/kernel32/client/file/npipe.c
+++ b/dll/win32/kernel32/client/file/npipe.c
@@ -20,17 +20,92 @@ LONG ProcessPipeId;
 
 /* FUNCTIONS 
******************************************************************/
 
+/*
+ * @implemented
+ */
 static
 BOOL
 NpGetUserNamep(HANDLE hNamedPipe,
                LPWSTR lpUserName,
                DWORD nMaxUserNameSize)
 {
-    /* FIXME - open the thread token, call ImpersonateNamedPipeClient() and
-               retrieve the user name with GetUserName(), revert the 
impersonation
-               and finally restore the thread token */
-    UNIMPLEMENTED;
-    return TRUE;
+    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 = GetProcAddress(hAdvapi, "RevertToSelf");
+    pGetUserNameW = GetProcAddress(hAdvapi, "GetUserNameW");
+    pImpersonateNamedPipeClient = 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;
 }
 
 

Reply via email to