userenv: Implement and test GetUserProfileDirectory.
This commit is contained in:
parent
1c6ea02ffa
commit
c4d8f7400b
|
@ -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 @@
|
||||||
#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
|
||||||
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;
|
||||||
|
WCHAR *dirW = NULL;
|
||||||
|
|
||||||
|
TRACE( "%p %p %p\n", hToken, lpProfileDir, lpcchSize );
|
||||||
|
|
||||||
|
if (!lpProfileDir || !lpcchSize)
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
return FALSE;
|
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};
|
||||||
|
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;
|
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";
|
||||||
|
|
Loading…
Reference in New Issue