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