-/*
- * ReactOS kernel
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
/* Build profile name postfix */
if (!ExpandEnvironmentStringsW(L"%SystemRoot%",
szSystemRoot,
- MAX_PATH))
+ ARRAYSIZE(szSystemRoot)))
{
DPRINT1("Error: %lu\n", GetLastError());
return FALSE;
while (*lpszPtr != (WCHAR)0)
{
if (*lpszPtr == L'\\')
- *lpszPtr = '_';
+ *lpszPtr = L'_';
lpszPtr++;
}
}
+static
+BOOL
+CheckForLoadedProfile(HANDLE hToken)
+{
+ UNICODE_STRING SidString;
+ HKEY hKey;
+
+ DPRINT("CheckForLoadedProfile() called\n");
+
+ /* Get the user SID string */
+ if (!GetUserSidStringFromToken(hToken, &SidString))
+ {
+ DPRINT1("GetUserSidStringFromToken() failed\n");
+ return FALSE;
+ }
+
+ if (RegOpenKeyExW(HKEY_USERS,
+ SidString.Buffer,
+ 0,
+ MAXIMUM_ALLOWED,
+ &hKey))
+ {
+ DPRINT("Profile not loaded\n");
+ RtlFreeUnicodeString(&SidString);
+ return FALSE;
+ }
+
+ RegCloseKey(hKey);
+
+ RtlFreeUnicodeString(&SidString);
+
+ DPRINT("Profile already loaded\n");
+
+ return TRUE;
+}
+
+
+static
+HANDLE
+CreateProfileMutex(
+ _In_ PWSTR pszSidString)
+{
+ SECURITY_DESCRIPTOR SecurityDescriptor;
+ SECURITY_ATTRIBUTES SecurityAttributes;
+ PWSTR pszMutexName = NULL;
+ HANDLE hMutex = NULL;
+
+ pszMutexName = HeapAlloc(GetProcessHeap(),
+ 0,
+ (wcslen(L"Global\\userenv: User Profile Mutex for ") + wcslen(pszSidString) + 1) * sizeof(WCHAR));
+ if (pszMutexName == NULL)
+ {
+ DPRINT("Failed to allocate the mutex name buffer!\n");
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+
+ /* Build the profile mutex name */
+ wcscpy(pszMutexName, L"Global\\userenv: User Profile Mutex for ");
+ wcscat(pszMutexName, pszSidString);
+
+ /* Initialize the security descriptor */
+ InitializeSecurityDescriptor(&SecurityDescriptor,
+ SECURITY_DESCRIPTOR_REVISION);
+
+ /* Set a NULL-DACL (everyone has access) */
+ SetSecurityDescriptorDacl(&SecurityDescriptor,
+ TRUE,
+ NULL,
+ FALSE);
+
+ /* Initialize the security attributes */
+ SecurityAttributes.nLength = sizeof(SecurityAttributes);
+ SecurityAttributes.lpSecurityDescriptor = &SecurityDescriptor;
+ SecurityAttributes.bInheritHandle = FALSE;
+
+ /* Create the profile mutex */
+ hMutex = CreateMutexW(&SecurityAttributes,
+ FALSE,
+ pszMutexName);
+ if (hMutex == NULL)
+ {
+ DPRINT1("Failed to create the profile mutex (Error %lu)\n", GetLastError());
+ }
+
+ HeapFree(GetProcessHeap(), 0, pszMutexName);
+
+ return hMutex;
+}
+
+
+static
+DWORD
+IncrementRefCount(
+ PWSTR pszSidString,
+ PDWORD pdwRefCount)
+{
+ HKEY hProfilesKey = NULL, hProfileKey = NULL;
+ DWORD dwRefCount = 0, dwLength, dwType;
+ DWORD dwError;
+
+ DPRINT1("IncrementRefCount(%S %p)\n",
+ pszSidString, pdwRefCount);
+
+ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
+ 0,
+ KEY_QUERY_VALUE,
+ &hProfilesKey);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("Error: %lu\n", dwError);
+ goto done;
+ }
+
+ dwError = RegOpenKeyExW(hProfilesKey,
+ pszSidString,
+ 0,
+ KEY_QUERY_VALUE | KEY_SET_VALUE,
+ &hProfileKey);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("Error: %lu\n", dwError);
+ goto done;
+ }
+
+ /* Get the reference counter */
+ dwLength = sizeof(dwRefCount);
+ RegQueryValueExW(hProfileKey,
+ L"RefCount",
+ NULL,
+ &dwType,
+ (PBYTE)&dwRefCount,
+ &dwLength);
+
+ dwRefCount++;
+
+ dwLength = sizeof(dwRefCount);
+ dwError = RegSetValueExW(hProfileKey,
+ L"RefCount",
+ 0,
+ REG_DWORD,
+ (PBYTE)&dwRefCount,
+ dwLength);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("Error: %lu\n", dwError);
+ goto done;
+ }
+
+ if (pdwRefCount != NULL)
+ *pdwRefCount = dwRefCount;
+
+done:
+ if (hProfileKey != NULL)
+ RegCloseKey(hProfileKey);
+
+ if (hProfilesKey != NULL)
+ RegCloseKey(hProfilesKey);
+
+ return dwError;
+}
+
+
+static
+DWORD
+DecrementRefCount(
+ PWSTR pszSidString,
+ PDWORD pdwRefCount)
+{
+ HKEY hProfilesKey = NULL, hProfileKey = NULL;
+ DWORD dwRefCount = 0, dwLength, dwType;
+ DWORD dwError;
+
+ DPRINT1("DecrementRefCount(%S %p)\n",
+ pszSidString, pdwRefCount);
+
+ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
+ 0,
+ KEY_QUERY_VALUE,
+ &hProfilesKey);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("Error: %lu\n", dwError);
+ goto done;
+ }
+
+ dwError = RegOpenKeyExW(hProfilesKey,
+ pszSidString,
+ 0,
+ KEY_QUERY_VALUE | KEY_SET_VALUE,
+ &hProfileKey);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("Error: %lu\n", dwError);
+ goto done;
+ }
+
+ /* Get the reference counter */
+ dwLength = sizeof(dwRefCount);
+ dwError = RegQueryValueExW(hProfileKey,
+ L"RefCount",
+ NULL,
+ &dwType,
+ (PBYTE)&dwRefCount,
+ &dwLength);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("Error: %lu\n", dwError);
+ goto done;
+ }
+
+ dwRefCount--;
+
+ dwLength = sizeof(dwRefCount);
+ dwError = RegSetValueExW(hProfileKey,
+ L"RefCount",
+ 0,
+ REG_DWORD,
+ (PBYTE)&dwRefCount,
+ dwLength);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("Error: %lu\n", dwError);
+ goto done;
+ }
+
+ if (pdwRefCount != NULL)
+ *pdwRefCount = dwRefCount;
+
+done:
+ if (hProfileKey != NULL)
+ RegCloseKey(hProfileKey);
+
+ if (hProfilesKey != NULL)
+ RegCloseKey(hProfilesKey);
+
+ return dwError;
+}
+
+
+/* PUBLIC FUNCTIONS ********************************************************/
+
BOOL
WINAPI
-CreateUserProfileA(PSID Sid,
- LPCSTR lpUserName)
+CopySystemProfile(
+ _In_ ULONG Unused)
{
- UNICODE_STRING UserName;
+ WCHAR szKeyName[MAX_PATH];
+ WCHAR szRawProfilePath[MAX_PATH];
+ WCHAR szProfilePath[MAX_PATH];
+ WCHAR szDefaultProfilePath[MAX_PATH];
+ UNICODE_STRING SidString = {0, 0, NULL};
+ HANDLE hToken = NULL;
+ PSID pUserSid = NULL;
+ HKEY hProfileKey = NULL;
+ DWORD dwDisposition;
+ BOOL bResult = FALSE;
+ DWORD cchSize;
+ DWORD dwError;
+
+ DPRINT1("CopySystemProfile()\n");
+
+ if (!OpenProcessToken(GetCurrentProcess(),
+ TOKEN_QUERY | TOKEN_IMPERSONATE,
+ &hToken))
+ {
+ DPRINT1("Failed to open the process token (Error %lu)\n", GetLastError());
+ return FALSE;
+ }
+
+ pUserSid = GetUserSid(hToken);
+ if (pUserSid == NULL)
+ {
+ DPRINT1("Failed to get the users SID (Error %lu)\n", GetLastError());
+ goto done;
+ }
+
+ /* Get the user SID string */
+ if (!GetUserSidStringFromToken(hToken, &SidString))
+ {
+ DPRINT1("GetUserSidStringFromToken() failed\n");
+ goto done;
+ }
+
+ StringCbCopyW(szKeyName, sizeof(szKeyName),
+ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
+ StringCbCatW(szKeyName, sizeof(szKeyName), SidString.Buffer);
+
+ RtlFreeUnicodeString(&SidString);
+
+ dwError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
+ szKeyName,
+ 0, NULL, 0,
+ KEY_WRITE,
+ NULL,
+ &hProfileKey,
+ &dwDisposition);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("Failed to create the profile key for the %s profile (Error %lu)\n",
+ SidString.Buffer, dwError);
+ goto done;
+ }
+
+ dwError = RegSetValueExW(hProfileKey,
+ L"Sid",
+ 0,
+ REG_BINARY,
+ (PBYTE)pUserSid,
+ RtlLengthSid(pUserSid));
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("Failed to set the SID value (Error %lu)\n", dwError);
+ goto done;
+ }
+
+ wcscpy(szRawProfilePath,
+ L"%systemroot%\\system32\\config\\systemprofile");
+
+ dwError = RegSetValueExW(hProfileKey,
+ L"ProfileImagePath",
+ 0,
+ REG_EXPAND_SZ,
+ (PBYTE)szRawProfilePath,
+ (wcslen(szRawProfilePath) + 1) * sizeof(WCHAR));
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("Failed to set the ProfileImagePath value (Error %lu)\n", dwError);
+ goto done;
+ }
+
+ /* Expand the raw profile path */
+ if (!ExpandEnvironmentStringsW(szRawProfilePath,
+ szProfilePath,
+ ARRAYSIZE(szProfilePath)))
+ {
+ DPRINT1("Failled to expand the raw profile path (Error %lu)\n", GetLastError());
+ goto done;
+ }
+
+ /* Create the profile directory if it does not exist yet */
+ // FIXME: Security!
+ if (!CreateDirectoryW(szProfilePath, NULL))
+ {
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ DPRINT1("Failed to create the profile directory (Error %lu)\n", GetLastError());
+ goto done;
+ }
+ }
+
+ /* Get the path of the default profile */
+ cchSize = ARRAYSIZE(szDefaultProfilePath);
+ if (!GetDefaultUserProfileDirectoryW(szDefaultProfilePath, &cchSize))
+ {
+ DPRINT1("Failed to create the default profile path (Error %lu)\n", GetLastError());
+ goto done;
+ }
+
+ /* Copy the default profile into the new profile directory */
+ // FIXME: Security!
+ if (!CopyDirectory(szProfilePath, szDefaultProfilePath))
+ {
+ DPRINT1("Failed to copy the default profile directory (Error %lu)\n", GetLastError());
+ goto done;
+ }
+
+ bResult = TRUE;
+
+done:
+ if (hProfileKey != NULL)
+ RegCloseKey(hProfileKey);
+
+ RtlFreeUnicodeString(&SidString);
+
+ if (pUserSid != NULL)
+ LocalFree(pUserSid);
+
+ if (hToken != NULL)
+ CloseHandle(hToken);
+
+ return bResult;
+}
+
+
+BOOL
+WINAPI
+CreateUserProfileA(
+ _In_ PSID pSid,
+ _In_ LPCSTR lpUserName)
+{
+ LPWSTR pUserNameW = NULL;
+ INT nLength;
BOOL bResult;
- if (!RtlCreateUnicodeStringFromAsciiz(&UserName,
- (LPSTR)lpUserName))
+ DPRINT("CreateUserProfileA(%p %s)\n", pSid, lpUserName);
+
+ /* Convert lpUserName to Unicode */
+ nLength = MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, NULL, 0);
+ pUserNameW = HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR));
+ if (pUserNameW == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
+ MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, pUserNameW, nLength);
- bResult = CreateUserProfileW(Sid, UserName.Buffer);
+ /* Call the Ex function */
+ bResult = CreateUserProfileExW(pSid,
+ pUserNameW,
+ NULL,
+ NULL,
+ 0,
+ FALSE);
- RtlFreeUnicodeString(&UserName);
+ HeapFree(GetProcessHeap(), 0, pUserNameW);
return bResult;
}
BOOL
WINAPI
-CreateUserProfileW(PSID Sid,
- LPCWSTR lpUserName)
+CreateUserProfileW(
+ _In_ PSID pSid,
+ _In_ LPCWSTR lpUserName)
+{
+ DPRINT("CreateUserProfileW(%p %S)\n", pSid, lpUserName);
+
+ /* Call the Ex function */
+ return CreateUserProfileExW(pSid,
+ lpUserName,
+ NULL,
+ NULL,
+ 0,
+ FALSE);
+}
+
+
+BOOL
+WINAPI
+CreateUserProfileExA(
+ _In_ PSID pSid,
+ _In_ LPCSTR lpUserName,
+ _In_opt_ LPCSTR lpUserHive,
+ _Out_opt_ LPSTR lpProfileDir,
+ _In_ DWORD dwDirSize,
+ _In_ BOOL bWin9xUpg)
+{
+ LPWSTR pUserNameW = NULL;
+ LPWSTR pUserHiveW = NULL;
+ LPWSTR pProfileDirW = NULL;
+ INT nLength;
+ BOOL bResult = FALSE;
+
+ DPRINT("CreateUserProfileExA(%p %s %s %p %lu %d)\n",
+ pSid, lpUserName, lpUserHive, lpProfileDir, dwDirSize, bWin9xUpg);
+
+ /* Check the parameters */
+ if (lpProfileDir != NULL && dwDirSize == 0)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* Convert lpUserName to Unicode */
+ nLength = MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, NULL, 0);
+ pUserNameW = HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR));
+ if (pUserNameW == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto done;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, pUserNameW, nLength);
+
+ /* Convert lpUserHive to Unicode */
+ if (lpUserHive != NULL)
+ {
+ nLength = MultiByteToWideChar(CP_ACP, 0, lpUserHive, -1, NULL, 0);
+ pUserHiveW = HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR));
+ if (pUserHiveW == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto done;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpUserHive, -1, pUserHiveW, nLength);
+ }
+
+ /* Allocate a Unicode buffer for lpProfileDir */
+ if (lpProfileDir != NULL)
+ {
+ pProfileDirW = HeapAlloc(GetProcessHeap(), 0, dwDirSize * sizeof(WCHAR));
+ if (pProfileDirW == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto done;
+ }
+ }
+
+ /* Call the Unicode function */
+ bResult = CreateUserProfileExW(pSid,
+ (LPCWSTR)pUserNameW,
+ (LPCWSTR)pUserHiveW,
+ pProfileDirW,
+ dwDirSize,
+ bWin9xUpg);
+
+ /* Convert the profile path to ANSI */
+ if (bResult && lpProfileDir != NULL)
+ {
+ WideCharToMultiByte(CP_ACP, 0, pProfileDirW, -1, lpProfileDir, dwDirSize, NULL, NULL);
+ }
+
+done:
+ /* Free the buffers */
+ if (pProfileDirW != NULL)
+ HeapFree(GetProcessHeap(), 0, pProfileDirW);
+
+ if (pUserHiveW != NULL)
+ HeapFree(GetProcessHeap(), 0, pUserHiveW);
+
+ if (pUserNameW != NULL)
+ HeapFree(GetProcessHeap(), 0, pUserNameW);
+
+ return bResult;
+}
+
+
+BOOL
+WINAPI
+CreateUserProfileExW(
+ _In_ PSID pSid,
+ _In_ LPCWSTR lpUserName,
+ _In_opt_ LPCWSTR lpUserHive,
+ _Out_opt_ LPWSTR lpProfileDir,
+ _In_ DWORD dwDirSize,
+ _In_ BOOL bWin9xUpg)
{
WCHAR szRawProfilesPath[MAX_PATH];
WCHAR szProfilesPath[MAX_PATH];
WCHAR szUserProfileName[MAX_PATH];
WCHAR szBuffer[MAX_PATH];
LPWSTR SidString;
- DWORD dwLength;
+ DWORD dwType, dwLength;
DWORD dwDisposition;
UINT i;
HKEY hKey;
BOOL bRet = TRUE;
LONG Error;
- DPRINT("CreateUserProfileW() called\n");
+ DPRINT("CreateUserProfileExW(%p %S %S %p %lu %d)\n",
+ pSid, lpUserName, lpUserHive, lpProfileDir, dwDirSize, bWin9xUpg);
+
+ /* Parameters validation */
+ if (!pSid || !lpUserName)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /*
+ * TODO:
+ * - Add support for lpUserHive.
+ * - bWin9xUpg is obsolete. Don't waste your time implementing this.
+ */
Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
}
/* Get profiles path */
- dwLength = MAX_PATH * sizeof(WCHAR);
+ dwLength = sizeof(szRawProfilesPath);
Error = RegQueryValueExW(hKey,
L"ProfilesDirectory",
NULL,
- NULL,
+ &dwType,
(LPBYTE)szRawProfilesPath,
&dwLength);
- if (Error != ERROR_SUCCESS)
+ if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
/* Expand it */
if (!ExpandEnvironmentStringsW(szRawProfilesPath,
szProfilesPath,
- MAX_PATH))
+ ARRAYSIZE(szProfilesPath)))
{
DPRINT1("Error: %lu\n", GetLastError());
RegCloseKey(hKey);
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 (GetLastError() != ERROR_ALREADY_EXISTS)
}
/* Get default user path */
- dwLength = MAX_PATH * sizeof(WCHAR);
+ dwLength = sizeof(szBuffer);
Error = RegQueryValueExW(hKey,
L"DefaultUserProfile",
NULL,
- NULL,
+ &dwType,
(LPBYTE)szBuffer,
&dwLength);
- if (Error != ERROR_SUCCESS)
+ if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
return FALSE;
}
- RegCloseKey (hKey);
+ RegCloseKey(hKey);
- wcscpy(szUserProfileName, lpUserName);
+ StringCbCopyW(szUserProfileName, sizeof(szUserProfileName), lpUserName);
- wcscpy(szUserProfilePath, szProfilesPath);
- wcscat(szUserProfilePath, L"\\");
- wcscat(szUserProfilePath, szUserProfileName);
+ /* Create user profile directory */
- wcscpy(szDefaultUserPath, szProfilesPath);
- wcscat(szDefaultUserPath, L"\\");
- wcscat(szDefaultUserPath, szBuffer);
+ StringCbCopyW(szUserProfilePath, sizeof(szUserProfilePath), szProfilesPath);
+ StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), L"\\");
+ StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), szUserProfileName);
- /* Create user profile directory */
+ // FIXME: Security!
if (!CreateDirectoryW(szUserProfilePath, NULL))
{
if (GetLastError() != ERROR_ALREADY_EXISTS)
{
swprintf(szUserProfileName, L"%s.%03u", lpUserName, i);
- wcscpy(szUserProfilePath, szProfilesPath);
- wcscat(szUserProfilePath, L"\\");
- wcscat(szUserProfilePath, szUserProfileName);
+ StringCbCopyW(szUserProfilePath, sizeof(szUserProfilePath), szProfilesPath);
+ StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), L"\\");
+ StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), szUserProfileName);
+ // FIXME: Security!
if (CreateDirectoryW(szUserProfilePath, NULL))
break;
}
/* 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))
{
DPRINT1("Error: %lu\n", GetLastError());
}
/* Add profile to profile list */
- if (!ConvertSidToStringSidW(Sid,
+ if (!ConvertSidToStringSidW(pSid,
&SidString))
{
DPRINT1("Error: %lu\n", GetLastError());
return FALSE;
}
- wcscpy(szBuffer,
- L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
- wcscat(szBuffer, SidString);
+ StringCbCopyW(szBuffer, sizeof(szBuffer),
+ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
+ StringCbCatW(szBuffer, sizeof(szBuffer), SidString);
/* Create user profile key */
Error = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
{
DPRINT1("Error: %lu\n", Error);
bRet = FALSE;
- goto Done;
+ goto done;
}
/* Create non-expanded user profile path */
- wcscpy(szBuffer, szRawProfilesPath);
- wcscat(szBuffer, L"\\");
- wcscat(szBuffer, szUserProfileName);
+ StringCbCopyW(szBuffer, sizeof(szBuffer), szRawProfilesPath);
+ StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
+ StringCbCatW(szBuffer, sizeof(szBuffer), szUserProfileName);
/* Set 'ProfileImagePath' value (non-expanded) */
Error = RegSetValueExW(hKey,
0,
REG_EXPAND_SZ,
(LPBYTE)szBuffer,
- (wcslen (szBuffer) + 1) * sizeof(WCHAR));
+ (wcslen(szBuffer) + 1) * sizeof(WCHAR));
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
bRet = FALSE;
- goto Done;
+ goto done;
}
/* Set 'Sid' value */
L"Sid",
0,
REG_BINARY,
- Sid,
- GetLengthSid(Sid));
+ pSid,
+ GetLengthSid(pSid));
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
bRet = FALSE;
- goto Done;
+ goto done;
}
RegCloseKey(hKey);
- /* Create user hive name */
- wcscpy(szBuffer, szUserProfilePath);
- wcscat(szBuffer, L"\\ntuser.dat");
+ /* Create user hive file */
+
+ /* Use the default hive file name */
+ StringCbCopyW(szBuffer, sizeof(szBuffer), szUserProfilePath);
+ StringCbCatW(szBuffer, sizeof(szBuffer), L"\\ntuser.dat");
/* Acquire restore privilege */
if (!AcquireRemoveRestorePrivilege(TRUE))
Error = GetLastError();
DPRINT1("Error: %lu\n", Error);
bRet = FALSE;
- goto Done;
+ goto done;
}
- /* Create new user hive */
+ /* Load the user hive */
Error = RegLoadKeyW(HKEY_USERS,
SidString,
szBuffer);
{
DPRINT1("Error: %lu\n", Error);
bRet = FALSE;
- goto Done;
+ goto done;
}
/* Initialize user hive */
RegUnLoadKeyW(HKEY_USERS, SidString);
AcquireRemoveRestorePrivilege(FALSE);
-Done:
+ /*
+ * 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:
LocalFree((HLOCAL)SidString);
SetLastError((DWORD)Error);
- DPRINT("CreateUserProfileW() done\n");
+ DPRINT("CreateUserProfileExW() done\n");
return bRet;
}
BOOL
WINAPI
-CreateUserProfileExA(IN PSID pSid,
- IN LPCSTR lpUserName,
- IN LPCSTR lpUserHive OPTIONAL,
- OUT LPSTR lpProfileDir OPTIONAL,
- IN DWORD dwDirSize,
- IN BOOL bWin9xUpg)
+DeleteProfileA(
+ _In_ LPCSTR lpSidString,
+ _In_opt_ LPCSTR lpProfilePath,
+ _In_opt_ LPCSTR lpComputerName)
{
- DPRINT1("CreateUserProfileExA() not implemented!\n");
- return FALSE;
+ BOOL bResult;
+ UNICODE_STRING SidString, ProfilePath, ComputerName;
+
+ DPRINT("DeleteProfileA() called\n");
+
+ /* Conversion to UNICODE */
+ if (lpSidString)
+ RtlCreateUnicodeStringFromAsciiz(&SidString,
+ (LPSTR)lpSidString);
+
+ if (lpProfilePath)
+ RtlCreateUnicodeStringFromAsciiz(&ProfilePath,
+ (LPSTR)lpProfilePath);
+
+ if (lpComputerName)
+ RtlCreateUnicodeStringFromAsciiz(&ComputerName,
+ (LPSTR)lpComputerName);
+
+ /* Call the UNICODE function */
+ bResult = DeleteProfileW(SidString.Buffer,
+ ProfilePath.Buffer,
+ ComputerName.Buffer);
+
+ /* Memory cleanup */
+ if (lpSidString)
+ RtlFreeUnicodeString(&SidString);
+
+ if (lpProfilePath)
+ RtlFreeUnicodeString(&ProfilePath);
+
+ if (lpComputerName)
+ RtlFreeUnicodeString(&ComputerName);
+
+ return bResult;
}
BOOL
WINAPI
-CreateUserProfileExW(IN PSID pSid,
- IN LPCWSTR lpUserName,
- IN LPCWSTR lpUserHive OPTIONAL,
- OUT LPWSTR lpProfileDir OPTIONAL,
- IN DWORD dwDirSize,
- IN BOOL bWin9xUpg)
+DeleteProfileW(
+ _In_ LPCWSTR lpSidString,
+ _In_opt_ LPCWSTR lpProfilePath,
+ _In_opt_ LPCWSTR lpComputerName)
{
- DPRINT1("CreateUserProfileExW() not implemented!\n");
+ DPRINT1("DeleteProfileW() not implemented!\n");
return FALSE;
}
BOOL
WINAPI
-GetAllUsersProfileDirectoryA(LPSTR lpProfileDir,
- LPDWORD lpcchSize)
+GetAllUsersProfileDirectoryA(
+ _Out_opt_ LPSTR lpProfileDir,
+ _Inout_ LPDWORD lpcchSize)
{
LPWSTR lpBuffer;
BOOL bResult;
+ if (!lpcchSize)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
lpBuffer = GlobalAlloc(GMEM_FIXED,
*lpcchSize * sizeof(WCHAR));
if (lpBuffer == NULL)
bResult = GetAllUsersProfileDirectoryW(lpBuffer,
lpcchSize);
- if (bResult)
+ if (bResult && lpProfileDir)
{
- WideCharToMultiByte(CP_ACP,
- 0,
- lpBuffer,
- -1,
- lpProfileDir,
- *lpcchSize,
- NULL,
- NULL);
+ bResult = WideCharToMultiByte(CP_ACP,
+ 0,
+ lpBuffer,
+ -1,
+ lpProfileDir,
+ *lpcchSize,
+ NULL,
+ NULL);
}
GlobalFree(lpBuffer);
BOOL
WINAPI
-GetAllUsersProfileDirectoryW(LPWSTR lpProfileDir,
- LPDWORD lpcchSize)
+GetAllUsersProfileDirectoryW(
+ _Out_opt_ LPWSTR lpProfileDir,
+ _Inout_ LPDWORD lpcchSize)
{
WCHAR szProfilePath[MAX_PATH];
WCHAR szBuffer[MAX_PATH];
- DWORD dwLength;
+ DWORD dwType, dwLength;
HKEY hKey;
LONG Error;
+ if (!lpcchSize)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
0,
Error = RegQueryValueExW(hKey,
L"ProfilesDirectory",
NULL,
- NULL,
+ &dwType,
(LPBYTE)szBuffer,
&dwLength);
- if (Error != ERROR_SUCCESS)
+ if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
/* Expand it */
if (!ExpandEnvironmentStringsW(szBuffer,
szProfilePath,
- MAX_PATH))
+ ARRAYSIZE(szProfilePath)))
{
DPRINT1("Error: %lu\n", GetLastError());
- RegCloseKey (hKey);
+ RegCloseKey(hKey);
return FALSE;
}
Error = RegQueryValueExW(hKey,
L"AllUsersProfile",
NULL,
- NULL,
+ &dwType,
(LPBYTE)szBuffer,
&dwLength);
- if (Error != ERROR_SUCCESS)
+ if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
return FALSE;
}
- RegCloseKey (hKey);
+ RegCloseKey(hKey);
- wcscat(szProfilePath, L"\\");
- wcscat(szProfilePath, szBuffer);
+ StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
+ StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
dwLength = wcslen(szProfilePath) + 1;
- if (lpProfileDir != NULL)
+ if (lpProfileDir && (*lpcchSize >= dwLength))
{
- if (*lpcchSize < dwLength)
- {
- *lpcchSize = dwLength;
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
-
- wcscpy(lpProfileDir, szProfilePath);
+ StringCchCopyW(lpProfileDir, *lpcchSize, szProfilePath);
+ *lpcchSize = dwLength;
+ return TRUE;
+ }
+ else // if (!lpProfileDir || (*lpcchSize < dwLength))
+ {
+ *lpcchSize = dwLength;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
}
-
- *lpcchSize = dwLength;
-
- return TRUE;
}
BOOL
WINAPI
-GetDefaultUserProfileDirectoryA(LPSTR lpProfileDir,
- LPDWORD lpcchSize)
+GetDefaultUserProfileDirectoryA(
+ _Out_opt_ LPSTR lpProfileDir,
+ _Inout_ LPDWORD lpcchSize)
{
LPWSTR lpBuffer;
BOOL bResult;
+ if (!lpcchSize)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
lpBuffer = GlobalAlloc(GMEM_FIXED,
*lpcchSize * sizeof(WCHAR));
if (lpBuffer == NULL)
bResult = GetDefaultUserProfileDirectoryW(lpBuffer,
lpcchSize);
- if (bResult)
+ if (bResult && lpProfileDir)
{
- WideCharToMultiByte(CP_ACP,
- 0,
- lpBuffer,
- -1,
- lpProfileDir,
- *lpcchSize,
- NULL,
- NULL);
+ bResult = WideCharToMultiByte(CP_ACP,
+ 0,
+ lpBuffer,
+ -1,
+ lpProfileDir,
+ *lpcchSize,
+ NULL,
+ NULL);
}
GlobalFree(lpBuffer);
BOOL
WINAPI
-GetDefaultUserProfileDirectoryW(LPWSTR lpProfileDir,
- LPDWORD lpcchSize)
+GetDefaultUserProfileDirectoryW(
+ _Out_opt_ LPWSTR lpProfileDir,
+ _Inout_ LPDWORD lpcchSize)
{
WCHAR szProfilePath[MAX_PATH];
WCHAR szBuffer[MAX_PATH];
- DWORD dwLength;
+ DWORD dwType, dwLength;
HKEY hKey;
LONG Error;
+ if (!lpcchSize)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
0,
Error = RegQueryValueExW(hKey,
L"ProfilesDirectory",
NULL,
- NULL,
+ &dwType,
(LPBYTE)szBuffer,
&dwLength);
- if (Error != ERROR_SUCCESS)
+ if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
/* Expand it */
if (!ExpandEnvironmentStringsW(szBuffer,
szProfilePath,
- MAX_PATH))
+ ARRAYSIZE(szProfilePath)))
{
DPRINT1("Error: %lu\n", GetLastError());
RegCloseKey(hKey);
Error = RegQueryValueExW(hKey,
L"DefaultUserProfile",
NULL,
- NULL,
+ &dwType,
(LPBYTE)szBuffer,
&dwLength);
- if (Error != ERROR_SUCCESS)
+ if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
RegCloseKey(hKey);
- wcscat(szProfilePath, L"\\");
- wcscat(szProfilePath, szBuffer);
+ StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
+ StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
dwLength = wcslen(szProfilePath) + 1;
- if (lpProfileDir != NULL)
+ if (lpProfileDir && (*lpcchSize >= dwLength))
{
- if (*lpcchSize < dwLength)
- {
- *lpcchSize = dwLength;
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
-
- wcscpy(lpProfileDir, szProfilePath);
+ StringCchCopyW(lpProfileDir, *lpcchSize, szProfilePath);
+ *lpcchSize = dwLength;
+ return TRUE;
+ }
+ else // if (!lpProfileDir || (*lpcchSize < dwLength))
+ {
+ *lpcchSize = dwLength;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
}
-
- *lpcchSize = dwLength;
-
- return TRUE;
}
BOOL
WINAPI
-GetProfilesDirectoryA(LPSTR lpProfileDir,
- LPDWORD lpcchSize)
+GetProfilesDirectoryA(
+ _Out_ LPSTR lpProfileDir, // _Out_opt_
+ _Inout_ LPDWORD lpcchSize)
{
LPWSTR lpBuffer;
BOOL bResult;
+ if (!lpcchSize)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
lpBuffer = GlobalAlloc(GMEM_FIXED,
*lpcchSize * sizeof(WCHAR));
if (lpBuffer == NULL)
bResult = GetProfilesDirectoryW(lpBuffer,
lpcchSize);
- if (bResult)
+ if (bResult && lpProfileDir)
{
- WideCharToMultiByte(CP_ACP,
- 0,
- lpBuffer,
- -1,
- lpProfileDir,
- *lpcchSize,
- NULL,
- NULL);
+ bResult = WideCharToMultiByte(CP_ACP,
+ 0,
+ lpBuffer,
+ -1,
+ lpProfileDir,
+ *lpcchSize,
+ NULL,
+ NULL);
}
GlobalFree(lpBuffer);
BOOL
WINAPI
-GetProfilesDirectoryW(LPWSTR lpProfilesDir,
- LPDWORD lpcchSize)
+GetProfilesDirectoryW(
+ _Out_ LPWSTR lpProfilesDir, // _Out_opt_
+ _Inout_ LPDWORD lpcchSize)
{
WCHAR szProfilesPath[MAX_PATH];
WCHAR szBuffer[MAX_PATH];
- DWORD dwLength;
+ DWORD dwType, dwLength;
HKEY hKey;
LONG Error;
+ if (!lpcchSize)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
0,
Error = RegQueryValueExW(hKey,
L"ProfilesDirectory",
NULL,
- NULL,
+ &dwType,
(LPBYTE)szBuffer,
&dwLength);
- if (Error != ERROR_SUCCESS)
+ if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
/* Expand it */
if (!ExpandEnvironmentStringsW(szBuffer,
szProfilesPath,
- MAX_PATH))
+ ARRAYSIZE(szProfilesPath)))
{
DPRINT1("Error: %lu\n", GetLastError());
return FALSE;
}
- dwLength = wcslen (szProfilesPath) + 1;
- if (lpProfilesDir != NULL)
+ dwLength = wcslen(szProfilesPath) + 1;
+ if (lpProfilesDir && (*lpcchSize >= dwLength))
{
- if (*lpcchSize < dwLength)
- {
- *lpcchSize = dwLength;
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
-
- wcscpy(lpProfilesDir, szProfilesPath);
+ StringCchCopyW(lpProfilesDir, *lpcchSize, szProfilesPath);
+ *lpcchSize = dwLength;
+ return TRUE;
+ }
+ else // if (!lpProfilesDir || (*lpcchSize < dwLength))
+ {
+ *lpcchSize = dwLength;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
}
+}
- *lpcchSize = dwLength;
- return TRUE;
+BOOL
+WINAPI
+GetProfileType(
+ _Out_ PDWORD pdwFlags)
+{
+ DPRINT1("GetProfileType() not implemented!\n");
+ return FALSE;
}
BOOL
WINAPI
-GetUserProfileDirectoryA(HANDLE hToken,
- LPSTR lpProfileDir,
- LPDWORD lpcchSize)
+GetUserProfileDirectoryA(
+ _In_ HANDLE hToken,
+ _Out_opt_ LPSTR lpProfileDir,
+ _Inout_ LPDWORD lpcchSize)
{
LPWSTR lpBuffer;
BOOL bResult;
+ if (!lpcchSize)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
lpBuffer = GlobalAlloc(GMEM_FIXED,
*lpcchSize * sizeof(WCHAR));
if (lpBuffer == NULL)
bResult = GetUserProfileDirectoryW(hToken,
lpBuffer,
lpcchSize);
- if (bResult)
+ if (bResult && lpProfileDir)
{
- WideCharToMultiByte(CP_ACP,
- 0,
- lpBuffer,
- -1,
- lpProfileDir,
- *lpcchSize,
- NULL,
- NULL);
+ bResult = WideCharToMultiByte(CP_ACP,
+ 0,
+ lpBuffer,
+ -1,
+ lpProfileDir,
+ *lpcchSize,
+ NULL,
+ NULL);
}
GlobalFree(lpBuffer);
BOOL
WINAPI
-GetUserProfileDirectoryW(HANDLE hToken,
- LPWSTR lpProfileDir,
- LPDWORD lpcchSize)
+GetUserProfileDirectoryW(
+ _In_ HANDLE hToken,
+ _Out_opt_ LPWSTR lpProfileDir,
+ _Inout_ LPDWORD lpcchSize)
{
UNICODE_STRING SidString;
WCHAR szKeyName[MAX_PATH];
WCHAR szRawImagePath[MAX_PATH];
WCHAR szImagePath[MAX_PATH];
- DWORD dwLength;
+ DWORD dwType, dwLength;
HKEY hKey;
LONG Error;
- if (!GetUserSidStringFromToken(hToken,
- &SidString))
+ if (!hToken)
{
- DPRINT1("GetUserSidFromToken() failed\n");
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (!lpcchSize)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* Get the user SID string */
+ if (!GetUserSidStringFromToken(hToken, &SidString))
+ {
+ DPRINT1("GetUserSidStringFromToken() failed\n");
return FALSE;
}
DPRINT("SidString: '%wZ'\n", &SidString);
- wcscpy(szKeyName,
- L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
- wcscat(szKeyName,
- SidString.Buffer);
+ StringCbCopyW(szKeyName, sizeof(szKeyName),
+ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
+ StringCbCatW(szKeyName, sizeof(szKeyName), SidString.Buffer);
RtlFreeUnicodeString(&SidString);
Error = RegQueryValueExW(hKey,
L"ProfileImagePath",
NULL,
- NULL,
+ &dwType,
(LPBYTE)szRawImagePath,
&dwLength);
- if (Error != ERROR_SUCCESS)
+ if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
/* Expand it */
if (!ExpandEnvironmentStringsW(szRawImagePath,
szImagePath,
- MAX_PATH))
+ ARRAYSIZE(szImagePath)))
{
- DPRINT1 ("Error: %lu\n", GetLastError());
+ DPRINT1("Error: %lu\n", GetLastError());
return FALSE;
}
DPRINT("ImagePath: '%S'\n", szImagePath);
- dwLength = wcslen (szImagePath) + 1;
- if (*lpcchSize < dwLength)
+ dwLength = wcslen(szImagePath) + 1;
+ if (lpProfileDir && (*lpcchSize >= dwLength))
{
+ StringCchCopyW(lpProfileDir, *lpcchSize, szImagePath);
*lpcchSize = dwLength;
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
-
- *lpcchSize = dwLength;
- wcscpy(lpProfileDir, szImagePath);
-
- return TRUE;
-}
-
-
-static
-BOOL
-CheckForLoadedProfile(HANDLE hToken)
-{
- UNICODE_STRING SidString;
- HKEY hKey;
-
- DPRINT("CheckForLoadedProfile() called\n");
-
- if (!GetUserSidStringFromToken(hToken,
- &SidString))
- {
- DPRINT1("GetUserSidFromToken() failed\n");
- return FALSE;
+ return TRUE;
}
-
- if (RegOpenKeyExW(HKEY_USERS,
- SidString.Buffer,
- 0,
- MAXIMUM_ALLOWED,
- &hKey))
+ else // if (!lpProfileDir || (*lpcchSize < dwLength))
{
- DPRINT("Profile not loaded\n");
- RtlFreeUnicodeString(&SidString);
+ *lpcchSize = dwLength;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
-
- RegCloseKey(hKey);
-
- RtlFreeUnicodeString(&SidString);
-
- DPRINT("Profile already loaded\n");
-
- return TRUE;
}
BOOL
WINAPI
-LoadUserProfileA(IN HANDLE hToken,
- IN OUT LPPROFILEINFOA lpProfileInfo)
+LoadUserProfileA(
+ _In_ HANDLE hToken,
+ _Inout_ LPPROFILEINFOA lpProfileInfo)
{
BOOL bResult = FALSE;
PROFILEINFOW ProfileInfoW = {0};
}
/* Convert the structure to UNICODE... */
- ProfileInfoW.dwSize = sizeof(PROFILEINFOW);
+ ProfileInfoW.dwSize = sizeof(ProfileInfoW);
ProfileInfoW.dwFlags = lpProfileInfo->dwFlags;
if (lpProfileInfo->lpUserName)
BOOL
WINAPI
-LoadUserProfileW(IN HANDLE hToken,
- IN OUT LPPROFILEINFOW lpProfileInfo)
+LoadUserProfileW(
+ _In_ HANDLE hToken,
+ _Inout_ LPPROFILEINFOW lpProfileInfo)
{
WCHAR szUserHivePath[MAX_PATH];
- LPWSTR UserName = NULL, Domain = NULL;
- DWORD UserNameLength = 0, DomainLength = 0;
PTOKEN_USER UserSid = NULL;
- SID_NAME_USE AccountType;
UNICODE_STRING SidString = { 0, 0, NULL };
+ HANDLE hProfileMutex = NULL;
LONG Error;
BOOL ret = FALSE;
DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
- DPRINT("LoadUserProfileW() called\n");
+ DPRINT("LoadUserProfileW(%p %p)\n", hToken, lpProfileInfo);
/* Check profile info */
if (!lpProfileInfo || (lpProfileInfo->dwSize != sizeof(PROFILEINFOW)) ||
return FALSE;
}
- /* Don't load a profile twice */
- if (CheckForLoadedProfile(hToken))
- {
- DPRINT ("Profile already loaded\n");
- lpProfileInfo->hProfile = NULL;
- return TRUE;
- }
+ DPRINT("UserName: %S\n", lpProfileInfo->lpUserName);
- if (lpProfileInfo->lpProfilePath)
+ /* Get the user SID string */
+ ret = GetUserSidStringFromToken(hToken, &SidString);
+ if (!ret)
{
- wcscpy(szUserHivePath, lpProfileInfo->lpProfilePath);
+ DPRINT1("GetUserSidStringFromToken() failed\n");
+ goto cleanup;
}
- else
+ ret = FALSE;
+
+ /* Create the profile mutex */
+ hProfileMutex = CreateProfileMutex(SidString.Buffer);
+ if (hProfileMutex == NULL)
{
- /* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
- if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
- {
- DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
- return FALSE;
- }
+ DPRINT1("Failed to create the profile mutex\n");
+ goto cleanup;
}
- /* Create user hive name */
- wcscat(szUserHivePath, L"\\");
- wcscat(szUserHivePath, lpProfileInfo->lpUserName);
- wcscat(szUserHivePath, L"\\ntuser.dat");
- DPRINT("szUserHivePath: %S\n", szUserHivePath);
+ /* Wait for the profile mutex */
+ WaitForSingleObject(hProfileMutex, INFINITE);
- /* Create user profile directory if needed */
- if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
+ /* Don't load a profile twice */
+ if (CheckForLoadedProfile(hToken))
{
- /* Get user sid */
- if (GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength) ||
- GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- {
- DPRINT1 ("GetTokenInformation() failed\n");
- return FALSE;
- }
+ DPRINT1("Profile %S already loaded\n", SidString.Buffer);
+ }
+ else
+ {
+ DPRINT1("Loading profile %S\n", SidString.Buffer);
- UserSid = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, dwLength);
- if (!UserSid)
+ if (lpProfileInfo->lpProfilePath)
{
- DPRINT1("HeapAlloc() failed\n");
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto cleanup;
+ /* Use the caller's specified roaming user profile path */
+ StringCbCopyW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpProfilePath);
}
-
- if (!GetTokenInformation(hToken, TokenUser, UserSid, dwLength, &dwLength))
+ else
{
- DPRINT1("GetTokenInformation() failed\n");
- goto cleanup;
+ /* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
+ if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
+ {
+ DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
+ goto cleanup;
+ }
}
- /* Get user name */
- do
+ /* Create user hive name */
+ StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\");
+ StringCbCatW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpUserName);
+ StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\ntuser.dat");
+ DPRINT("szUserHivePath: %S\n", szUserHivePath);
+
+ /* Create user profile directory if needed */
+ if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
{
- if (UserNameLength > 0)
+ /* Get user sid */
+ if (GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength) ||
+ GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
- HeapFree(GetProcessHeap(), 0, UserName);
- UserName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, UserNameLength * sizeof(WCHAR));
- if (!UserName)
- {
- DPRINT1("HeapAlloc() failed\n");
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto cleanup;
- }
+ DPRINT1 ("GetTokenInformation() failed\n");
+ goto cleanup;
}
- if (DomainLength > 0)
+
+ UserSid = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, dwLength);
+ if (!UserSid)
{
- HeapFree(GetProcessHeap(), 0, Domain);
- Domain = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, DomainLength * sizeof(WCHAR));
- if (!Domain)
- {
- DPRINT1("HeapAlloc() failed\n");
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto cleanup;
- }
+ DPRINT1("HeapAlloc() failed\n");
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+
+ if (!GetTokenInformation(hToken, TokenUser, UserSid, dwLength, &dwLength))
+ {
+ DPRINT1("GetTokenInformation() failed\n");
+ goto cleanup;
+ }
+
+ /* Create profile */
+ ret = CreateUserProfileW(UserSid->User.Sid, lpProfileInfo->lpUserName);
+ if (!ret)
+ {
+ DPRINT1("CreateUserProfileW() failed\n");
+ goto cleanup;
}
- ret = LookupAccountSidW(NULL,
- UserSid->User.Sid,
- UserName,
- &UserNameLength,
- Domain,
- &DomainLength,
- &AccountType);
- } while (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
-
- if (!ret)
- {
- DPRINT1("LookupAccountSidW() failed\n");
- goto cleanup;
}
- /* Create profile */
- /* FIXME: ignore Domain? */
- DPRINT("UserName %S, Domain %S\n", UserName, Domain);
- ret = CreateUserProfileW(UserSid->User.Sid, UserName);
- if (!ret)
+ /* Acquire restore privilege */
+ if (!AcquireRemoveRestorePrivilege(TRUE))
{
- DPRINT1("CreateUserProfileW() failed\n");
+ DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
goto cleanup;
}
- }
-
- /* Get user SID string */
- ret = GetUserSidStringFromToken(hToken, &SidString);
- if (!ret)
- {
- DPRINT1("GetUserSidFromToken() failed\n");
- goto cleanup;
- }
- ret = FALSE;
-
- /* Acquire restore privilege */
- if (!AcquireRemoveRestorePrivilege(TRUE))
- {
- DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
- goto cleanup;
- }
- /* Load user registry hive */
- Error = RegLoadKeyW(HKEY_USERS,
- SidString.Buffer,
- szUserHivePath);
- AcquireRemoveRestorePrivilege(FALSE);
+ /* Load user registry hive */
+ Error = RegLoadKeyW(HKEY_USERS,
+ SidString.Buffer,
+ szUserHivePath);
+ AcquireRemoveRestorePrivilege(FALSE);
- /* HACK: Do not fail if the profile has already been loaded! */
- if (Error == ERROR_SHARING_VIOLATION)
- Error = ERROR_SUCCESS;
+ /* HACK: Do not fail if the profile has already been loaded! */
+ if (Error == ERROR_SHARING_VIOLATION)
+ Error = ERROR_SUCCESS;
- if (Error != ERROR_SUCCESS)
- {
- DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
- SetLastError((DWORD)Error);
- goto cleanup;
+ if (Error != ERROR_SUCCESS)
+ {
+ DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
+ SetLastError((DWORD)Error);
+ goto cleanup;
+ }
}
/* Open future HKEY_CURRENT_USER */
goto cleanup;
}
+ Error = IncrementRefCount(SidString.Buffer, NULL);
+ if (Error != ERROR_SUCCESS)
+ {
+ DPRINT1("IncrementRefCount() failed (Error %ld)\n", Error);
+ SetLastError((DWORD)Error);
+ goto cleanup;
+ }
+
ret = TRUE;
cleanup:
- HeapFree(GetProcessHeap(), 0, UserSid);
- HeapFree(GetProcessHeap(), 0, UserName);
- HeapFree(GetProcessHeap(), 0, Domain);
+ if (UserSid != NULL)
+ HeapFree(GetProcessHeap(), 0, UserSid);
+
+ if (hProfileMutex != NULL)
+ {
+ ReleaseMutex(hProfileMutex);
+ CloseHandle(hProfileMutex);
+ }
+
RtlFreeUnicodeString(&SidString);
DPRINT("LoadUserProfileW() done\n");
BOOL
WINAPI
-UnloadUserProfile(HANDLE hToken,
- HANDLE hProfile)
+UnloadUserProfile(
+ _In_ HANDLE hToken,
+ _In_ HANDLE hProfile)
{
- UNICODE_STRING SidString;
+ UNICODE_STRING SidString = {0, 0, NULL};
+ HANDLE hProfileMutex = NULL;
+ DWORD dwRefCount = 0;
LONG Error;
+ BOOL bRet = FALSE;
DPRINT("UnloadUserProfile() called\n");
return FALSE;
}
- RegCloseKey(hProfile);
-
- if (!GetUserSidStringFromToken(hToken,
- &SidString))
+ /* Get the user SID string */
+ if (!GetUserSidStringFromToken(hToken, &SidString))
{
- DPRINT1("GetUserSidFromToken() failed\n");
+ DPRINT1("GetUserSidStringFromToken() failed\n");
return FALSE;
}
DPRINT("SidString: '%wZ'\n", &SidString);
- /* Acquire restore privilege */
- if (!AcquireRemoveRestorePrivilege(TRUE))
+ /* Create the profile mutex */
+ hProfileMutex = CreateProfileMutex(SidString.Buffer);
+ if (hProfileMutex == NULL)
{
- DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
- RtlFreeUnicodeString(&SidString);
- return FALSE;
+ DPRINT1("Failed to create the profile mutex\n");
+ goto cleanup;
}
- /* Unload the hive */
- Error = RegUnLoadKeyW(HKEY_USERS,
- SidString.Buffer);
+ /* Wait for the profile mutex */
+ WaitForSingleObject(hProfileMutex, INFINITE);
- /* Remove restore privilege */
- AcquireRemoveRestorePrivilege(FALSE);
+ /* Close the profile handle */
+ RegCloseKey(hProfile);
+ Error = DecrementRefCount(SidString.Buffer, &dwRefCount);
if (Error != ERROR_SUCCESS)
{
- DPRINT1("RegUnLoadKeyW() failed (Error %ld)\n", Error);
- RtlFreeUnicodeString(&SidString);
+ DPRINT1("DecrementRefCount() failed (Error %ld)\n", Error);
SetLastError((DWORD)Error);
- return FALSE;
+ goto cleanup;
}
- RtlFreeUnicodeString(&SidString);
-
- DPRINT("UnloadUserProfile() done\n");
-
- return TRUE;
-}
-
-
-BOOL
-WINAPI
-DeleteProfileW(LPCWSTR lpSidString,
- LPCWSTR lpProfilePath,
- LPCWSTR lpComputerName)
-{
- DPRINT1("DeleteProfileW() not implemented!\n");
- return FALSE;
-}
-
-
-BOOL
-WINAPI
-DeleteProfileA(LPCSTR lpSidString,
- LPCSTR lpProfilePath,
- LPCSTR lpComputerName)
-{
- BOOL bResult;
- UNICODE_STRING SidString, ProfilePath, ComputerName;
+ if (dwRefCount == 0)
+ {
+ DPRINT1("RefCount is 0: Unload the Hive!\n");
- DPRINT("DeleteProfileA() called\n");
+ /* Acquire restore privilege */
+ if (!AcquireRemoveRestorePrivilege(TRUE))
+ {
+ DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
+ goto cleanup;
+ }
- /* Conversion to UNICODE */
- if (lpSidString)
- RtlCreateUnicodeStringFromAsciiz(&SidString,
- (LPSTR)lpSidString);
+ /* HACK */
+ {
+ HKEY hUserKey;
+
+ Error = RegOpenKeyExW(HKEY_USERS,
+ SidString.Buffer,
+ 0,
+ KEY_WRITE,
+ &hUserKey);
+ if (Error == ERROR_SUCCESS)
+ {
+ RegDeleteKeyW(hUserKey,
+ L"Volatile Environment");
- if (lpProfilePath)
- RtlCreateUnicodeStringFromAsciiz(&ProfilePath,
- (LPSTR)lpProfilePath);
+ RegCloseKey(hUserKey);
+ }
+ }
+ /* End of HACK */
- if (lpComputerName)
- RtlCreateUnicodeStringFromAsciiz(&ComputerName,
- (LPSTR)lpComputerName);
+ /* Unload the hive */
+ Error = RegUnLoadKeyW(HKEY_USERS,
+ SidString.Buffer);
- /* Call the UNICODE function */
- bResult = DeleteProfileW(SidString.Buffer,
- ProfilePath.Buffer,
- ComputerName.Buffer);
+ /* Remove restore privilege */
+ AcquireRemoveRestorePrivilege(FALSE);
- /* Memory cleanup */
- if (lpSidString)
- RtlFreeUnicodeString(&SidString);
+ if (Error != ERROR_SUCCESS)
+ {
+ DPRINT1("RegUnLoadKeyW() failed (Error %ld)\n", Error);
+ SetLastError((DWORD)Error);
+ goto cleanup;
+ }
+ }
- if (lpProfilePath)
- RtlFreeUnicodeString(&ProfilePath);
+ bRet = TRUE;
- if (lpComputerName)
- RtlFreeUnicodeString(&ComputerName);
+cleanup:
+ if (hProfileMutex != NULL)
+ {
+ ReleaseMutex(hProfileMutex);
+ CloseHandle(hProfileMutex);
+ }
- return bResult;
-}
+ RtlFreeUnicodeString(&SidString);
+ DPRINT("UnloadUserProfile() done\n");
-BOOL
-WINAPI
-GetProfileType(OUT PDWORD pdwFlags)
-{
- DPRINT1("GetProfileType() not implemented!\n");
- return FALSE;
+ return bRet;
}
/* EOF */