Commit c4d8f740 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

userenv: Implement and test GetUserProfileDirectory.

parent 1c6ea02f
...@@ -283,8 +283,112 @@ static void test_get_profiles_dir(void) ...@@ -283,8 +283,112 @@ static void test_get_profiles_dir(void)
expect_gle(ERROR_INSUFFICIENT_BUFFER); 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) START_TEST(userenv)
{ {
test_create_env(); test_create_env();
test_get_profiles_dir(); test_get_profiles_dir();
test_get_user_profile_dir();
} }
...@@ -26,9 +26,11 @@ ...@@ -26,9 +26,11 @@
#include "winbase.h" #include "winbase.h"
#include "winreg.h" #include "winreg.h"
#include "winternl.h" #include "winternl.h"
#include "winnls.h"
#include "userenv.h" #include "userenv.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL( userenv ); WINE_DEFAULT_DEBUG_CHANNEL( userenv );
...@@ -115,15 +117,79 @@ BOOL WINAPI GetDefaultUserProfileDirectoryW( LPWSTR lpProfileDir, LPDWORD lpcchS ...@@ -115,15 +117,79 @@ BOOL WINAPI GetDefaultUserProfileDirectoryW( LPWSTR lpProfileDir, LPDWORD lpcchS
BOOL WINAPI GetUserProfileDirectoryA( HANDLE hToken, LPSTR lpProfileDir, BOOL WINAPI GetUserProfileDirectoryA( HANDLE hToken, LPSTR lpProfileDir,
LPDWORD lpcchSize ) LPDWORD lpcchSize )
{ {
FIXME("%p %p %p\n", hToken, lpProfileDir, lpcchSize ); BOOL ret;
return FALSE; 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, BOOL WINAPI GetUserProfileDirectoryW( HANDLE hToken, LPWSTR lpProfileDir,
LPDWORD lpcchSize ) LPDWORD lpcchSize )
{ {
FIXME("%p %p %p\n", hToken, lpProfileDir, lpcchSize ); static const WCHAR slashW[] = {'\\',0};
return FALSE; 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"; static const char ProfileListA[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment