Commit e5394c6c authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

userenv: Implement GetProfilesDirectory.

parent 4e19b7ae
...@@ -3,6 +3,7 @@ TOPOBJDIR = ../.. ...@@ -3,6 +3,7 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@ SRCDIR = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
MODULE = userenv.dll MODULE = userenv.dll
IMPORTS = advapi32
IMPORTLIB = userenv IMPORTLIB = userenv
C_SRCS = \ C_SRCS = \
......
...@@ -240,32 +240,29 @@ static void test_get_profiles_dir(void) ...@@ -240,32 +240,29 @@ static void test_get_profiles_dir(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
r = GetProfilesDirectoryA(NULL, NULL); r = GetProfilesDirectoryA(NULL, NULL);
expect(FALSE, r); expect(FALSE, r);
todo_wine
expect_gle(ERROR_INVALID_PARAMETER); expect_gle(ERROR_INVALID_PARAMETER);
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
r = GetProfilesDirectoryA(NULL, &cch); r = GetProfilesDirectoryA(NULL, &cch);
expect(FALSE, r); expect(FALSE, r);
todo_wine
expect_gle(ERROR_INVALID_PARAMETER); expect_gle(ERROR_INVALID_PARAMETER);
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
cch = 1; cch = 1;
r = GetProfilesDirectoryA(small_buf, &cch); r = GetProfilesDirectoryA(small_buf, &cch);
expect(FALSE, r); expect(FALSE, r);
todo_wine
expect_gle(ERROR_INSUFFICIENT_BUFFER); expect_gle(ERROR_INSUFFICIENT_BUFFER);
/* MSDN claims the returned character count includes the NULL terminator /* 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. * 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); 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); r = GetProfilesDirectoryA(buf, &cch);
/* Rather than a BOOL, the return value is also the number of characters /* Rather than a BOOL, the return value is also the number of characters
* stored in the buffer. * stored in the buffer.
*/ */
todo_wine
expect(profiles_len - 1, r); expect(profiles_len - 1, r);
todo_wine
ok(!strcmp(buf, profiles_dir), "expected %s, got %s\n", profiles_dir, buf); ok(!strcmp(buf, profiles_dir), "expected %s, got %s\n", profiles_dir, buf);
HeapFree(GetProcessHeap(), 0, buf); HeapFree(GetProcessHeap(), 0, buf);
......
...@@ -114,16 +114,128 @@ BOOL WINAPI GetUserProfileDirectoryW( HANDLE hToken, LPWSTR lpProfileDir, ...@@ -114,16 +114,128 @@ BOOL WINAPI GetUserProfileDirectoryW( HANDLE hToken, LPWSTR lpProfileDir,
return FALSE; return FALSE;
} }
static const char ProfileListA[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList";
BOOL WINAPI GetProfilesDirectoryA( LPSTR lpProfilesDir, LPDWORD lpcchSize ) BOOL WINAPI GetProfilesDirectoryA( LPSTR lpProfilesDir, LPDWORD lpcchSize )
{ {
FIXME("%p %p\n", lpProfilesDir, lpcchSize ); static const char ProfilesDirectory[] = "ProfilesDirectory";
return FALSE; 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 ) BOOL WINAPI GetProfilesDirectoryW( LPWSTR lpProfilesDir, LPDWORD lpcchSize )
{ {
FIXME("%p %p\n", lpProfilesDir, lpcchSize ); static const WCHAR ProfilesDirectory[] = {'P','r','o','f','i','l','e','s','D','i','r','e','c','t','o','r','y',0};
return FALSE; 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 ) BOOL WINAPI GetAllUsersProfileDirectoryA( LPSTR lpProfileDir, LPDWORD lpcchSize )
......
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