-/* $Id: profile.c,v 1.4 2004/01/23 10:39:22 ekohl Exp $
+/*
+ * ReactOS kernel
+ * Copyright (C) 2004 ReactOS Team
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: profile.c,v 1.15 2004/10/05 13:39:42 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PROGRAMMER: Eric Kohl
*/
-#include <ntos.h>
-#include <windows.h>
-#include <string.h>
-
-#include <userenv.h>
-
-#include "internal.h"
+#include "precomp.h"
/* FUNCTIONS ***************************************************************/
DWORD dwMaxLength)
{
WCHAR szSystemRoot[MAX_PATH];
- WCHAR szDrivePostfix[3];
LPWSTR lpszPostfix;
LPWSTR lpszPtr;
- DWORD dwPostfixLength;
/* Build profile name postfix */
if (!ExpandEnvironmentStringsW (L"%SystemRoot%",
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)
+ if (wcslen(lpName) + wcslen(lpszPostfix) >= dwMaxLength)
{
DPRINT1("Error: buffer overflow\n");
return FALSE;
}
- wcscat (lpName, lpszPostfix);
- if (szSystemRoot[0] != L'C')
+ wcscat(lpName, lpszPostfix);
+
+ return TRUE;
+}
+
+
+BOOL WINAPI
+CreateUserProfileA (PSID Sid,
+ LPCSTR lpUserName)
+{
+ UNICODE_STRING UserName;
+ BOOL bResult;
+ NTSTATUS Status;
+
+ Status = RtlCreateUnicodeStringFromAsciiz (&UserName,
+ (LPSTR)lpUserName);
+ if (!NT_SUCCESS(Status))
{
- wcscat (lpName, szDrivePostfix);
+ SetLastError (RtlNtStatusToDosError (Status));
+ return FALSE;
}
- return TRUE;
+ bResult = CreateUserProfileW (Sid,
+ UserName.Buffer);
+
+ RtlFreeUnicodeString (&UserName);
+
+ return bResult;
}
HKEY hKey;
NTSTATUS Status;
+ DPRINT("CreateUserProfileW() called\n");
if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
RegCloseKey (hKey);
/* Create user hive name */
- wcscat (szUserProfilePath, L"\\ntuser.dat");
+ wcscpy (szBuffer, szUserProfilePath);
+ wcscat (szBuffer, L"\\ntuser.dat");
/* Create new user hive */
if (RegLoadKeyW (HKEY_USERS,
SidString.Buffer,
- szUserProfilePath))
+ szBuffer))
{
DPRINT1("Error: %lu\n", GetLastError());
RtlFreeUnicodeString (&SidString);
}
/* Initialize user hive */
- if (!CreateUserHive (SidString.Buffer))
+ if (!CreateUserHive (SidString.Buffer, szUserProfilePath))
{
DPRINT1("Error: %lu\n", GetLastError());
RtlFreeUnicodeString (&SidString);
RtlFreeUnicodeString (&SidString);
+ DPRINT("CreateUserProfileW() done\n");
+
return TRUE;
}
+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;
+}
+
+
BOOL WINAPI
GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir,
LPDWORD lpcchSize)
}
+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;
+}
+
+
BOOL WINAPI
GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir,
LPDWORD lpcchSize)
}
+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;
+}
+
+
BOOL WINAPI
GetProfilesDirectoryW (LPWSTR lpProfilesDir,
LPDWORD lpcchSize)
}
+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;
+}
+
+
BOOL WINAPI
GetUserProfileDirectoryW (HANDLE hToken,
LPWSTR lpProfileDir,
LPDWORD lpcchSize)
{
- /* FIXME */
- return GetDefaultUserProfileDirectoryW (lpProfileDir, lpcchSize);
+ 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;
+}
+
+
+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;
+}
+
+
+BOOL WINAPI
+LoadUserProfileA (HANDLE hToken,
+ LPPROFILEINFOA lpProfileInfo)
+{
+ DPRINT ("LoadUserProfileA() not implemented\n");
+ return FALSE;
+}
+
+
+BOOL WINAPI
+LoadUserProfileW (HANDLE hToken,
+ LPPROFILEINFOW lpProfileInfo)
+{
+ WCHAR szUserHivePath[MAX_PATH];
+ UNICODE_STRING SidString;
+ DWORD dwLength;
+
+ DPRINT ("LoadUserProfileW() called\n");
+
+ /* Check profile info */
+ if (lpProfileInfo->dwSize != sizeof(PROFILEINFOW) ||
+ lpProfileInfo->lpUserName == NULL ||
+ lpProfileInfo->lpUserName[0] == 0)
+ {
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* Don't load a profile twice */
+ if (CheckForLoadedProfile (hToken))
+ {
+ DPRINT ("Profile already loaded\n");
+ lpProfileInfo->hProfile = NULL;
+ return TRUE;
+ }
+
+ if (!GetProfilesDirectoryW (szUserHivePath,
+ &dwLength))
+ {
+ DPRINT1("GetProfilesDirectoryW() failed\n", GetLastError());
+ 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;
+ }
+
+ if (RegOpenKeyExW (HKEY_USERS,
+ SidString.Buffer,
+ 0,
+ KEY_ALL_ACCESS,
+ (PHKEY)&lpProfileInfo->hProfile))
+ {
+ DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
+ RtlFreeUnicodeString (&SidString);
+ return FALSE;
+ }
+
+ RtlFreeUnicodeString (&SidString);
+
+ DPRINT ("LoadUserProfileW() done\n");
+
+ return TRUE;
+}
+
+
+BOOL WINAPI
+UnloadUserProfile (HANDLE hToken,
+ HANDLE hProfile)
+{
+ UNICODE_STRING SidString;
+
+ DPRINT ("UnloadUserProfile() called\n");
+
+ if (hProfile == NULL)
+ {
+ DPRINT1 ("Invalide profile handle\n");
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ RegCloseKey (hProfile);
+
+ 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");
+
+ return TRUE;
}
/* EOF */