Hans Leidekker : userenv: Implement and test GetUserProfileDirectory.

Alexandre Julliard julliard at winehq.org
Wed Mar 2 12:23:49 CST 2011


Module: wine
Branch: master
Commit: c4d8f7400b51ca3a196e9a9d9bea7254a2b716cc
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c4d8f7400b51ca3a196e9a9d9bea7254a2b716cc

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Wed Mar  2 10:46:56 2011 +0100

userenv: Implement and test GetUserProfileDirectory.

---

 dlls/userenv/tests/userenv.c |  104 ++++++++++++++++++++++++++++++++++++++++++
 dlls/userenv/userenv_main.c  |   74 ++++++++++++++++++++++++++++--
 2 files changed, 174 insertions(+), 4 deletions(-)

diff --git a/dlls/userenv/tests/userenv.c b/dlls/userenv/tests/userenv.c
index c96b710..cd81232 100644
--- a/dlls/userenv/tests/userenv.c
+++ b/dlls/userenv/tests/userenv.c
@@ -283,8 +283,112 @@ static void test_get_profiles_dir(void)
     expect_gle(ERROR_INSUFFICIENT_BUFFER);
 }
 
+static void test_get_user_profile_dir(void)
+{
+    BOOL ret;
+    DWORD error, len;
+    HANDLE token;
+    char *dirA;
+    WCHAR *dirW;
+
+    if (!GetEnvironmentVariableA( "ALLUSERSPROFILE", NULL, 0 ))
+    {
+        win_skip("Skipping tests on NT4\n");
+        return;
+    }
+
+    ret = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token );
+    ok(ret, "expected success %u\n", GetLastError());
+
+    SetLastError( 0xdeadbeef );
+    ret = GetUserProfileDirectoryA( NULL, NULL, NULL );
+    error = GetLastError();
+    ok(!ret, "expected failure\n");
+    ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
+
+    SetLastError( 0xdeadbeef );
+    ret = GetUserProfileDirectoryA( token, NULL, NULL );
+    error = GetLastError();
+    ok(!ret, "expected failure\n");
+    ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
+
+    dirA = HeapAlloc( GetProcessHeap(), 0, 32 );
+    SetLastError( 0xdeadbeef );
+    ret = GetUserProfileDirectoryA( token, dirA, NULL );
+    error = GetLastError();
+    ok(!ret, "expected failure\n");
+    ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
+    HeapFree( GetProcessHeap(), 0, dirA );
+
+    len = 0;
+    SetLastError( 0xdeadbeef );
+    ret = GetUserProfileDirectoryA( token, NULL, &len );
+    error = GetLastError();
+    ok(!ret, "expected failure\n");
+    ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
+    ok(!len, "expected 0, got %u\n", len);
+
+    len = 0;
+    dirA = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 32 );
+    SetLastError( 0xdeadbeef );
+    ret = GetUserProfileDirectoryA( token, dirA, &len );
+    error = GetLastError();
+    ok(!ret, "expected failure\n");
+    ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
+    ok(len, "expected len > 0\n");
+    HeapFree( GetProcessHeap(), 0, dirA );
+
+    dirA = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
+    SetLastError( 0xdeadbeef );
+    ret = GetUserProfileDirectoryA( token, dirA, &len );
+    ok(ret, "expected success %u\n", GetLastError());
+    ok(len, "expected len > 0\n");
+    ok(lstrlenA( dirA ) == len - 1, "length mismatch %d != %d - 1\n", lstrlenA( dirA ), len );
+    trace("%s\n", dirA);
+    HeapFree( GetProcessHeap(), 0, dirA );
+
+    SetLastError( 0xdeadbeef );
+    ret = GetUserProfileDirectoryW( NULL, NULL, NULL );
+    error = GetLastError();
+    ok(!ret, "expected failure\n");
+    todo_wine ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
+
+    SetLastError( 0xdeadbeef );
+    ret = GetUserProfileDirectoryW( token, NULL, NULL );
+    error = GetLastError();
+    ok(!ret, "expected failure\n");
+    ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
+
+    dirW = HeapAlloc( GetProcessHeap(), 0, 32 );
+    SetLastError( 0xdeadbeef );
+    ret = GetUserProfileDirectoryW( token, dirW, NULL );
+    error = GetLastError();
+    ok(!ret, "expected failure\n");
+    ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
+    HeapFree( GetProcessHeap(), 0, dirW );
+
+    len = 0;
+    SetLastError( 0xdeadbeef );
+    ret = GetUserProfileDirectoryW( token, NULL, &len );
+    error = GetLastError();
+    ok(!ret, "expected failure\n");
+    ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
+    ok(len, "expected len > 0\n");
+
+    dirW = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR) );
+    SetLastError( 0xdeadbeef );
+    ret = GetUserProfileDirectoryW( token, dirW, &len );
+    ok(ret, "expected success %u\n", GetLastError());
+    ok(len, "expected len > 0\n");
+    ok(lstrlenW( dirW ) == len - 1, "length mismatch %d != %d - 1\n", lstrlenW( dirW ), len );
+    HeapFree( GetProcessHeap(), 0, dirW );
+
+    CloseHandle( token );
+}
+
 START_TEST(userenv)
 {
     test_create_env();
     test_get_profiles_dir();
+    test_get_user_profile_dir();
 }
