723 lines
19 KiB
C
723 lines
19 KiB
C
/** Module Header **\
|
|
* Module Name: upesave.c
|
|
|
|
* Copyright (c) 1992, Microsoft Corporation
|
|
|
|
* Handles OPening and saving of Profiles: default, system, current and user
|
|
* profiles.
|
|
|
|
* History:
|
|
* 11-20-92 JohanneC Created.
|
|
*/
|
|
|
|
//#define UNICODE 1
|
|
|
|
#ifndef RC_INVOKED
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#endif
|
|
#include "upedit.h"
|
|
|
|
|
|
#define SYSTEM_DEFAULT_SUBKEY TEXT(".DEFAULT")
|
|
#define TEMP_USER_SUBKEY TEXT("TEMP_USER")
|
|
#define TEMP_USER_HIVE_PATH TEXT("%systemroot%\\system32\\config\\")
|
|
#define TEMP_SAVE_HIVE TEXT("%systemroot%\\system32\\config\\HiveSave")
|
|
#define USERDEF_HIVE TEXT("%systemroot%\\system32\\config\\USERDEF")
|
|
#define USERDEF_TEMP_HIVE TEXT("%systemroot%\\system32\\config\\USERTMP")
|
|
#define SYSTEM_DEFAULT_HIVE TEXT("%systemroot%\\system32\\config\\DEFAULT")
|
|
#define SYSTEM_TEMP_HIVE TEXT("%systemroot%\\system32\\config\\SYSTMP")
|
|
|
|
LPTSTR lpTempUserHive = NULL;
|
|
LPTSTR lpTempUserHivePath = NULL;
|
|
LPTSTR lpTempHiveKey;
|
|
extern TCHAR szDefExt[];
|
|
extern PSID gSystemSid;
|
|
|
|
BOOL AllocAndExpandEnvironmentStrings(LPTSTR String, LPTSTR *lpExpandedString);
|
|
VOID GetRegistryKeyFromPath(LPTSTR lpPath, LPTSTR *lpKey);
|
|
|
|
/*
|
|
* ClearTempUserProfile
|
|
|
|
* Purpose : unloads the temp user profile loaded from a file, and deletes
|
|
* the temp file
|
|
|
|
* History:
|
|
* 11-20-92 JohanneC Created.
|
|
*/
|
|
BOOL APIENTRY ClearTempUserProfile()
|
|
{
|
|
BOOL bRet;
|
|
|
|
if (hkeyCurrentUser == HKEY_CURRENT_USER)
|
|
return(TRUE);
|
|
|
|
|
|
// Close registry keys.
|
|
|
|
if (hkeyPMSettings) {
|
|
RegCloseKey(hkeyPMSettings);
|
|
}
|
|
if (hkeyPMRestrict) {
|
|
RegCloseKey(hkeyPMRestrict);
|
|
}
|
|
if (hkeyProgramManager) {
|
|
RegCloseKey(hkeyProgramManager);
|
|
}
|
|
if (hkeyProgramGroups) {
|
|
RegCloseKey(hkeyProgramGroups);
|
|
}
|
|
if (hkeyCurrentUser) {
|
|
RegCloseKey(hkeyCurrentUser);
|
|
}
|
|
|
|
hkeyCurrentUser = HKEY_CURRENT_USER;
|
|
|
|
bRet = (RegUnLoadKey(HKEY_USERS, lpTempHiveKey) == ERROR_SUCCESS);
|
|
|
|
if (*lpTempUserHive) {
|
|
DeleteFile(lpTempUserHive);
|
|
lstrcat(lpTempUserHive, TEXT(".log"));
|
|
DeleteFile(lpTempUserHive);
|
|
LocalFree(lpTempUserHive);
|
|
lpTempUserHive = NULL;
|
|
}
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
/*
|
|
|
|
*/
|
|
VOID APIENTRY FixupNulls(LPTSTR p)
|
|
{
|
|
while (*p != TEXT('\0')) {
|
|
if (*p == TEXT('#'))
|
|
*p = TEXT('\0');
|
|
#ifdef DBCS
|
|
p = CharNext(p);
|
|
#else
|
|
p++;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/*
|
|
|
|
* FUNCTION: GetProfileName
|
|
|
|
* PURPOSE: Uses the OPEN or SAVE common dialog to get the profile
|
|
* filename to be openned or saved (depending on the flag
|
|
* bOpenFilename).
|
|
|
|
|
|
*/
|
|
BOOL APIENTRY GetProfileName(LPTSTR lpFilePath, DWORD cb, BOOL bOpenFilename)
|
|
{
|
|
OPENFILENAME ofn; // Structure used to init dialog.
|
|
TCHAR szFilters[200*sizeof(TCHAR)]; // Filters string.
|
|
TCHAR szTitle[80*sizeof(TCHAR)]; // Title for dialog.
|
|
|
|
/* Load filters for profile file selection. */
|
|
LoadString(hInst, IDS_FILTERS, szFilters, sizeof(szFilters));
|
|
|
|
/* Convert the hashes in the filter into NULLs for the dialog. */
|
|
FixupNulls(szFilters);
|
|
|
|
/*
|
|
* Stomp on the file path so that the dialog doesn't
|
|
* try to use it to initialise the dialog. The result is put
|
|
* in here.
|
|
*/
|
|
*lpFilePath = TEXT('\0');
|
|
|
|
/* Setup info for comm dialog. */
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = hwndUPE;
|
|
ofn.hInstance = NULL;
|
|
ofn.lpstrFilter = szFilters;
|
|
ofn.lpstrCustomFilter = NULL;
|
|
ofn.nFilterIndex = 1;
|
|
ofn.nMaxCustFilter = 0;
|
|
ofn.lpstrFile = lpFilePath;
|
|
ofn.nMaxFile = cb;
|
|
ofn.lpstrInitialDir = NULL;
|
|
ofn.lpfnHook = NULL;
|
|
ofn.lpstrDefExt = szDefExt;
|
|
ofn.lpstrFileTitle = NULL;
|
|
ofn.lpTemplateName = 0;
|
|
|
|
if (bOpenFilename) {
|
|
|
|
// Open which profile ?
|
|
|
|
LoadString(hInst, IDS_OPENTITLE, szTitle, sizeof(szTitle));
|
|
ofn.lpstrTitle = szTitle;
|
|
ofn.Flags = OFN_SHOWHELP | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
|
|
|
|
if (!GetOpenFileName(&ofn)) {
|
|
return(FALSE);
|
|
}
|
|
}
|
|
else {
|
|
|
|
// Save Profile in ?
|
|
|
|
LoadString(hInst, IDS_SAVEAS, szTitle, sizeof(szTitle));
|
|
ofn.lpstrTitle = szTitle;
|
|
ofn.Flags = OFN_SHOWHELP | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
|
|
|
|
if (!GetSaveFileName(&ofn)) {
|
|
return(FALSE);
|
|
}
|
|
lstrcpy(lpFilePath, ofn.lpstrFile);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
BOOL GetPermittedUser(HWND hwnd, PSID *pSid)
|
|
{
|
|
LPTSTR lpUserName = NULL;
|
|
LPTSTR lpUserDomain = NULL;
|
|
LPTSTR lpBuffer = NULL;
|
|
DWORD cbAccountName = 0;
|
|
DWORD cbUserDomain = 0;
|
|
SID_NAME_USE SidNameUse;
|
|
|
|
if (!*pSid) {
|
|
GetSidFromOpenedProfile(pSid);
|
|
}
|
|
if (!*pSid) {
|
|
return(FALSE);
|
|
}
|
|
|
|
// Get the space needed for the User name and the Domain name
|
|
if (!LookupAccountSid(NULL, *pSid, NULL, &cbAccountName, NULL, &cbUserDomain, &SidNameUse) ) {
|
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
|
LocalFree(*pSid);
|
|
*pSid = NULL;
|
|
return(FALSE);
|
|
}
|
|
}
|
|
lpUserName = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * cbAccountName);
|
|
if (!lpUserName) {
|
|
LocalFree(*pSid);
|
|
*pSid = NULL;
|
|
return(FALSE);
|
|
}
|
|
lpUserDomain = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * cbUserDomain);
|
|
if (!lpUserDomain) {
|
|
LocalFree(lpUserName);
|
|
LocalFree(*pSid);
|
|
*pSid = NULL;
|
|
return(FALSE);
|
|
}
|
|
|
|
// Now get the user name and domain name
|
|
if (!LookupAccountSid(NULL, *pSid, lpUserName, &cbAccountName, lpUserDomain, &cbUserDomain, &SidNameUse) ) {
|
|
LocalFree(lpUserName);
|
|
LocalFree(lpUserDomain);
|
|
LocalFree(*pSid);
|
|
*pSid = NULL;
|
|
return(FALSE);
|
|
}
|
|
|
|
if (*lpUserName) {
|
|
lpBuffer = (LPTSTR)LocalAlloc(LPTR, (lstrlen(lpUserDomain) + lstrlen(lpUserName) +
|
|
2) * sizeof(TCHAR));
|
|
if (lpBuffer) {
|
|
lstrcpy(lpBuffer, lpUserDomain);
|
|
lstrcat(lpBuffer, TEXT("\\"));
|
|
lstrcat(lpBuffer, lpUserName);
|
|
SetDlgItemText(hwnd, IDD_USEDBY, lpBuffer);
|
|
LocalFree(lpBuffer);
|
|
}
|
|
}
|
|
LocalFree(lpUserName);
|
|
LocalFree(lpUserDomain);
|
|
return(TRUE);
|
|
}
|
|
|
|
/*
|
|
* OpenUserProfile
|
|
|
|
* Purpose : Load an existing profile in the registry and unload previously
|
|
* loaded profile (and delete its tmp file).
|
|
|
|
* History:
|
|
* 11-20-92 JohanneC Created.
|
|
*/
|
|
BOOL APIENTRY OpenUserProfile(LPTSTR szFilePath, PSID *pUserSid)
|
|
{
|
|
|
|
TCHAR szErrorTitle[80*sizeof(TCHAR)]; // Title for error message box.
|
|
TCHAR szMessage[MAXMESSAGELEN*sizeof(TCHAR)]; // Title for error message box.
|
|
DWORD err;
|
|
|
|
// be prepared for errors.
|
|
LoadString(hInst, IDS_OPENERROR, szErrorTitle, sizeof(szErrorTitle));
|
|
|
|
|
|
// Copy the profile to a temp hive before loading it in the registry.
|
|
|
|
if (!lpTempUserHivePath) {
|
|
if (!AllocAndExpandEnvironmentStrings(TEMP_USER_HIVE_PATH, &lpTempUserHivePath))
|
|
return(FALSE);
|
|
}
|
|
|
|
lpTempUserHive = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) *
|
|
(lstrlen(lpTempUserHivePath) + 17));
|
|
if (!lpTempUserHive) {
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!GetTempFileName(lpTempUserHivePath, TEXT("tmp"), 0, lpTempUserHive)) {
|
|
lstrcpy(lpTempUserHive, lpTempUserHivePath);
|
|
lstrcat(lpTempUserHive, TEXT("\\HiveOpen"));
|
|
}
|
|
|
|
if (CopyFile(szFilePath, lpTempUserHive, FALSE)) {
|
|
GetRegistryKeyFromPath(lpTempUserHive, &lpTempHiveKey);
|
|
if ((err = RegLoadKey(HKEY_USERS, lpTempHiveKey, lpTempUserHive)) == ERROR_SUCCESS) {
|
|
if (RegOpenKeyEx(HKEY_USERS, lpTempHiveKey, 0, MAXIMUM_ALLOWED, &hkeyCurrentUser) != ERROR_SUCCESS) {
|
|
|
|
// Error, do not have access to the profile.
|
|
|
|
LoadString(hInst, IDS_OPENACCESSDENIED, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szErrorTitle, MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
|
|
ClearTempUserProfile();
|
|
return(FALSE);
|
|
}
|
|
}
|
|
else {
|
|
DeleteFile(lpTempUserHive);
|
|
lstrcat(lpTempUserHive, TEXT(".log"));
|
|
DeleteFile(lpTempUserHive);
|
|
LocalFree(lpTempUserHive);
|
|
|
|
|
|
// Could not load the user profile, check the error code
|
|
|
|
if (err == ERROR_BADDB) {
|
|
// bad format: not a profile registry file
|
|
LoadString(hInst, IDS_OPENBADFORMAT, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szErrorTitle,
|
|
MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
|
|
return(FALSE);
|
|
}
|
|
else {
|
|
// generic error message : Failed to load profile
|
|
LoadString(hInst, IDS_OPENFAILED, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szErrorTitle,
|
|
MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
|
|
return(FALSE);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
// An error occured trying to load the profile.
|
|
|
|
LoadString(hInst, IDS_OPENFAILED, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szErrorTitle,
|
|
MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
// Clear permitted to use profile field.
|
|
|
|
SetDlgItemText(hwndUPE, IDD_USEDBY, TEXT(""));
|
|
*pUserSid = NULL;
|
|
if (!GetPermittedUser(hwndUPE, pUserSid)) {
|
|
LoadString(hInst, IDS_ACCOUNTUNKNOWN, szMessage, sizeof(szMessage));
|
|
SetDlgItemText(hwndUPE, IDD_USEDBY, szMessage);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/*
|
|
* SaveUserProfile
|
|
|
|
* Purpose : Save the loaded profile as a file.
|
|
|
|
* History:
|
|
* 11-20-92 JohanneC Created.
|
|
*/
|
|
BOOL APIENTRY SaveUserProfile(PSID pUserSid, LPTSTR lpFilePath)
|
|
{
|
|
TCHAR szTitle[20*sizeof(TCHAR)];
|
|
TCHAR szMessage[MAXMESSAGELEN*sizeof(TCHAR)];
|
|
LPTSTR lpTmpHive = NULL;
|
|
SID_IDENTIFIER_AUTHORITY
|
|
NtAuthority = SECURITY_NT_AUTHORITY;
|
|
PSECURITY_DESCRIPTOR lpSecDesc;
|
|
LPSECURITY_ATTRIBUTES lpSecAttr;
|
|
SECURITY_ATTRIBUTES SecAttr;
|
|
NTSTATUS NtStatus;
|
|
BOOL err = FALSE;
|
|
|
|
|
|
ResetEvent(hProgramGroupsEvent);
|
|
|
|
/* Write the selected settings in the registry. */
|
|
if (!SaveUPESettingsToRegistry())
|
|
return(FALSE);
|
|
|
|
RegFlushKey(hkeyCurrentUser);
|
|
|
|
RegNotifyChangeKeyValue(hkeyProgramGroupsCurrent, TRUE, REG_NOTIFY_CHANGE_NAME,
|
|
hProgramGroupsEvent, TRUE);
|
|
|
|
LoadString(hInst, IDS_SAVEAS, szTitle, sizeof(szTitle));
|
|
|
|
|
|
// Before the profile we need to apply protection.
|
|
|
|
NtStatus = ApplyProfileProtection(NULL, pUserSid, hkeyCurrentUser);
|
|
if (NtStatus) {
|
|
if (NtStatus == STATUS_INVALID_SID) {
|
|
LoadString(hInst, IDS_INVALIDSID, szMessage, sizeof(szMessage));
|
|
} else {
|
|
LoadString(hInst, IDS_PROTECTERROR, szMessage, sizeof(szMessage));
|
|
}
|
|
MessageBox(hwndUPE, szMessage, szTitle, MB_ICONEXCLAMATION | MB_OK);
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
// Now that the protection is on the profile, restrict the special keys
|
|
// like the locked groups and the restriction subkey for the Program Manager.
|
|
|
|
if (!LockGroups(FALSE)) {
|
|
goto Error;
|
|
}
|
|
|
|
lpSecDesc = CreateSecurityDescriptorForFile(pUserSid, lpFilePath);
|
|
if (lpSecDesc) {
|
|
SecAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
|
SecAttr.lpSecurityDescriptor = lpSecDesc;
|
|
SecAttr.bInheritHandle = TRUE;
|
|
lpSecAttr = &SecAttr;
|
|
}
|
|
else {
|
|
lpSecAttr = NULL;
|
|
}
|
|
|
|
|
|
if (RegSaveKey(hkeyCurrentUser, lpFilePath, lpSecAttr) != ERROR_SUCCESS) {
|
|
|
|
|
|
// Save the profile to a temp hive then copy it over.
|
|
|
|
|
|
if (!AllocAndExpandEnvironmentStrings(TEMP_SAVE_HIVE, &lpTmpHive))
|
|
goto Error;
|
|
|
|
DeleteFile(lpTmpHive);
|
|
|
|
if (RegSaveKey(hkeyCurrentUser, lpTmpHive, NULL) != ERROR_SUCCESS) {
|
|
LocalFree(lpTmpHive);
|
|
lpTmpHive = NULL;
|
|
Error:
|
|
LoadString(hInst, IDS_ERRORSAVING, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szTitle, MB_ICONEXCLAMATION | MB_OK);
|
|
err = TRUE;
|
|
}
|
|
else {
|
|
if (CopyFile(lpTmpHive, lpFilePath, FALSE)) {
|
|
DeleteFile(lpTmpHive);
|
|
LocalFree(lpTmpHive);
|
|
lpTmpHive = NULL;
|
|
if (lpSecDesc)
|
|
SetFileSecurity(lpFilePath,
|
|
DACL_SECURITY_INFORMATION,
|
|
lpSecDesc);
|
|
}
|
|
else {
|
|
// DbgPrint("UPEDIT: could not overwrite file %s, error = %d\n\r",
|
|
// lpFilePath, GetLastError());
|
|
goto Error;
|
|
}
|
|
}
|
|
}
|
|
if (lpTmpHive)
|
|
LocalFree(lpTmpHive);
|
|
|
|
if (lpSecDesc)
|
|
DeleteSecurityDescriptor(lpSecDesc);
|
|
|
|
return(!err);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* SaveCurrentProfile
|
|
|
|
* Purpose : Save the current profile.
|
|
|
|
* History:
|
|
* 11-20-92 JohanneC Created.
|
|
*/
|
|
BOOL APIENTRY SaveCurrentProfile(PSECURITY_DESCRIPTOR pSecDesc, PSID CurrentUserSid)
|
|
{
|
|
TCHAR szTitle[MAXTITLELEN * sizeof(TCHAR)];
|
|
TCHAR szMessage[MAXMESSAGELEN * sizeof(TCHAR)];
|
|
NTSTATUS NtStatus;
|
|
DWORD err;
|
|
|
|
LoadString(hInst, IDS_SAVECURRENT, szTitle, sizeof(szTitle));
|
|
|
|
/* Write the selected settings in the registry. */
|
|
if (!SaveUPESettingsToRegistry()) {
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
NtStatus = ApplyProfileProtection( pSecDesc, CurrentUserSid, HKEY_CURRENT_USER );
|
|
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
|
|
// Failed to apply protection on profile
|
|
|
|
LoadString(hInst, IDS_PROTECTERROR, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szTitle, MB_OK | MB_ICONEXCLAMATION);
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!LockGroups(FALSE))
|
|
return(FALSE);
|
|
|
|
err = RegFlushKey(HKEY_CURRENT_USER);
|
|
if (err != ERROR_SUCCESS) {
|
|
LoadString(hInst, IDS_SAVECURFAILED, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szTitle, MB_OK | MB_ICONEXCLAMATION);
|
|
return(FALSE);
|
|
}
|
|
|
|
InitializeUPESettings(hwndUPE, TRUE);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/*
|
|
* SaveDefaultProfile
|
|
|
|
* Purpose : Save the current profile as the default profile.
|
|
|
|
* History:
|
|
* 11-20-92 JohanneC Created.
|
|
*/
|
|
BOOL APIENTRY SaveDefaultProfile()
|
|
{
|
|
TCHAR szTitle[MAXTITLELEN * sizeof(TCHAR)];
|
|
TCHAR szMessage[MAXMESSAGELEN * sizeof(TCHAR)];
|
|
LPTSTR lpUserDefTmpHive = NULL;
|
|
LPTSTR lpUserDefPath = NULL;
|
|
NTSTATUS NtStatus;
|
|
DWORD err;
|
|
|
|
LoadString(hInst, IDS_SAVEDEFAULT, szTitle, sizeof(szTitle));
|
|
|
|
/* Write the selected settings in the registry. */
|
|
if (!SaveUPESettingsToRegistry()) {
|
|
return(FALSE);
|
|
}
|
|
|
|
NtStatus = ApplyProfileProtection( NULL, gSystemSid, hkeyCurrentUser );
|
|
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
|
|
// Failed to apply protection on profile
|
|
|
|
LoadString(hInst, IDS_PROTECTERROR, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szTitle, MB_OK | MB_ICONEXCLAMATION);
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!LockGroups(FALSE)) {
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
// Save the User Default profile.
|
|
|
|
if (!AllocAndExpandEnvironmentStrings(USERDEF_TEMP_HIVE, &lpUserDefTmpHive))
|
|
goto Error;
|
|
|
|
DeleteFile(lpUserDefTmpHive);
|
|
err = RegSaveKey(hkeyCurrentUser, lpUserDefTmpHive, NULL);
|
|
if (!err) {
|
|
|
|
// copy the user default to %systemroot%\system32\config\USERDEF
|
|
|
|
if (!AllocAndExpandEnvironmentStrings(USERDEF_HIVE, &lpUserDefPath))
|
|
goto Error;
|
|
|
|
if (!CopyFile(lpUserDefTmpHive, lpUserDefPath, FALSE)) {
|
|
goto Error;
|
|
}
|
|
|
|
// delete temp file
|
|
DeleteFile(lpUserDefTmpHive);
|
|
|
|
LocalFree(lpUserDefTmpHive);
|
|
LocalFree(lpUserDefPath);
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
else {
|
|
|
|
Error:
|
|
if (lpUserDefTmpHive) {
|
|
DeleteFile(lpUserDefTmpHive);
|
|
LocalFree(lpUserDefTmpHive);
|
|
}
|
|
if (lpUserDefPath) {
|
|
LocalFree(lpUserDefPath);
|
|
}
|
|
LoadString(hInst, IDS_SAVEDEFFAILED, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szTitle, MB_OK | MB_ICONEXCLAMATION);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* SaveSystemProfile
|
|
|
|
* Purpose : Save the current profile as the system profile.
|
|
|
|
* History:
|
|
* 11-20-92 JohanneC Created.
|
|
*/
|
|
BOOL APIENTRY SaveSystemProfile()
|
|
{
|
|
TCHAR szTitle[MAXTITLELEN * sizeof(TCHAR)];
|
|
TCHAR szMessage[MAXMESSAGELEN * sizeof(TCHAR)];
|
|
LPTSTR lpSystemTmpHive = NULL;
|
|
LPTSTR lpSystemDefPath = NULL;
|
|
LPTSTR lpSystemDefPathLog = NULL;
|
|
NTSTATUS NtStatus;
|
|
DWORD err;
|
|
|
|
LoadString(hInst, IDS_SAVESYSTEM, szTitle, sizeof(szTitle));
|
|
|
|
/* Write the selected settings in the registry. */
|
|
if (!SaveUPESettingsToRegistry()) {
|
|
return(FALSE);
|
|
}
|
|
|
|
NtStatus = ApplyProfileProtection( NULL, gSystemSid, hkeyCurrentUser );
|
|
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
|
|
// Failed to apply protection on profile
|
|
|
|
LoadString(hInst, IDS_PROTECTERROR, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szTitle, MB_OK | MB_ICONEXCLAMATION);
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
// Save the System profile.
|
|
|
|
if (!AllocAndExpandEnvironmentStrings(SYSTEM_TEMP_HIVE, &lpSystemTmpHive))
|
|
goto Error;
|
|
|
|
DeleteFile(lpSystemTmpHive);
|
|
if (err = RegSaveKey(hkeyCurrentUser, lpSystemTmpHive, NULL))
|
|
goto Error;
|
|
|
|
|
|
// Move the hive to the system default hive on reboot.
|
|
|
|
AllocAndExpandEnvironmentStrings(SYSTEM_DEFAULT_HIVE, &lpSystemDefPath);
|
|
if (!lpSystemDefPath) {
|
|
goto Error;
|
|
}
|
|
|
|
if (!MoveFileEx(lpSystemTmpHive, lpSystemDefPath,
|
|
MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING)) {
|
|
err = GetLastError();
|
|
}
|
|
else {
|
|
lpSystemDefPathLog = LocalAlloc (LPTR, (lstrlen(lpSystemDefPath) + 5) *
|
|
sizeof (TCHAR));
|
|
|
|
if (lpSystemDefPathLog) {
|
|
lstrcpy(lpSystemDefPathLog, lpSystemDefPath);
|
|
lstrcat(lpSystemDefPathLog, TEXT(".log"));
|
|
if (!MoveFileEx(lpSystemDefPathLog, NULL,
|
|
MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING))
|
|
err = GetLastError();
|
|
} else {
|
|
err = GetLastError();
|
|
}
|
|
}
|
|
|
|
|
|
if (err) {
|
|
Error:
|
|
LoadString(hInst, IDS_SAVESYSFAILED, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szTitle, MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
else {
|
|
|
|
|
|
// The system default will only be changed at next reboot.
|
|
|
|
LoadString(hInst, IDS_NEWSYSTEMDEF, szMessage, sizeof(szMessage));
|
|
MessageBox(hwndUPE, szMessage, szTitle, MB_OK | MB_ICONINFORMATION);
|
|
}
|
|
|
|
if (lpSystemDefPath)
|
|
LocalFree(lpSystemDefPath);
|
|
if (lpSystemTmpHive)
|
|
LocalFree(lpSystemTmpHive);
|
|
|
|
return(!err);
|
|
}
|
|
|
|
BOOL AllocAndExpandEnvironmentStrings(LPTSTR String, LPTSTR *lpExpandedString)
|
|
{
|
|
LPTSTR lptmp = NULL;
|
|
DWORD cchBuffer;
|
|
|
|
// Get the number of characters needed.
|
|
cchBuffer = ExpandEnvironmentStrings(String, lptmp, 0);
|
|
if (cchBuffer) {
|
|
cchBuffer++; // for NULL terminator
|
|
lptmp = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * cchBuffer);
|
|
if (!lptmp) {
|
|
return(FALSE);
|
|
}
|
|
cchBuffer = ExpandEnvironmentStrings(String, lptmp, cchBuffer);
|
|
}
|
|
*lpExpandedString = lptmp;
|
|
return(TRUE);
|
|
}
|
|
|
|
VOID GetRegistryKeyFromPath(LPTSTR lpPath, LPTSTR *lpKey)
|
|
{
|
|
LPTSTR lptmp;
|
|
|
|
*lpKey = lpPath;
|
|
|
|
for (lptmp = lpPath; *lptmp; lptmp++) {
|
|
if (*lptmp == TEXT('\\')) {
|
|
*lpKey = lptmp+1;
|
|
}
|
|
}
|
|
|
|
}
|