dlls/userenv: fixed stubs GetUserProfileDirectoryW/A (5)

Andreas Rosenberg andreas.rosenberg at apis.de
Thu Mar 5 11:43:30 CST 2009


-------------- next part --------------
From d59c1fe3e26e0cb41a3affe4034abc6dc9bd0556 Mon Sep 17 00:00:00 2001
From: Andreas.Rosenberg <andreas.rosenberg at apis.de>
Date: Thu, 5 Mar 2009 18:41:37 +0100
Subject: dlls/userenv: fixed stubs GetUserProfileDirectoryW/A

---
 dlls/userenv/Makefile.in     |    2 +-
 dlls/userenv/tests/userenv.c |   37 +++++++++++++++++
 dlls/userenv/userenv_main.c  |   88 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 123 insertions(+), 4 deletions(-)

diff --git a/dlls/userenv/Makefile.in b/dlls/userenv/Makefile.in
index 07bba8f..4e2f6fd 100644
--- a/dlls/userenv/Makefile.in
+++ b/dlls/userenv/Makefile.in
@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = userenv.dll
-IMPORTS   = kernel32 ntdll
+IMPORTS   = kernel32 ntdll advapi32
 IMPORTLIB = userenv
 
 C_SRCS = \
diff --git a/dlls/userenv/tests/userenv.c b/dlls/userenv/tests/userenv.c
index d782d2f..b5310fc 100644
--- a/dlls/userenv/tests/userenv.c
+++ b/dlls/userenv/tests/userenv.c
@@ -272,9 +272,46 @@ static void test_create_env(void)
     expect(TRUE, r);
     r = get_env(env[3], "WINE_XYZZY", &st);
     expect(TRUE, r);
+    CloseHandle(htok);
+}
+
+void test_profile_dir()
+{
+    BOOL r;
+    DWORD lastError,sizePath,sizeExpected;
+    HANDLE htoken;
+    WCHAR buffer[MAX_PATH];
+
+    r = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &htoken);
+    expect(TRUE, r);
+
+    SetLastError(0xDEADAFFE);
+    r = GetUserProfileDirectoryW(htoken , NULL, NULL );
+    lastError = GetLastError();
+    expect(FALSE, r);
+    expect(lastError, ERROR_INVALID_PARAMETER);
+
+    sizePath = 0;
+    SetLastError(0xDEADAFFE);
+    r = GetUserProfileDirectoryW(htoken , buffer, &sizePath );
+    lastError = GetLastError();
+    expect(FALSE,r);
+    expect(lastError, ERROR_INSUFFICIENT_BUFFER);
+    ok(sizePath > 0, "Expected (sizePath>0), got %d\n",sizePath );
+
+    sizeExpected = sizePath;
+    sizePath = sizeof(buffer);
+    SetLastError(0xDEADAFFE);
+    r = GetUserProfileDirectoryW(htoken , buffer, &sizePath );
+    lastError = GetLastError();
+    expect(TRUE,r);
+    expect(sizeExpected,lstrlenW(buffer)+1);
+    expect(lastError,0xDEADAFFE);
+    CloseHandle(htoken);
 }
 
 START_TEST(userenv)
 {
     test_create_env();
+    test_profile_dir();
 }
diff --git a/dlls/userenv/userenv_main.c b/dlls/userenv/userenv_main.c
index 1eaaa71..37b2167 100644
--- a/dlls/userenv/userenv_main.c
+++ b/dlls/userenv/userenv_main.c
@@ -27,9 +27,28 @@
 #include "winreg.h"
 #include "winternl.h"
 #include "userenv.h"
+#include "lmcons.h"
+#include "winreg.h"
+#include "winnls.h"
 
 #include "wine/debug.h"
 