diff --git a/dlls/userenv/userenv_main.c b/dlls/userenv/userenv_main.c
index 4204472..6a2a953 100644
--- a/dlls/userenv/userenv_main.c
+++ b/dlls/userenv/userenv_main.c
@@ -26,9 +26,11 @@
 #include "winbase.h"
 #include "winreg.h"
 #include "winternl.h"
+#include "winnls.h"
 #include "userenv.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL( userenv );
 
@@ -115,15 +117,79 @@ BOOL WINAPI GetDefaultUserProfileDirectoryW( LPWSTR lpProfileDir, LPDWORD lpcchS
 BOOL WINAPI GetUserProfileDirectoryA( HANDLE hToken, LPSTR lpProfileDir,
                      LPDWORD lpcchSize )
 {
-    FIXME("%p %p %p\n", hToken, lpProfileDir, lpcchSize );
-    return FALSE;
+    BOOL ret;
+    WCHAR *dirW = NULL;
+
+    TRACE( "%p %p %p\n", hToken, lpProfileDir, lpcchSize );
+
+    if (!lpProfileDir || !lpcchSize)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+    if (!(dirW = HeapAlloc( GetProcessHeap(), 0, *lpcchSize * sizeof(WCHAR) )))
+        return FALSE;
+
+    if ((ret = GetUserProfileDirectoryW( hToken, dirW, lpcchSize )))
+        WideCharToMultiByte( CP_ACP, 0, dirW, *lpcchSize, lpProfileDir, *lpcchSize, NULL, NULL );
+
+    HeapFree( GetProcessHeap(), 0, dirW );
+    return ret;
 }
 
 BOOL WINAPI GetUserProfileDirectoryW( HANDLE hToken, LPWSTR lpProfileDir,
                      LPDWORD lpcchSize )
 {
-    FIXME("%p %p %p\n", hToken, lpProfileDir, lpcchSize );
-    return FALSE;
+    static const WCHAR slashW[] = {'\\',0};
+    TOKEN_USER *t;
+    WCHAR *userW = NULL, *dirW = NULL;
+    DWORD len, dir_len, domain_len;
+    SID_NAME_USE use;
+    BOOL ret = FALSE;
+
+    TRACE( "%p %p %p\n", hToken, lpProfileDir, lpcchSize );
+
+    if (!lpcchSize)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+
+    len = 0;
+    GetTokenInformation( hToken, TokenUser, NULL, 0, &len );
+    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE;
+    if (!(t = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
+    if (!GetTokenInformation( hToken, TokenUser, t, len, &len )) goto done;
+
+    len = 0;
+    LookupAccountSidW( NULL, t->User.Sid, NULL, &len, NULL, &domain_len, NULL );
+    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done;
+    if (!(userW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) goto done;
+    if (!LookupAccountSidW( NULL, t->User.Sid, userW, &len, NULL, &domain_len, &use )) goto done;
+
+    dir_len = 0;
+    GetProfilesDirectoryW( NULL, &dir_len );
+    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done;
+    if (!(dirW = HeapAlloc( GetProcessHeap(), 0, (dir_len + 1) * sizeof(WCHAR) ))) goto done;
+    if (!GetProfilesDirectoryW( dirW, &dir_len )) goto done;
+
+    len += dir_len + 2;
+    if (*lpcchSize < len)
+    {
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );
+        *lpcchSize = len;
+        goto done;
+    }
+    strcpyW( lpProfileDir, dirW );
+    strcatW( lpProfileDir, slashW );
+    strcatW( lpProfileDir, userW );
+    *lpcchSize = len;
+    ret = TRUE;
+
+done:
+    HeapFree( GetProcessHeap(), 0, userW );
+    HeapFree( GetProcessHeap(), 0, dirW );
+    return ret;
 }
 
 static const char ProfileListA[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList";




More information about the wine-cvs mailing list