2004-08-15 19:02:40 +00:00
|
|
|
/* $Id: profile.c,v 1.12 2004/08/15 19:02:40 chorns Exp $
|
2004-01-13 12:34:09 +00:00
|
|
|
*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS system libraries
|
|
|
|
* FILE: lib/userenv/profile.c
|
|
|
|
* PURPOSE: User profile code
|
|
|
|
* PROGRAMMER: Eric Kohl
|
|
|
|
*/
|
|
|
|
|
2004-08-15 19:02:40 +00:00
|
|
|
#include "precomp.h"
|
2004-01-13 12:34:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
|
2004-01-16 15:31:53 +00:00
|
|
|
BOOL
|
|
|
|
AppendSystemPostfix (LPWSTR lpName,
|
|
|
|
DWORD dwMaxLength)
|
|
|
|
{
|
|
|
|
WCHAR szSystemRoot[MAX_PATH];
|
|
|
|
WCHAR szDrivePostfix[3];
|
|
|
|
LPWSTR lpszPostfix;
|
|
|
|
LPWSTR lpszPtr;
|
|
|
|
DWORD dwPostfixLength;
|
|
|
|
|
|
|
|
/* Build profile name postfix */
|
|
|
|
if (!ExpandEnvironmentStringsW (L"%SystemRoot%",
|
|
|
|
szSystemRoot,
|
|
|
|
MAX_PATH))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
_wcsupr (szSystemRoot);
|
|
|
|
|
|
|
|
/* Get name postfix */
|
|
|
|
szSystemRoot[2] = L'.';
|
|
|
|
lpszPostfix = &szSystemRoot[2];
|
|
|
|
lpszPtr = lpszPostfix;
|
|
|
|
while (*lpszPtr != (WCHAR)0)
|
|
|
|
{
|
|
|
|
if (*lpszPtr == L'\\')
|
|
|
|
*lpszPtr = '_';
|
|
|
|
lpszPtr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
dwPostfixLength = wcslen (lpszPostfix);
|
|
|
|
if (szSystemRoot[0] != L'C')
|
|
|
|
{
|
|
|
|
dwPostfixLength += 2;
|
|
|
|
szDrivePostfix[0] = L'_';
|
|
|
|
szDrivePostfix[1] = szSystemRoot[0];
|
|
|
|
szDrivePostfix[2] = (WCHAR)0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wcslen (lpName) + dwPostfixLength >= dwMaxLength)
|
|
|
|
{
|
|
|
|
DPRINT1("Error: buffer overflow\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
wcscat (lpName, lpszPostfix);
|
|
|
|
if (szSystemRoot[0] != L'C')
|
|
|
|
{
|
|
|
|
wcscat (lpName, szDrivePostfix);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-19 10:51:17 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
CreateUserProfileA (PSID Sid,
|
|
|
|
LPCSTR lpUserName)
|
|
|
|
{
|
|
|
|
UNICODE_STRING UserName;
|
|
|
|
BOOL bResult;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = RtlCreateUnicodeStringFromAsciiz (&UserName,
|
|
|
|
(LPSTR)lpUserName);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastError (RtlNtStatusToDosError (Status));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bResult = CreateUserProfileW (Sid,
|
|
|
|
UserName.Buffer);
|
|
|
|
|
|
|
|
RtlFreeUnicodeString (&UserName);
|
|
|
|
|
|
|
|
return bResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-13 12:34:09 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
CreateUserProfileW (PSID Sid,
|
|
|
|
LPCWSTR lpUserName)
|
|
|
|
{
|
2004-01-15 14:59:06 +00:00
|
|
|
WCHAR szRawProfilesPath[MAX_PATH];
|
|
|
|
WCHAR szProfilesPath[MAX_PATH];
|
|
|
|
WCHAR szUserProfilePath[MAX_PATH];
|
|
|
|
WCHAR szDefaultUserPath[MAX_PATH];
|
|
|
|
WCHAR szBuffer[MAX_PATH];
|
|
|
|
UNICODE_STRING SidString;
|
|
|
|
DWORD dwLength;
|
|
|
|
DWORD dwDisposition;
|
|
|
|
HKEY hKey;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2004-02-28 11:30:59 +00:00
|
|
|
DPRINT ("CreateUserProfileW() called\n");
|
2004-01-15 14:59:06 +00:00
|
|
|
|
|
|
|
if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
|
|
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
|
|
|
|
0,
|
|
|
|
KEY_ALL_ACCESS,
|
|
|
|
&hKey))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get profiles path */
|
|
|
|
dwLength = MAX_PATH * sizeof(WCHAR);
|
|
|
|
if (RegQueryValueExW (hKey,
|
|
|
|
L"ProfilesDirectory",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(LPBYTE)szRawProfilesPath,
|
|
|
|
&dwLength))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Expand it */
|
|
|
|
if (!ExpandEnvironmentStringsW (szRawProfilesPath,
|
|
|
|
szProfilesPath,
|
|
|
|
MAX_PATH))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get default user path */
|
|
|
|
dwLength = MAX_PATH * sizeof(WCHAR);
|
|
|
|
if (RegQueryValueExW (hKey,
|
|
|
|
L"DefaultUserProfile",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(LPBYTE)szBuffer,
|
|
|
|
&dwLength))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
|
|
|
|
wcscpy (szUserProfilePath, szProfilesPath);
|
|
|
|
wcscat (szUserProfilePath, L"\\");
|
|
|
|
wcscat (szUserProfilePath, lpUserName);
|
2004-01-16 15:31:53 +00:00
|
|
|
if (!AppendSystemPostfix (szUserProfilePath, MAX_PATH))
|
|
|
|
{
|
|
|
|
DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-01-15 14:59:06 +00:00
|
|
|
|
|
|
|
wcscpy (szDefaultUserPath, szProfilesPath);
|
|
|
|
wcscat (szDefaultUserPath, L"\\");
|
|
|
|
wcscat (szDefaultUserPath, szBuffer);
|
|
|
|
|
|
|
|
/* Create user profile directory */
|
|
|
|
if (!CreateDirectoryW (szUserProfilePath, NULL))
|
|
|
|
{
|
|
|
|
if (GetLastError () != ERROR_ALREADY_EXISTS)
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy default user directory */
|
|
|
|
if (!CopyDirectory (szUserProfilePath, szDefaultUserPath))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add profile to profile list */
|
|
|
|
Status = RtlConvertSidToUnicodeString (&SidString, Sid, TRUE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Status: %lx\n", Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
wcscpy (szBuffer,
|
|
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
|
|
|
|
wcscat (szBuffer, SidString.Buffer);
|
|
|
|
|
|
|
|
/* Create user profile key */
|
|
|
|
if (RegCreateKeyExW (HKEY_LOCAL_MACHINE,
|
|
|
|
szBuffer,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
REG_OPTION_NON_VOLATILE,
|
|
|
|
KEY_ALL_ACCESS,
|
|
|
|
NULL,
|
|
|
|
&hKey,
|
|
|
|
&dwDisposition))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create non-expanded user profile path */
|
|
|
|
wcscpy (szBuffer, szRawProfilesPath);
|
|
|
|
wcscat (szBuffer, L"\\");
|
|
|
|
wcscat (szBuffer, lpUserName);
|
2004-01-16 15:31:53 +00:00
|
|
|
if (!AppendSystemPostfix (szBuffer, MAX_PATH))
|
|
|
|
{
|
|
|
|
DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-01-15 14:59:06 +00:00
|
|
|
|
|
|
|
/* Set 'ProfileImagePath' value (non-expanded) */
|
|
|
|
if (RegSetValueExW (hKey,
|
|
|
|
L"ProfileImagePath",
|
|
|
|
0,
|
|
|
|
REG_EXPAND_SZ,
|
|
|
|
(LPBYTE)szBuffer,
|
|
|
|
(wcslen (szBuffer) + 1) * sizeof(WCHAR)))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set 'Sid' value */
|
|
|
|
if (RegSetValueExW (hKey,
|
|
|
|
L"Sid",
|
|
|
|
0,
|
|
|
|
REG_BINARY,
|
|
|
|
Sid,
|
|
|
|
RtlLengthSid (Sid)))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
|
|
|
|
/* Create user hive name */
|
|
|
|
wcscat (szUserProfilePath, L"\\ntuser.dat");
|
|
|
|
|
|
|
|
/* Create new user hive */
|
|
|
|
if (RegLoadKeyW (HKEY_USERS,
|
|
|
|
SidString.Buffer,
|
|
|
|
szUserProfilePath))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-01-23 10:39:22 +00:00
|
|
|
/* Initialize user hive */
|
2004-01-16 15:31:53 +00:00
|
|
|
if (!CreateUserHive (SidString.Buffer))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-01-15 14:59:06 +00:00
|
|
|
|
|
|
|
RegUnLoadKeyW (HKEY_USERS,
|
|
|
|
SidString.Buffer);
|
|
|
|
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
|
2004-02-28 11:30:59 +00:00
|
|
|
DPRINT ("CreateUserProfileW() done\n");
|
|
|
|
|
2004-01-13 12:34:09 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-03 12:05:44 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
GetAllUsersProfileDirectoryA (LPSTR lpProfileDir,
|
|
|
|
LPDWORD lpcchSize)
|
|
|
|
{
|
|
|
|
LPWSTR lpBuffer;
|
|
|
|
BOOL bResult;
|
|
|
|
|
|
|
|
lpBuffer = GlobalAlloc (GMEM_FIXED,
|
|
|
|
*lpcchSize * sizeof(WCHAR));
|
|
|
|
if (lpBuffer == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
bResult = GetAllUsersProfileDirectoryW (lpBuffer,
|
|
|
|
lpcchSize);
|
|
|
|
if (bResult)
|
|
|
|
{
|
|
|
|
WideCharToMultiByte (CP_ACP,
|
|
|
|
0,
|
|
|
|
lpBuffer,
|
|
|
|
-1,
|
|
|
|
lpProfileDir,
|
|
|
|
*lpcchSize,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalFree (lpBuffer);
|
|
|
|
|
|
|
|
return bResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-13 12:34:09 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir,
|
|
|
|
LPDWORD lpcchSize)
|
|
|
|
{
|
|
|
|
WCHAR szProfilePath[MAX_PATH];
|
|
|
|
WCHAR szBuffer[MAX_PATH];
|
|
|
|
DWORD dwLength;
|
|
|
|
HKEY hKey;
|
|
|
|
|
|
|
|
if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
|
|
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
|
|
|
|
0,
|
|
|
|
KEY_READ,
|
|
|
|
&hKey))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get profiles path */
|
|
|
|
dwLength = MAX_PATH * sizeof(WCHAR);
|
|
|
|
if (RegQueryValueExW (hKey,
|
|
|
|
L"ProfilesDirectory",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(LPBYTE)szBuffer,
|
|
|
|
&dwLength))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Expand it */
|
|
|
|
if (!ExpandEnvironmentStringsW (szBuffer,
|
|
|
|
szProfilePath,
|
|
|
|
MAX_PATH))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get 'AllUsersProfile' name */
|
|
|
|
dwLength = MAX_PATH * sizeof(WCHAR);
|
|
|
|
if (RegQueryValueExW (hKey,
|
|
|
|
L"AllUsersProfile",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(LPBYTE)szBuffer,
|
|
|
|
&dwLength))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
|
|
|
|
wcscat (szProfilePath, L"\\");
|
|
|
|
wcscat (szProfilePath, szBuffer);
|
|
|
|
|
|
|
|
dwLength = wcslen (szProfilePath);
|
|
|
|
if (lpProfileDir != NULL)
|
|
|
|
{
|
|
|
|
if (*lpcchSize < dwLength)
|
|
|
|
{
|
|
|
|
*lpcchSize = dwLength;
|
|
|
|
SetLastError (ERROR_INSUFFICIENT_BUFFER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
wcscpy (lpProfileDir, szProfilePath);
|
|
|
|
}
|
|
|
|
|
|
|
|
*lpcchSize = dwLength;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-03 12:05:44 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
GetDefaultUserProfileDirectoryA (LPSTR lpProfileDir,
|
|
|
|
LPDWORD lpcchSize)
|
|
|
|
{
|
|
|
|
LPWSTR lpBuffer;
|
|
|
|
BOOL bResult;
|
|
|
|
|
|
|
|
lpBuffer = GlobalAlloc (GMEM_FIXED,
|
|
|
|
*lpcchSize * sizeof(WCHAR));
|
|
|
|
if (lpBuffer == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
bResult = GetDefaultUserProfileDirectoryW (lpBuffer,
|
|
|
|
lpcchSize);
|
|
|
|
if (bResult)
|
|
|
|
{
|
|
|
|
WideCharToMultiByte (CP_ACP,
|
|
|
|
0,
|
|
|
|
lpBuffer,
|
|
|
|
-1,
|
|
|
|
lpProfileDir,
|
|
|
|
*lpcchSize,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalFree (lpBuffer);
|
|
|
|
|
|
|
|
return bResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-13 12:34:09 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir,
|
|
|
|
LPDWORD lpcchSize)
|
|
|
|
{
|
|
|
|
WCHAR szProfilePath[MAX_PATH];
|
|
|
|
WCHAR szBuffer[MAX_PATH];
|
|
|
|
DWORD dwLength;
|
|
|
|
HKEY hKey;
|
|
|
|
|
|
|
|
if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
|
|
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
|
|
|
|
0,
|
|
|
|
KEY_READ,
|
|
|
|
&hKey))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get profiles path */
|
|
|
|
dwLength = MAX_PATH * sizeof(WCHAR);
|
|
|
|
if (RegQueryValueExW (hKey,
|
|
|
|
L"ProfilesDirectory",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(LPBYTE)szBuffer,
|
|
|
|
&dwLength))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Expand it */
|
|
|
|
if (!ExpandEnvironmentStringsW (szBuffer,
|
|
|
|
szProfilePath,
|
|
|
|
MAX_PATH))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get 'DefaultUserProfile' name */
|
|
|
|
dwLength = MAX_PATH * sizeof(WCHAR);
|
|
|
|
if (RegQueryValueExW (hKey,
|
|
|
|
L"DefaultUserProfile",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(LPBYTE)szBuffer,
|
|
|
|
&dwLength))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
|
|
|
|
wcscat (szProfilePath, L"\\");
|
|
|
|
wcscat (szProfilePath, szBuffer);
|
|
|
|
|
|
|
|
dwLength = wcslen (szProfilePath);
|
|
|
|
if (lpProfileDir != NULL)
|
|
|
|
{
|
|
|
|
if (*lpcchSize < dwLength)
|
|
|
|
{
|
|
|
|
*lpcchSize = dwLength;
|
|
|
|
SetLastError (ERROR_INSUFFICIENT_BUFFER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
wcscpy (lpProfileDir, szProfilePath);
|
|
|
|
}
|
|
|
|
|
|
|
|
*lpcchSize = dwLength;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-03 12:05:44 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
GetProfilesDirectoryA (LPSTR lpProfileDir,
|
|
|
|
LPDWORD lpcchSize)
|
|
|
|
{
|
|
|
|
LPWSTR lpBuffer;
|
|
|
|
BOOL bResult;
|
|
|
|
|
|
|
|
lpBuffer = GlobalAlloc (GMEM_FIXED,
|
|
|
|
*lpcchSize * sizeof(WCHAR));
|
|
|
|
if (lpBuffer == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
bResult = GetProfilesDirectoryW (lpBuffer,
|
|
|
|
lpcchSize);
|
|
|
|
if (bResult)
|
|
|
|
{
|
|
|
|
WideCharToMultiByte (CP_ACP,
|
|
|
|
0,
|
|
|
|
lpBuffer,
|
|
|
|
-1,
|
|
|
|
lpProfileDir,
|
|
|
|
*lpcchSize,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalFree (lpBuffer);
|
|
|
|
|
|
|
|
return bResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-13 12:34:09 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
GetProfilesDirectoryW (LPWSTR lpProfilesDir,
|
|
|
|
LPDWORD lpcchSize)
|
|
|
|
{
|
|
|
|
WCHAR szProfilesPath[MAX_PATH];
|
|
|
|
WCHAR szBuffer[MAX_PATH];
|
|
|
|
DWORD dwLength;
|
|
|
|
HKEY hKey;
|
|
|
|
|
|
|
|
if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
|
|
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
|
|
|
|
0,
|
|
|
|
KEY_READ,
|
|
|
|
&hKey))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-01-15 14:59:06 +00:00
|
|
|
/* Get profiles path */
|
2004-01-13 12:34:09 +00:00
|
|
|
dwLength = MAX_PATH * sizeof(WCHAR);
|
|
|
|
if (RegQueryValueExW (hKey,
|
|
|
|
L"ProfilesDirectory",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(LPBYTE)szBuffer,
|
|
|
|
&dwLength))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
|
2004-01-15 14:59:06 +00:00
|
|
|
/* Expand it */
|
2004-01-13 12:34:09 +00:00
|
|
|
if (!ExpandEnvironmentStringsW (szBuffer,
|
|
|
|
szProfilesPath,
|
|
|
|
MAX_PATH))
|
|
|
|
{
|
|
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
dwLength = wcslen (szProfilesPath);
|
|
|
|
if (lpProfilesDir != NULL)
|
|
|
|
{
|
|
|
|
if (*lpcchSize < dwLength)
|
|
|
|
{
|
|
|
|
*lpcchSize = dwLength;
|
|
|
|
SetLastError (ERROR_INSUFFICIENT_BUFFER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
wcscpy (lpProfilesDir, szProfilesPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
*lpcchSize = dwLength;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-03 12:05:44 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
GetUserProfileDirectoryA (HANDLE hToken,
|
|
|
|
LPSTR lpProfileDir,
|
|
|
|
LPDWORD lpcchSize)
|
|
|
|
{
|
|
|
|
LPWSTR lpBuffer;
|
|
|
|
BOOL bResult;
|
|
|
|
|
|
|
|
lpBuffer = GlobalAlloc (GMEM_FIXED,
|
|
|
|
*lpcchSize * sizeof(WCHAR));
|
|
|
|
if (lpBuffer == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
bResult = GetUserProfileDirectoryW (hToken,
|
|
|
|
lpBuffer,
|
|
|
|
lpcchSize);
|
|
|
|
if (bResult)
|
|
|
|
{
|
|
|
|
WideCharToMultiByte (CP_ACP,
|
|
|
|
0,
|
|
|
|
lpBuffer,
|
|
|
|
-1,
|
|
|
|
lpProfileDir,
|
|
|
|
*lpcchSize,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalFree (lpBuffer);
|
|
|
|
|
|
|
|
return bResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-13 12:34:09 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
GetUserProfileDirectoryW (HANDLE hToken,
|
|
|
|
LPWSTR lpProfileDir,
|
|
|
|
LPDWORD lpcchSize)
|
|
|
|
{
|
2004-03-14 18:15:59 +00:00
|
|
|
UNICODE_STRING SidString;
|
|
|
|
WCHAR szKeyName[MAX_PATH];
|
|
|
|
WCHAR szRawImagePath[MAX_PATH];
|
|
|
|
WCHAR szImagePath[MAX_PATH];
|
|
|
|
DWORD dwLength;
|
|
|
|
HKEY hKey;
|
|
|
|
|
|
|
|
if (!GetUserSidFromToken (hToken,
|
|
|
|
&SidString))
|
|
|
|
{
|
|
|
|
DPRINT1 ("GetUserSidFromToken() failed\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT ("SidString: '%wZ'\n", &SidString);
|
|
|
|
|
|
|
|
wcscpy (szKeyName,
|
|
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
|
|
|
|
wcscat (szKeyName,
|
|
|
|
SidString.Buffer);
|
|
|
|
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
|
|
|
|
DPRINT ("KeyName: '%S'\n", szKeyName);
|
|
|
|
|
|
|
|
if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
|
|
|
|
szKeyName,
|
|
|
|
0,
|
|
|
|
KEY_ALL_ACCESS,
|
|
|
|
&hKey))
|
|
|
|
{
|
|
|
|
DPRINT1 ("Error: %lu\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
dwLength = MAX_PATH * sizeof(WCHAR);
|
|
|
|
if (RegQueryValueExW (hKey,
|
|
|
|
L"ProfileImagePath",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(LPBYTE)szRawImagePath,
|
|
|
|
&dwLength))
|
|
|
|
{
|
|
|
|
DPRINT1 ("Error: %lu\n", GetLastError());
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
|
|
|
|
DPRINT ("RawImagePath: '%S'\n", szRawImagePath);
|
|
|
|
|
|
|
|
/* Expand it */
|
|
|
|
if (!ExpandEnvironmentStringsW (szRawImagePath,
|
|
|
|
szImagePath,
|
|
|
|
MAX_PATH))
|
|
|
|
{
|
|
|
|
DPRINT1 ("Error: %lu\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT ("ImagePath: '%S'\n", szImagePath);
|
|
|
|
|
|
|
|
dwLength = wcslen (szImagePath);
|
|
|
|
if (dwLength > *lpcchSize)
|
|
|
|
{
|
|
|
|
DPRINT1 ("Buffer too small\n");
|
|
|
|
SetLastError (ERROR_INSUFFICIENT_BUFFER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
*lpcchSize = dwLength;
|
|
|
|
wcscpy (lpProfileDir,
|
|
|
|
szImagePath);
|
|
|
|
|
|
|
|
return TRUE;
|
2004-03-17 14:46:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static BOOL
|
|
|
|
CheckForLoadedProfile (HANDLE hToken)
|
|
|
|
{
|
|
|
|
UNICODE_STRING SidString;
|
|
|
|
HKEY hKey;
|
|
|
|
|
|
|
|
DPRINT ("CheckForLoadedProfile() called \n");
|
|
|
|
|
|
|
|
if (!GetUserSidFromToken (hToken,
|
|
|
|
&SidString))
|
|
|
|
{
|
|
|
|
DPRINT1 ("GetUserSidFromToken() failed\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (RegOpenKeyExW (HKEY_USERS,
|
|
|
|
SidString.Buffer,
|
|
|
|
0,
|
|
|
|
KEY_ALL_ACCESS,
|
|
|
|
&hKey))
|
|
|
|
{
|
|
|
|
DPRINT ("Profile not loaded\n");
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
|
|
|
|
DPRINT ("Profile already loaded\n");
|
|
|
|
|
|
|
|
return TRUE;
|
2004-01-13 12:34:09 +00:00
|
|
|
}
|
|
|
|
|
2004-02-28 11:30:59 +00:00
|
|
|
|
2004-04-29 14:41:26 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
LoadUserProfileA (HANDLE hToken,
|
|
|
|
LPPROFILEINFOA lpProfileInfo)
|
|
|
|
{
|
|
|
|
DPRINT ("LoadUserProfileA() not implemented\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-28 11:30:59 +00:00
|
|
|
BOOL WINAPI
|
|
|
|
LoadUserProfileW (HANDLE hToken,
|
|
|
|
LPPROFILEINFOW lpProfileInfo)
|
|
|
|
{
|
2004-03-13 20:49:07 +00:00
|
|
|
WCHAR szUserHivePath[MAX_PATH];
|
|
|
|
UNICODE_STRING SidString;
|
|
|
|
DWORD dwLength;
|
|
|
|
|
|
|
|
DPRINT ("LoadUserProfileW() called\n");
|
2004-02-28 11:30:59 +00:00
|
|
|
|
|
|
|
/* Check profile info */
|
|
|
|
if (lpProfileInfo->dwSize != sizeof(PROFILEINFOW) ||
|
|
|
|
lpProfileInfo->lpUserName == NULL ||
|
|
|
|
lpProfileInfo->lpUserName[0] == 0)
|
|
|
|
{
|
|
|
|
SetLastError (ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-03-17 14:46:23 +00:00
|
|
|
/* Don't load a profile twice */
|
|
|
|
if (CheckForLoadedProfile (hToken))
|
2004-03-13 20:49:07 +00:00
|
|
|
{
|
2004-03-17 14:46:23 +00:00
|
|
|
DPRINT ("Profile already loaded\n");
|
|
|
|
lpProfileInfo->hProfile = NULL;
|
|
|
|
return TRUE;
|
2004-03-13 20:49:07 +00:00
|
|
|
}
|
|
|
|
|
2004-03-17 14:46:23 +00:00
|
|
|
if (!GetProfilesDirectoryW (szUserHivePath,
|
|
|
|
&dwLength))
|
2004-03-13 20:49:07 +00:00
|
|
|
{
|
2004-03-17 14:46:23 +00:00
|
|
|
DPRINT1("GetProfilesDirectoryW() failed\n", GetLastError());
|
2004-03-13 20:49:07 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
wcscat (szUserHivePath, L"\\");
|
|
|
|
wcscat (szUserHivePath, lpProfileInfo->lpUserName);
|
|
|
|
if (!AppendSystemPostfix (szUserHivePath, MAX_PATH))
|
|
|
|
{
|
|
|
|
DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create user hive name */
|
|
|
|
wcscat (szUserHivePath, L"\\ntuser.dat");
|
|
|
|
|
|
|
|
DPRINT ("szUserHivePath: %S\n", szUserHivePath);
|
|
|
|
|
|
|
|
if (!GetUserSidFromToken (hToken,
|
|
|
|
&SidString))
|
|
|
|
{
|
|
|
|
DPRINT1 ("GetUserSidFromToken() failed\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT ("SidString: '%wZ'\n", &SidString);
|
|
|
|
|
|
|
|
if (RegLoadKeyW (HKEY_USERS,
|
|
|
|
SidString.Buffer,
|
|
|
|
szUserHivePath))
|
|
|
|
{
|
|
|
|
DPRINT1 ("RegLoadKeyW() failed (Error %ld)\n", GetLastError());
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-03-14 18:15:59 +00:00
|
|
|
if (RegOpenKeyExW (HKEY_USERS,
|
|
|
|
SidString.Buffer,
|
|
|
|
0,
|
|
|
|
KEY_ALL_ACCESS,
|
|
|
|
(PHKEY)&lpProfileInfo->hProfile))
|
|
|
|
{
|
|
|
|
DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-03-13 20:49:07 +00:00
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
|
|
|
|
DPRINT ("LoadUserProfileW() done\n");
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI
|
|
|
|
UnloadUserProfile (HANDLE hToken,
|
|
|
|
HANDLE hProfile)
|
|
|
|
{
|
|
|
|
UNICODE_STRING SidString;
|
|
|
|
|
|
|
|
DPRINT ("UnloadUserProfile() called\n");
|
|
|
|
|
2004-03-14 18:15:59 +00:00
|
|
|
if (hProfile == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1 ("Invalide profile handle\n");
|
|
|
|
SetLastError (ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey (hProfile);
|
|
|
|
|
2004-03-13 20:49:07 +00:00
|
|
|
if (!GetUserSidFromToken (hToken,
|
|
|
|
&SidString))
|
|
|
|
{
|
|
|
|
DPRINT1 ("GetUserSidFromToken() failed\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT ("SidString: '%wZ'\n", &SidString);
|
|
|
|
|
|
|
|
if (RegUnLoadKeyW (HKEY_USERS,
|
|
|
|
SidString.Buffer))
|
|
|
|
{
|
|
|
|
DPRINT1 ("RegUnLoadKeyW() failed (Error %ld)\n", GetLastError());
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RtlFreeUnicodeString (&SidString);
|
|
|
|
|
|
|
|
DPRINT ("UnloadUserProfile() done\n");
|
2004-02-28 11:30:59 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2004-01-13 12:34:09 +00:00
|
|
|
/* EOF */
|