+static WCHAR const profile_pathname[49] = {
+    'S', 'o', 'f', 't', 'w', 'a', 'r', 'e', '\\',
+    'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', '\\',
+    'W', 'i', 'n', 'd', 'o', 'w', 's', ' ', 'N', 'T', '\\', 
+    'C', 'u', 'r', 'r', 'e', 'n', 't', 'V', 'e', 'r', 's', 'i', 'o', 'n', '\\',
+    0 };
+
+    static WCHAR const profile_subkey[12] = {
+        'P', 'r', 'o', 'f', 'i', 'l', 'e', 'L', 'i', 's', 't',
+    0 };
+
+static WCHAR const profile_keyname[18] = {
+        'P', 'r', 'o', 'f', 'i', 'l', 'e', 's', 'D', 'i', 'r','e', 'c', 't', 'o', 'r', 'y',
+    0 };
+
+
 WINE_DEFAULT_DEBUG_CHANNEL( userenv );
 
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
@@ -92,14 +111,77 @@ BOOL WINAPI ExpandEnvironmentStringsForUserW( HANDLE hToken, LPCWSTR lpSrc,
 BOOL WINAPI GetUserProfileDirectoryA( HANDLE hToken, LPSTR lpProfileDir,
                      LPDWORD lpcchSize )
 {
-    FIXME("%p %p %p\n", hToken, lpProfileDir, lpcchSize );
-    return FALSE;
+    LPWSTR bufW = NULL;
+    DWORD wBufLen;
+    BOOL res;
+
+    TRACE("%p %s %p\n", hToken, lpProfileDir, lpcchSize );
+    /* profile specific tokens not supported, so hToken ignored  */
+
+    if (lpcchSize && lpProfileDir) {
+        wBufLen = *lpcchSize;
+        bufW = HeapAlloc(GetProcessHeap(),0,wBufLen * sizeof(WCHAR));
+    }
+    else { /* We need this to get the buffer size */
+        wBufLen = 0;
+    }
+    res = GetUserProfileDirectoryW(hToken,bufW,&wBufLen);
+    if (res) {
+        if (lpcchSize && lpcchSize) {
+            WideCharToMultiByte(CP_ACP, 0, bufW, -1, lpProfileDir,
+                                      wBufLen, NULL, NULL);
+            *lpcchSize = wBufLen;
+        }
+        else {/* get the length */
+            if ( lpcchSize )
+                *lpcchSize = wBufLen;
+        }
+    if ( bufW )
+        HeapFree(GetProcessHeap(),0,bufW);
+    }
+    return res;
 }
 
 BOOL WINAPI GetUserProfileDirectoryW( HANDLE hToken, LPWSTR lpProfileDir,
                      LPDWORD lpcchSize )
 {
-    FIXME("%p %p %p\n", hToken, lpProfileDir, lpcchSize );
+    WCHAR buffer[MAX_PATH],userName[UNLEN+1];
+    LONG res;
+    DWORD sizePath,sizeName,error;
+    HKEY keyProfileDir;
+
+    TRACE("%p %s %p\n", hToken,  debugstr_w(lpProfileDir), lpcchSize );
+    /* profile specific tokens not supported, so hToken ignored  */
+
+    if ( !lpcchSize ) {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,profile_pathname,0L,KEY_QUERY_VALUE,&keyProfileDir);
+    if (res == ERROR_SUCCESS ) {
+        sizePath = sizeof(buffer);
+        res = RegGetValueW(keyProfileDir,profile_subkey,profile_keyname,RRF_RT_ANY,
+                           NULL,buffer,&sizePath);  /* RegGetValue expects pcbData in bytes */
+        RegCloseKey(keyProfileDir);
+        if ( res == ERROR_SUCCESS ) {
+            sizeName = sizeof(userName) / sizeof(WCHAR);
+            res = GetUserNameW(&(userName[0]),&sizeName);  /* GetUserName expects lpnSize in chars */
+            if ( res ) {
+                sizePath = sizePath / sizeof(WCHAR);
+                if ( !lpProfileDir  || ( sizeName + sizePath > *lpcchSize ) ) {
+                    *lpcchSize = sizeName + sizePath;
+                    SetLastError(ERROR_INSUFFICIENT_BUFFER);
+                } else {
+                    lstrcpyW(lpProfileDir,&(buffer[0]));
+                    lstrcatW(lpProfileDir,(LPWSTR)&(L"\\"));
+                    lstrcatW(lpProfileDir,&(userName[0]));
+                    *lpcchSize = sizeName + sizePath;
+                    return TRUE;
+                }
+            }
+        }
+    }
     return FALSE;
 }
 
-- 
1.5.2.4



More information about the wine-devel mailing list