|
|
//*************************************************************
//
// Personal Classes Profile management routines
//
// Microsoft Confidential
// Copyright (c) Microsoft Corporation 1995
// All rights reserved
//
//*************************************************************
#include "uenv.h"
LPTSTR GetSidString(HANDLE UserToken); VOID DeleteSidString(LPTSTR SidString); PSID GetUserSid (HANDLE UserToken); VOID DeleteUserSid(PSID Sid);
BOOL MergeUserClasses( HKEY UserClassStore, HKEY CommonClassStore, HKEY MergedClassStore, BOOL ForceNew);
BOOL CloneRegistryTree( HKEY hkSourceTree, HKEY hkDestinationTree, LPTSTR lpDestTreeName );
BOOL AddSharedValuesToSubkeys( HKEY hkShared, LPTSTR pszSubtree );
BOOL AddSharedValues( HKEY hkShared ); void CreateMachineClassHive( ) { HKEY hkUser = NULL; HKEY hkMachine = NULL; LONG result; DWORD dwDisp;
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Classes"), 0, KEY_READ, &hkUser); if (ERROR_SUCCESS != result) { return; } result = RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\MachineClasses"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkMachine, &dwDisp );
if (ERROR_SUCCESS != result) { RegCloseKey( hkUser ); return; } CloneRegistryTree(hkUser, hkMachine, NULL);
AddSharedValues( hkMachine );
RegCloseKey( hkUser ); RegCloseKey( hkMachine ); }
LPTSTR GetUserMergedHivePath( LPTSTR SidString ) { // open HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\ProfileList
// open ...\SidString
// get value for ProfileImagePath, and if it is reg_expand_sz, expand it
// append Classes as the last component of the hive file name
long result; HKEY hkProfileListKey; HKEY hkProfileKey; TCHAR ProfilePath[256]; TCHAR ExpandedProfilePath[256]; LPTSTR pszProfileDirectory = NULL; LPTSTR pszReturnedHivePath = NULL; DWORD dwType; DWORD dwSize = sizeof( ProfilePath );
result = RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList", 0, KEY_READ, &hkProfileListKey );
// Bug 45992
if (ERROR_SUCCESS != result) { return NULL; } result = RegOpenKeyEx( hkProfileListKey, SidString, 0, KEY_READ, &hkProfileKey );
if (ERROR_SUCCESS != result) { RegCloseKey(hkProfileListKey); return NULL; } result = RegQueryValueEx( hkProfileKey, L"ProfileImagePath", NULL, &dwType, (BYTE*)&ProfilePath, &dwSize );
// Close them keys
RegCloseKey(hkProfileListKey); RegCloseKey(hkProfileKey); if (ERROR_SUCCESS != result) { return NULL; } if ( dwType == REG_EXPAND_SZ ) { ExpandEnvironmentStrings( ProfilePath, ExpandedProfilePath, sizeof(ExpandedProfilePath)/sizeof(TCHAR) ); pszProfileDirectory = ExpandedProfilePath; } else { pszProfileDirectory = ProfilePath; }
pszReturnedHivePath = (LPTSTR) LocalAlloc( LPTR, (lstrlenW( pszProfileDirectory )+1) * sizeof(TCHAR) + sizeof( L"\\ClsRoot" ) ); // Bug 45993
if (pszReturnedHivePath) { // make up the returned string as the profile directory with \ClsRoot on the end
lstrcpyW( pszReturnedHivePath, pszProfileDirectory ); lstrcatW( pszReturnedHivePath, L"\\ClsRoot" ); }
return pszReturnedHivePath; }
void FreeUserMergedHivePath( LPTSTR hivepath ) { LocalFree( hivepath ); }
// see if the desired hive file already exists. If so, load it and return
// otherwise, create a hive containing a single key, load it and return
BOOL CreateUserMergedClasses( LPTSTR SidString, LPTSTR MergedClassesString, HKEY * phkMerged ) { LPTSTR HivePath; long result; HKEY DummyKey = NULL; DWORD dwDisp; NTSTATUS Status; BOOLEAN WasEnabled;
HivePath = GetUserMergedHivePath( SidString ); if (!HivePath) { return FALSE; } // see if the desired hive file already exists. If so, load it and return
if ( 0xFFFFFFFF == GetFileAttributes( HivePath ) ) { // create a hive containing a single key, load it and return
result = RegCreateKeyEx( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\DummyKey", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &DummyKey, &dwDisp ); if (ERROR_SUCCESS != result) { FreeUserMergedHivePath( HivePath ); return FALSE; } //
// Enable the backup privilege
//
Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &WasEnabled);
// do this by doing a RegSaveKey of a small subtree
result = RegSaveKey( DummyKey, HivePath, NULL );
result = RegCloseKey( DummyKey ); //
// Restore the privilege to its previous state
//
Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, WasEnabled, FALSE, &WasEnabled); }
//
// Enable the restore privilege
//
Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &WasEnabled);
result = RegLoadKey( HKEY_USERS, MergedClassesString, HivePath );
// if result is OK, then open the subkey and return it
result = RegOpenKeyEx( HKEY_USERS, MergedClassesString, 0, KEY_ALL_ACCESS, phkMerged );
FreeUserMergedHivePath( HivePath ); // close keys?
//
// Restore the privilege to its previous state
//
Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, WasEnabled, FALSE, &WasEnabled);
return TRUE; }
void MergeUserClassHives( HANDLE Token ) { HKEY hkUser = NULL; HKEY hkMachine = NULL; HKEY hkMerged = NULL; LONG result; LPTSTR SidString; LPTSTR MergedClassesString; DWORD dwDisp; BOOL ForceNew = FALSE;
result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Classes"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hkUser, &dwDisp);
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\MachineClasses"), 0, KEY_READ, &hkMachine);
if ( result == ERROR_FILE_NOT_FOUND ) { CreateMachineClassHive(); result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\MachineClasses"), 0, KEY_READ, &hkMachine);
}
// Bugs 45996 and 45997
SidString = GetSidString( Token ); if (SidString) { MergedClassesString = (LPTSTR) LocalAlloc( LPTR, (lstrlenW( SidString ) + 1) * sizeof(WCHAR) + sizeof(L"_MergedClasses" ) ); if (MergedClassesString) { lstrcpyW( MergedClassesString, SidString ); lstrcatW( MergedClassesString, L"_MergedClasses" ); result = RegOpenKeyEx( HKEY_USERS, MergedClassesString, 0, KEY_ALL_ACCESS, &hkMerged ); if ( result == ERROR_FILE_NOT_FOUND ) { CreateUserMergedClasses(SidString, MergedClassesString, &hkMerged ); ForceNew = TRUE; } MergeUserClasses(hkUser, hkMachine, hkMerged, ForceNew ); LocalFree( MergedClassesString ); } }
RegCloseKey( hkUser ); RegCloseKey( hkMachine ); RegCloseKey( hkMerged );
DeleteSidString( SidString ); }
void MergeHives( ) { HANDLE Token; NTSTATUS Status;
Status = NtOpenProcessToken( NtCurrentProcess(), TOKEN_QUERY, &Token );
MergeUserClassHives( Token );
NtClose( Token );
}
|