[USERENV]

- Fix some DPRINTs;
- Add parameter validation in CreateUserProfileExW;
- Return the directory path of the created profile in CreateUserProfileExW, if the user wants it;
- Add value type validation for RegQueryValueExW calls;
- Use ARRAYSIZE where needed;
- Add parameter validation in GetAllUsersProfileDirectoryA, GetDefaultUserProfileDirectoryA;
- Correctly return error code in GetAllUsersProfileDirectoryW, GetDefaultUserProfileDirectoryW, GetProfilesDirectoryW and GetUserProfileDirectoryW. Should fix the userenv_apitest:GetProfileDirs tests.

svn path=/trunk/; revision=73737
This commit is contained in:
Hermès Bélusca-Maïto 2017-02-06 22:58:20 +00:00
parent e324a62898
commit 6050891f74

View file

@ -266,7 +266,7 @@ CreateUserProfileExW(
WCHAR szUserProfileName[MAX_PATH]; WCHAR szUserProfileName[MAX_PATH];
WCHAR szBuffer[MAX_PATH]; WCHAR szBuffer[MAX_PATH];
LPWSTR SidString; LPWSTR SidString;
DWORD dwLength; DWORD dwType, dwLength;
DWORD dwDisposition; DWORD dwDisposition;
UINT i; UINT i;
HKEY hKey; HKEY hKey;
@ -276,9 +276,16 @@ CreateUserProfileExW(
DPRINT("CreateUserProfileExW(%p %S %S %p %lu %d)\n", DPRINT("CreateUserProfileExW(%p %S %S %p %lu %d)\n",
pSid, lpUserName, lpUserHive, lpProfileDir, dwDirSize, bWin9xUpg); pSid, lpUserName, lpUserHive, lpProfileDir, dwDirSize, bWin9xUpg);
/* Parameters validation */
if (!pSid || !lpUserName)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
/* /*
* TODO: * TODO:
* - Add support for lpUserHive, lpProfileDir. * - Add support for lpUserHive.
* - bWin9xUpg is obsolete. Don't waste your time implementing this. * - bWin9xUpg is obsolete. Don't waste your time implementing this.
*/ */
@ -299,10 +306,10 @@ CreateUserProfileExW(
Error = RegQueryValueExW(hKey, Error = RegQueryValueExW(hKey,
L"ProfilesDirectory", L"ProfilesDirectory",
NULL, NULL,
NULL, &dwType,
(LPBYTE)szRawProfilesPath, (LPBYTE)szRawProfilesPath,
&dwLength); &dwLength);
if (Error != ERROR_SUCCESS) if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{ {
DPRINT1("Error: %lu\n", Error); DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey); RegCloseKey(hKey);
@ -320,7 +327,8 @@ CreateUserProfileExW(
return FALSE; return FALSE;
} }
/* create the profiles directory if it does not yet exist */ /* Create the profiles directory if it does not exist yet */
// FIXME: Security!
if (!CreateDirectoryW(szProfilesPath, NULL)) if (!CreateDirectoryW(szProfilesPath, NULL))
{ {
if (GetLastError() != ERROR_ALREADY_EXISTS) if (GetLastError() != ERROR_ALREADY_EXISTS)
@ -335,10 +343,10 @@ CreateUserProfileExW(
Error = RegQueryValueExW(hKey, Error = RegQueryValueExW(hKey,
L"DefaultUserProfile", L"DefaultUserProfile",
NULL, NULL,
NULL, &dwType,
(LPBYTE)szBuffer, (LPBYTE)szBuffer,
&dwLength); &dwLength);
if (Error != ERROR_SUCCESS) if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{ {
DPRINT1("Error: %lu\n", Error); DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey); RegCloseKey(hKey);
@ -346,19 +354,17 @@ CreateUserProfileExW(
return FALSE; return FALSE;
} }
RegCloseKey (hKey); RegCloseKey(hKey);
wcscpy(szUserProfileName, lpUserName); StringCbCopyW(szUserProfileName, sizeof(szUserProfileName), lpUserName);
wcscpy(szUserProfilePath, szProfilesPath);
wcscat(szUserProfilePath, L"\\");
wcscat(szUserProfilePath, szUserProfileName);
wcscpy(szDefaultUserPath, szProfilesPath);
wcscat(szDefaultUserPath, L"\\");
wcscat(szDefaultUserPath, szBuffer);
/* Create user profile directory */ /* Create user profile directory */
StringCbCopyW(szUserProfilePath, sizeof(szUserProfilePath), szProfilesPath);
StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), L"\\");
StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), szUserProfileName);
// FIXME: Security!
if (!CreateDirectoryW(szUserProfilePath, NULL)) if (!CreateDirectoryW(szUserProfilePath, NULL))
{ {
if (GetLastError() != ERROR_ALREADY_EXISTS) if (GetLastError() != ERROR_ALREADY_EXISTS)
@ -371,10 +377,11 @@ CreateUserProfileExW(
{ {
swprintf(szUserProfileName, L"%s.%03u", lpUserName, i); swprintf(szUserProfileName, L"%s.%03u", lpUserName, i);
wcscpy(szUserProfilePath, szProfilesPath); StringCbCopyW(szUserProfilePath, sizeof(szUserProfilePath), szProfilesPath);
wcscat(szUserProfilePath, L"\\"); StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), L"\\");
wcscat(szUserProfilePath, szUserProfileName); StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), szUserProfileName);
// FIXME: Security!
if (CreateDirectoryW(szUserProfilePath, NULL)) if (CreateDirectoryW(szUserProfilePath, NULL))
break; break;
@ -387,6 +394,12 @@ CreateUserProfileExW(
} }
/* Copy default user directory */ /* Copy default user directory */
StringCbCopyW(szDefaultUserPath, sizeof(szDefaultUserPath), szProfilesPath);
StringCbCatW(szDefaultUserPath, sizeof(szDefaultUserPath), L"\\");
StringCbCatW(szDefaultUserPath, sizeof(szDefaultUserPath), szBuffer);
// FIXME: Security!
if (!CopyDirectory(szUserProfilePath, szDefaultUserPath)) if (!CopyDirectory(szUserProfilePath, szDefaultUserPath))
{ {
DPRINT1("Error: %lu\n", GetLastError()); DPRINT1("Error: %lu\n", GetLastError());
@ -401,9 +414,9 @@ CreateUserProfileExW(
return FALSE; return FALSE;
} }
wcscpy(szBuffer, StringCbCopyW(szBuffer, sizeof(szBuffer),
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\"); L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
wcscat(szBuffer, SidString); StringCbCatW(szBuffer, sizeof(szBuffer), SidString);
/* Create user profile key */ /* Create user profile key */
Error = RegCreateKeyExW(HKEY_LOCAL_MACHINE, Error = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
@ -423,9 +436,9 @@ CreateUserProfileExW(
} }
/* Create non-expanded user profile path */ /* Create non-expanded user profile path */
wcscpy(szBuffer, szRawProfilesPath); StringCbCopyW(szBuffer, sizeof(szBuffer), szRawProfilesPath);
wcscat(szBuffer, L"\\"); StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
wcscat(szBuffer, szUserProfileName); StringCbCatW(szBuffer, sizeof(szBuffer), szUserProfileName);
/* Set 'ProfileImagePath' value (non-expanded) */ /* Set 'ProfileImagePath' value (non-expanded) */
Error = RegSetValueExW(hKey, Error = RegSetValueExW(hKey,
@ -459,9 +472,11 @@ CreateUserProfileExW(
RegCloseKey(hKey); RegCloseKey(hKey);
/* Create user hive name */ /* Create user hive file */
wcscpy(szBuffer, szUserProfilePath);
wcscat(szBuffer, L"\\ntuser.dat"); /* Use the default hive file name */
StringCbCopyW(szBuffer, sizeof(szBuffer), szUserProfilePath);
StringCbCatW(szBuffer, sizeof(szBuffer), L"\\ntuser.dat");
/* Acquire restore privilege */ /* Acquire restore privilege */
if (!AcquireRemoveRestorePrivilege(TRUE)) if (!AcquireRemoveRestorePrivilege(TRUE))
@ -472,7 +487,7 @@ CreateUserProfileExW(
goto done; goto done;
} }
/* Create new user hive */ /* Load the user hive */
Error = RegLoadKeyW(HKEY_USERS, Error = RegLoadKeyW(HKEY_USERS,
SidString, SidString,
szBuffer); szBuffer);
@ -497,6 +512,13 @@ CreateUserProfileExW(
RegUnLoadKeyW(HKEY_USERS, SidString); RegUnLoadKeyW(HKEY_USERS, SidString);
AcquireRemoveRestorePrivilege(FALSE); AcquireRemoveRestorePrivilege(FALSE);
/*
* If the caller wants to retrieve the user profile path,
* give it now. 'dwDirSize' is the number of characters.
*/
if (lpProfileDir && dwDirSize)
StringCchCopyW(lpProfileDir, dwDirSize, szUserProfilePath);
done: done:
LocalFree((HLOCAL)SidString); LocalFree((HLOCAL)SidString);
SetLastError((DWORD)Error); SetLastError((DWORD)Error);
@ -516,6 +538,12 @@ GetAllUsersProfileDirectoryA(
LPWSTR lpBuffer; LPWSTR lpBuffer;
BOOL bResult; BOOL bResult;
if (!lpcchSize)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
lpBuffer = GlobalAlloc(GMEM_FIXED, lpBuffer = GlobalAlloc(GMEM_FIXED,
*lpcchSize * sizeof(WCHAR)); *lpcchSize * sizeof(WCHAR));
if (lpBuffer == NULL) if (lpBuffer == NULL)
@ -523,16 +551,16 @@ GetAllUsersProfileDirectoryA(
bResult = GetAllUsersProfileDirectoryW(lpBuffer, bResult = GetAllUsersProfileDirectoryW(lpBuffer,
lpcchSize); lpcchSize);
if (bResult) if (bResult && lpProfileDir)
{ {
WideCharToMultiByte(CP_ACP, bResult = WideCharToMultiByte(CP_ACP,
0, 0,
lpBuffer, lpBuffer,
-1, -1,
lpProfileDir, lpProfileDir,
*lpcchSize, *lpcchSize,
NULL, NULL,
NULL); NULL);
} }
GlobalFree(lpBuffer); GlobalFree(lpBuffer);
@ -549,7 +577,7 @@ GetAllUsersProfileDirectoryW(
{ {
WCHAR szProfilePath[MAX_PATH]; WCHAR szProfilePath[MAX_PATH];
WCHAR szBuffer[MAX_PATH]; WCHAR szBuffer[MAX_PATH];
DWORD dwLength; DWORD dwType, dwLength;
HKEY hKey; HKEY hKey;
LONG Error; LONG Error;
@ -576,10 +604,10 @@ GetAllUsersProfileDirectoryW(
Error = RegQueryValueExW(hKey, Error = RegQueryValueExW(hKey,
L"ProfilesDirectory", L"ProfilesDirectory",
NULL, NULL,
NULL, &dwType,
(LPBYTE)szBuffer, (LPBYTE)szBuffer,
&dwLength); &dwLength);
if (Error != ERROR_SUCCESS) if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{ {
DPRINT1("Error: %lu\n", Error); DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey); RegCloseKey(hKey);
@ -590,10 +618,10 @@ GetAllUsersProfileDirectoryW(
/* Expand it */ /* Expand it */
if (!ExpandEnvironmentStringsW(szBuffer, if (!ExpandEnvironmentStringsW(szBuffer,
szProfilePath, szProfilePath,
MAX_PATH)) ARRAYSIZE(szProfilePath)))
{ {
DPRINT1("Error: %lu\n", GetLastError()); DPRINT1("Error: %lu\n", GetLastError());
RegCloseKey (hKey); RegCloseKey(hKey);
return FALSE; return FALSE;
} }
@ -602,10 +630,10 @@ GetAllUsersProfileDirectoryW(
Error = RegQueryValueExW(hKey, Error = RegQueryValueExW(hKey,
L"AllUsersProfile", L"AllUsersProfile",
NULL, NULL,
NULL, &dwType,
(LPBYTE)szBuffer, (LPBYTE)szBuffer,
&dwLength); &dwLength);
if (Error != ERROR_SUCCESS) if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{ {
DPRINT1("Error: %lu\n", Error); DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey); RegCloseKey(hKey);
@ -613,27 +641,24 @@ GetAllUsersProfileDirectoryW(
return FALSE; return FALSE;
} }
RegCloseKey (hKey); RegCloseKey(hKey);
wcscat(szProfilePath, L"\\"); StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
wcscat(szProfilePath, szBuffer); StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
dwLength = wcslen(szProfilePath) + 1; dwLength = wcslen(szProfilePath) + 1;
if (lpProfileDir != NULL) if (lpProfileDir && (*lpcchSize >= dwLength))
{ {
if (*lpcchSize < dwLength) StringCchCopyW(lpProfileDir, *lpcchSize, szProfilePath);
{ *lpcchSize = dwLength;
*lpcchSize = dwLength; return TRUE;
SetLastError(ERROR_INSUFFICIENT_BUFFER); }
return FALSE; else // if (!lpProfileDir || (*lpcchSize < dwLength))
} {
*lpcchSize = dwLength;
wcscpy(lpProfileDir, szProfilePath); SetLastError(ERROR_INSUFFICIENT_BUFFER);
} return FALSE;
}
*lpcchSize = dwLength;
return TRUE;
} }
@ -646,6 +671,12 @@ GetDefaultUserProfileDirectoryA(
LPWSTR lpBuffer; LPWSTR lpBuffer;
BOOL bResult; BOOL bResult;
if (!lpcchSize)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
lpBuffer = GlobalAlloc(GMEM_FIXED, lpBuffer = GlobalAlloc(GMEM_FIXED,
*lpcchSize * sizeof(WCHAR)); *lpcchSize * sizeof(WCHAR));
if (lpBuffer == NULL) if (lpBuffer == NULL)
@ -653,16 +684,16 @@ GetDefaultUserProfileDirectoryA(
bResult = GetDefaultUserProfileDirectoryW(lpBuffer, bResult = GetDefaultUserProfileDirectoryW(lpBuffer,
lpcchSize); lpcchSize);
if (bResult) if (bResult && lpProfileDir)
{ {
WideCharToMultiByte(CP_ACP, bResult = WideCharToMultiByte(CP_ACP,
0, 0,
lpBuffer, lpBuffer,
-1, -1,
lpProfileDir, lpProfileDir,
*lpcchSize, *lpcchSize,
NULL, NULL,
NULL); NULL);
} }
GlobalFree(lpBuffer); GlobalFree(lpBuffer);
@ -679,7 +710,7 @@ GetDefaultUserProfileDirectoryW(
{ {
WCHAR szProfilePath[MAX_PATH]; WCHAR szProfilePath[MAX_PATH];
WCHAR szBuffer[MAX_PATH]; WCHAR szBuffer[MAX_PATH];
DWORD dwLength; DWORD dwType, dwLength;
HKEY hKey; HKEY hKey;
LONG Error; LONG Error;
@ -706,10 +737,10 @@ GetDefaultUserProfileDirectoryW(
Error = RegQueryValueExW(hKey, Error = RegQueryValueExW(hKey,
L"ProfilesDirectory", L"ProfilesDirectory",
NULL, NULL,
NULL, &dwType,
(LPBYTE)szBuffer, (LPBYTE)szBuffer,
&dwLength); &dwLength);
if (Error != ERROR_SUCCESS) if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{ {
DPRINT1("Error: %lu\n", Error); DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey); RegCloseKey(hKey);
@ -720,7 +751,7 @@ GetDefaultUserProfileDirectoryW(
/* Expand it */ /* Expand it */
if (!ExpandEnvironmentStringsW(szBuffer, if (!ExpandEnvironmentStringsW(szBuffer,
szProfilePath, szProfilePath,
MAX_PATH)) ARRAYSIZE(szProfilePath)))
{ {
DPRINT1("Error: %lu\n", GetLastError()); DPRINT1("Error: %lu\n", GetLastError());
RegCloseKey(hKey); RegCloseKey(hKey);
@ -732,10 +763,10 @@ GetDefaultUserProfileDirectoryW(
Error = RegQueryValueExW(hKey, Error = RegQueryValueExW(hKey,
L"DefaultUserProfile", L"DefaultUserProfile",
NULL, NULL,
NULL, &dwType,
(LPBYTE)szBuffer, (LPBYTE)szBuffer,
&dwLength); &dwLength);
if (Error != ERROR_SUCCESS) if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{ {
DPRINT1("Error: %lu\n", Error); DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey); RegCloseKey(hKey);
@ -745,25 +776,22 @@ GetDefaultUserProfileDirectoryW(
RegCloseKey(hKey); RegCloseKey(hKey);
wcscat(szProfilePath, L"\\"); StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
wcscat(szProfilePath, szBuffer); StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
dwLength = wcslen(szProfilePath) + 1; dwLength = wcslen(szProfilePath) + 1;
if (lpProfileDir != NULL) if (lpProfileDir && (*lpcchSize >= dwLength))
{ {
if (*lpcchSize < dwLength) StringCchCopyW(lpProfileDir, *lpcchSize, szProfilePath);
{ *lpcchSize = dwLength;
*lpcchSize = dwLength; return TRUE;
SetLastError(ERROR_INSUFFICIENT_BUFFER); }
return FALSE; else // if (!lpProfileDir || (*lpcchSize < dwLength))
} {
*lpcchSize = dwLength;
wcscpy(lpProfileDir, szProfilePath); SetLastError(ERROR_INSUFFICIENT_BUFFER);
} return FALSE;
}
*lpcchSize = dwLength;
return TRUE;
} }
@ -776,7 +804,7 @@ GetProfilesDirectoryA(
LPWSTR lpBuffer; LPWSTR lpBuffer;
BOOL bResult; BOOL bResult;
if (!lpProfileDir || !lpcchSize) if (!lpcchSize)
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
@ -789,7 +817,7 @@ GetProfilesDirectoryA(
bResult = GetProfilesDirectoryW(lpBuffer, bResult = GetProfilesDirectoryW(lpBuffer,
lpcchSize); lpcchSize);
if (bResult) if (bResult && lpProfileDir)
{ {
bResult = WideCharToMultiByte(CP_ACP, bResult = WideCharToMultiByte(CP_ACP,
0, 0,
@ -815,10 +843,9 @@ GetProfilesDirectoryW(
{ {
WCHAR szProfilesPath[MAX_PATH]; WCHAR szProfilesPath[MAX_PATH];
WCHAR szBuffer[MAX_PATH]; WCHAR szBuffer[MAX_PATH];
DWORD dwLength; DWORD dwType, dwLength;
HKEY hKey; HKEY hKey;
LONG Error; LONG Error;
BOOL bRet = FALSE;
if (!lpcchSize) if (!lpcchSize)
{ {
@ -843,10 +870,10 @@ GetProfilesDirectoryW(
Error = RegQueryValueExW(hKey, Error = RegQueryValueExW(hKey,
L"ProfilesDirectory", L"ProfilesDirectory",
NULL, NULL,
NULL, &dwType,
(LPBYTE)szBuffer, (LPBYTE)szBuffer,
&dwLength); &dwLength);
if (Error != ERROR_SUCCESS) if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{ {
DPRINT1("Error: %lu\n", Error); DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey); RegCloseKey(hKey);
@ -866,26 +893,18 @@ GetProfilesDirectoryW(
} }
dwLength = wcslen(szProfilesPath) + 1; dwLength = wcslen(szProfilesPath) + 1;
if (lpProfilesDir != NULL) if (lpProfilesDir && (*lpcchSize >= dwLength))
{ {
if (*lpcchSize < dwLength) StringCchCopyW(lpProfilesDir, *lpcchSize, szProfilesPath);
{ *lpcchSize = dwLength;
SetLastError(ERROR_INSUFFICIENT_BUFFER); return TRUE;
}
else
{
wcscpy(lpProfilesDir, szProfilesPath);
bRet = TRUE;
}
} }
else else // if (!lpProfilesDir || (*lpcchSize < dwLength))
{ {
*lpcchSize = dwLength;
SetLastError(ERROR_INSUFFICIENT_BUFFER); SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
} }
*lpcchSize = dwLength;
return bRet;
} }
@ -899,9 +918,9 @@ GetUserProfileDirectoryA(
LPWSTR lpBuffer; LPWSTR lpBuffer;
BOOL bResult; BOOL bResult;
if (!lpProfileDir || !lpcchSize) if (!lpcchSize)
{ {
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@ -913,16 +932,16 @@ GetUserProfileDirectoryA(
bResult = GetUserProfileDirectoryW(hToken, bResult = GetUserProfileDirectoryW(hToken,
lpBuffer, lpBuffer,
lpcchSize); lpcchSize);
if (bResult) if (bResult && lpProfileDir)
{ {
WideCharToMultiByte(CP_ACP, bResult = WideCharToMultiByte(CP_ACP,
0, 0,
lpBuffer, lpBuffer,
-1, -1,
lpProfileDir, lpProfileDir,
*lpcchSize, *lpcchSize,
NULL, NULL,
NULL); NULL);
} }
GlobalFree(lpBuffer); GlobalFree(lpBuffer);
@ -942,7 +961,7 @@ GetUserProfileDirectoryW(
WCHAR szKeyName[MAX_PATH]; WCHAR szKeyName[MAX_PATH];
WCHAR szRawImagePath[MAX_PATH]; WCHAR szRawImagePath[MAX_PATH];
WCHAR szImagePath[MAX_PATH]; WCHAR szImagePath[MAX_PATH];
DWORD dwLength; DWORD dwType, dwLength;
HKEY hKey; HKEY hKey;
LONG Error; LONG Error;
@ -958,19 +977,18 @@ GetUserProfileDirectoryW(
return FALSE; return FALSE;
} }
if (!GetUserSidStringFromToken(hToken, /* Get the user SID string */
&SidString)) if (!GetUserSidStringFromToken(hToken, &SidString))
{ {
DPRINT1("GetUserSidFromToken() failed\n"); DPRINT1("GetUserSidStringFromToken() failed\n");
return FALSE; return FALSE;
} }
DPRINT("SidString: '%wZ'\n", &SidString); DPRINT("SidString: '%wZ'\n", &SidString);
wcscpy(szKeyName, StringCbCopyW(szKeyName, sizeof(szKeyName),
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\"); L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
wcscat(szKeyName, StringCbCatW(szKeyName, sizeof(szKeyName), SidString.Buffer);
SidString.Buffer);
RtlFreeUnicodeString(&SidString); RtlFreeUnicodeString(&SidString);
@ -992,10 +1010,10 @@ GetUserProfileDirectoryW(
Error = RegQueryValueExW(hKey, Error = RegQueryValueExW(hKey,
L"ProfileImagePath", L"ProfileImagePath",
NULL, NULL,
NULL, &dwType,
(LPBYTE)szRawImagePath, (LPBYTE)szRawImagePath,
&dwLength); &dwLength);
if (Error != ERROR_SUCCESS) if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{ {
DPRINT1("Error: %lu\n", Error); DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey); RegCloseKey(hKey);
@ -1018,18 +1036,19 @@ GetUserProfileDirectoryW(
DPRINT("ImagePath: '%S'\n", szImagePath); DPRINT("ImagePath: '%S'\n", szImagePath);
dwLength = wcslen (szImagePath) + 1; dwLength = wcslen(szImagePath) + 1;
if (*lpcchSize < dwLength) if (lpProfileDir && (*lpcchSize >= dwLength))
{
StringCchCopyW(lpProfileDir, *lpcchSize, szImagePath);
*lpcchSize = dwLength;
return TRUE;
}
else // if (!lpProfileDir || (*lpcchSize < dwLength))
{ {
*lpcchSize = dwLength; *lpcchSize = dwLength;
SetLastError(ERROR_INSUFFICIENT_BUFFER); SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
*lpcchSize = dwLength;
wcscpy(lpProfileDir, szImagePath);
return TRUE;
} }
@ -1042,10 +1061,10 @@ CheckForLoadedProfile(HANDLE hToken)
DPRINT("CheckForLoadedProfile() called\n"); DPRINT("CheckForLoadedProfile() called\n");
if (!GetUserSidStringFromToken(hToken, /* Get the user SID string */
&SidString)) if (!GetUserSidStringFromToken(hToken, &SidString))
{ {
DPRINT1("GetUserSidFromToken() failed\n"); DPRINT1("GetUserSidStringFromToken() failed\n");
return FALSE; return FALSE;
} }
@ -1217,7 +1236,8 @@ LoadUserProfileW(
if (lpProfileInfo->lpProfilePath) if (lpProfileInfo->lpProfilePath)
{ {
wcscpy(szUserHivePath, lpProfileInfo->lpProfilePath); /* Use the caller's specified roaming user profile path */
StringCbCopyW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpProfilePath);
} }
else else
{ {
@ -1230,9 +1250,9 @@ LoadUserProfileW(
} }
/* Create user hive name */ /* Create user hive name */
wcscat(szUserHivePath, L"\\"); StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\");
wcscat(szUserHivePath, lpProfileInfo->lpUserName); StringCbCatW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpUserName);
wcscat(szUserHivePath, L"\\ntuser.dat"); StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\ntuser.dat");
DPRINT("szUserHivePath: %S\n", szUserHivePath); DPRINT("szUserHivePath: %S\n", szUserHivePath);
/* Create user profile directory if needed */ /* Create user profile directory if needed */
@ -1311,11 +1331,11 @@ LoadUserProfileW(
} }
} }
/* Get user SID string */ /* Get the user SID string */
ret = GetUserSidStringFromToken(hToken, &SidString); ret = GetUserSidStringFromToken(hToken, &SidString);
if (!ret) if (!ret)
{ {
DPRINT1("GetUserSidFromToken() failed\n"); DPRINT1("GetUserSidStringFromToken() failed\n");
goto cleanup; goto cleanup;
} }
ret = FALSE; ret = FALSE;
@ -1390,10 +1410,10 @@ UnloadUserProfile(
RegCloseKey(hProfile); RegCloseKey(hProfile);
if (!GetUserSidStringFromToken(hToken, /* Get the user SID string */
&SidString)) if (!GetUserSidStringFromToken(hToken, &SidString))
{ {
DPRINT1("GetUserSidFromToken() failed\n"); DPRINT1("GetUserSidStringFromToken() failed\n");
return FALSE; return FALSE;
} }