Juan Lang : userenv: Implement GetProfilesDirectory.
Alexandre Julliard
julliard at winehq.org
Fri Aug 27 11:11:20 CDT 2010
Module: wine
Branch: master
Commit: e5394c6ce562104a5fc5a34c787396363b61a281
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e5394c6ce562104a5fc5a34c787396363b61a281
Author: Juan Lang <juan.lang at gmail.com>
Date: Thu Aug 26 17:17:44 2010 -0700
userenv: Implement GetProfilesDirectory.
---
dlls/userenv/Makefile.in | 1 +
dlls/userenv/tests/userenv.c | 11 ++---
dlls/userenv/userenv_main.c | 120 ++++++++++++++++++++++++++++++++++++++++--
3 files changed, 121 insertions(+), 11 deletions(-)
diff --git a/dlls/userenv/Makefile.in b/dlls/userenv/Makefile.in
index f3a4149..aaf0de1 100644
--- a/dlls/userenv/Makefile.in
+++ b/dlls/userenv/Makefile.in
@@ -3,6 +3,7 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = userenv.dll
+IMPORTS = advapi32
IMPORTLIB = userenv
C_SRCS = \
diff --git a/dlls/userenv/tests/userenv.c b/dlls/userenv/tests/userenv.c
index 790cc80..4fa257b 100644
--- a/dlls/userenv/tests/userenv.c
+++ b/dlls/userenv/tests/userenv.c
@@ -240,32 +240,29 @@ static void test_get_profiles_dir(void)
SetLastError(0xdeadbeef);
r = GetProfilesDirectoryA(NULL, NULL);
expect(FALSE, r);
- todo_wine
expect_gle(ERROR_INVALID_PARAMETER);
SetLastError(0xdeadbeef);
r = GetProfilesDirectoryA(NULL, &cch);
expect(FALSE, r);
- todo_wine
expect_gle(ERROR_INVALID_PARAMETER);
SetLastError(0xdeadbeef);
cch = 1;
r = GetProfilesDirectoryA(small_buf, &cch);
expect(FALSE, r);
- todo_wine
expect_gle(ERROR_INSUFFICIENT_BUFFER);
/* MSDN claims the returned character count includes the NULL terminator
* when the buffer is too small, but that's not in fact what gets returned.
*/
- todo_wine
ok(cch == profiles_len - 1, "expected %d, got %d\n", profiles_len - 1, cch);
- buf = HeapAlloc(GetProcessHeap(), 0, cch);
+ /* Allocate one more character than the return value to prevent a buffer
+ * overrun.
+ */
+ buf = HeapAlloc(GetProcessHeap(), 0, cch + 1);
r = GetProfilesDirectoryA(buf, &cch);
/* Rather than a BOOL, the return value is also the number of characters
* stored in the buffer.
*/
- todo_wine
expect(profiles_len - 1, r);
- todo_wine
ok(!strcmp(buf, profiles_dir), "expected %s, got %s\n", profiles_dir, buf);
HeapFree(GetProcessHeap(), 0, buf);
diff --git a/dlls/userenv/userenv_main.c b/dlls/userenv/userenv_main.c
index ddf0e21..9247f44 100644
--- a/dlls/userenv/userenv_main.c
+++ b/dlls/userenv/userenv_main.c
@@ -114,16 +114,128 @@ BOOL WINAPI GetUserProfileDirectoryW( HANDLE hToken, LPWSTR lpProfileDir,
return FALSE;
}
+static const char ProfileListA[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList";
+
BOOL WINAPI GetProfilesDirectoryA( LPSTR lpProfilesDir, LPDWORD lpcchSize )
{
- FIXME("%p %p\n", lpProfilesDir, lpcchSize );
- return FALSE;
+ static const char ProfilesDirectory[] = "ProfilesDirectory";
+ LONG l;
+ HKEY key;
+ BOOL ret = FALSE;
+ DWORD len = 0, expanded_len;
+ LPSTR unexpanded_profiles_dir = NULL;
+
+ TRACE("%p %p\n", lpProfilesDir, lpcchSize );
+
+ if (!lpProfilesDir || !lpcchSize)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ l = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ProfileListA, 0, KEY_READ, &key);
+ if (l)
+ {
+ SetLastError(l);
+ return FALSE;
+ }
+ l = RegQueryValueExA(key, ProfilesDirectory, NULL, NULL, NULL, &len);
+ if (l)
+ {
+ SetLastError(l);
+ goto end;
+ }
+ unexpanded_profiles_dir = HeapAlloc(GetProcessHeap(), 0, len);
+ if (!unexpanded_profiles_dir)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ goto end;
+ }
+ l = RegQueryValueExA(key, ProfilesDirectory, NULL, NULL,
+ (BYTE *)unexpanded_profiles_dir, &len);
+ if (l)
+ {
+ SetLastError(l);
+ goto end;
+ }
+ expanded_len = ExpandEnvironmentStringsA(unexpanded_profiles_dir, NULL, 0);
+ /* The returned length doesn't include the NULL terminator. */
+ if (*lpcchSize < expanded_len - 1)
+ {
+ *lpcchSize = expanded_len - 1;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ goto end;
+ }
+ *lpcchSize = expanded_len - 1;
+ /* The return value is also the expected length. */
+ ret = ExpandEnvironmentStringsA(unexpanded_profiles_dir, lpProfilesDir,
+ expanded_len) - 1;
+end:
+ HeapFree(GetProcessHeap(), 0, unexpanded_profiles_dir);
+ RegCloseKey(key);
+ return ret;
}
+static const WCHAR ProfileListW[] = {'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','\\','P','r','o','f','i','l','e','L','i','s','t',0};
+
BOOL WINAPI GetProfilesDirectoryW( LPWSTR lpProfilesDir, LPDWORD lpcchSize )
{
- FIXME("%p %p\n", lpProfilesDir, lpcchSize );
- return FALSE;
+ static const WCHAR ProfilesDirectory[] = {'P','r','o','f','i','l','e','s','D','i','r','e','c','t','o','r','y',0};
+ LONG l;
+ HKEY key;
+ BOOL ret = FALSE;
+ DWORD len = 0, expanded_len;
+ LPWSTR unexpanded_profiles_dir = NULL;
+
+ TRACE("%p %p\n", lpProfilesDir, lpcchSize );
+
+ if (!lpProfilesDir || !lpcchSize)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ l = RegOpenKeyExW(HKEY_LOCAL_MACHINE, ProfileListW, 0, KEY_READ, &key);
+ if (l)
+ {
+ SetLastError(l);
+ return FALSE;
+ }
+ l = RegQueryValueExW(key, ProfilesDirectory, NULL, NULL, NULL, &len);
+ if (l)
+ {
+ SetLastError(l);
+ goto end;
+ }
+ unexpanded_profiles_dir = HeapAlloc(GetProcessHeap(), 0, len);
+ if (!unexpanded_profiles_dir)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ goto end;
+ }
+ l = RegQueryValueExW(key, ProfilesDirectory, NULL, NULL,
+ (BYTE *)unexpanded_profiles_dir, &len);
+ if (l)
+ {
+ SetLastError(l);
+ goto end;
+ }
+ expanded_len = ExpandEnvironmentStringsW(unexpanded_profiles_dir, NULL, 0);
+ /* The returned length doesn't include the NULL terminator. */
+ if (*lpcchSize < expanded_len - 1)
+ {
+ *lpcchSize = expanded_len - 1;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ goto end;
+ }
+ *lpcchSize = expanded_len - 1;
+ /* The return value is also the expected length. */
+ ret = ExpandEnvironmentStringsW(unexpanded_profiles_dir, lpProfilesDir,
+ expanded_len) - 1;
+end:
+ HeapFree(GetProcessHeap(), 0, unexpanded_profiles_dir);
+ RegCloseKey(key);
+ return ret;
}
BOOL WINAPI GetAllUsersProfileDirectoryA( LPSTR lpProfileDir, LPDWORD lpcchSize )
More information about the wine-cvs
mailing list