From d59c1fe3e26e0cb41a3affe4034abc6dc9bd0556 Mon Sep 17 00:00:00 2001 From: Andreas.Rosenberg 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