dlls/userenv: fixed stubs GetUserProfileDirectoryW/A (3rd try)
Andreas Rosenberg
andreas.rosenberg at apis.de
Thu Mar 5 06:39:24 CST 2009
-------------- next part --------------
From 0fdd0f59e3d08e81fcd1d1e30cdad4f3b3c4c365 Mon Sep 17 00:00:00 2001
From: Andreas.Rosenberg <andreas.rosenberg at apis.de>
Date: Thu, 5 Mar 2009 13:25:56 +0100
Subject: dlls/userenv: fixed stubs for GetUserProfileDirectoryA/W
---
dlls/userenv/Makefile.in | 2 +-
dlls/userenv/tests/userenv.c | 35 +++++++++++++++++
dlls/userenv/userenv_main.c | 88 ++++++++++++++++++++++++++++++++++++++++-
3 files changed, 121 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..ff529e4 100644
--- a/dlls/userenv/tests/userenv.c
+++ b/dlls/userenv/tests/userenv.c
@@ -272,9 +272,44 @@ 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()
+{
+ DWORD lastError,sizePath,sizeExpected,r;
+ HANDLE htoken;
+ WCHAR buffer[MAX_PATH];
+
+ r = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &htoken);
+ expect(TRUE, r);
+
+ r = GetUserProfileDirectoryW(htoken , NULL, NULL );
+ lastError = GetLastError();
+ expect(FALSE, r);
+ expect(lastError, ERROR_INVALID_PARAMETER);
+
+ sizePath = 0;
+ 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); /* upon sucess an int > 0 is returned - which may not be == TRUE */
+ expect(sizeExpected,lstrlenW(buffer)+1);
+ expect(r,lstrlenW(buffer));
+ 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..fec7900 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 *lpcchSize - 1; /* Win returns the number of chars in the result string */
+ }
+ }
+ }
+ }
return FALSE;
}
--
1.5.2.4
More information about the wine-patches
mailing list