|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
usermig.c
Abstract:
The functions in this module are called to perform migration of per-user settings.
Author:
Jim Schmidt (jimschm) 04-Feb-1997
Revision History:
jimschm 23-Sep-1998 Redesigned for new progress bar and shell code jimschm 11-Jul-1998 Support for dynamic user profile dir, removal of MikeCo code. calinn 12-Dec-1997 Added RestoreMMSettings_User jimschm 21-Apr-1997 Added UserProfileExt
--*/
#include "pch.h"
#include "migmainp.h"
#ifndef UNICODE
#error UNICODE required
#endif
VOID pSuppressEmptyWallpaper ( VOID );
VOID pCheckY2KCompliance ( VOID );
DWORD PrepareUserForMigration ( IN DWORD Request, IN PMIGRATE_USER_ENUM EnumPtr ) { static USERMIGDATA Data; static BOOL DefaultHiveLoaded = FALSE; LONG rc; MEMDB_ENUM e; TCHAR RegKey[MAX_REGISTRY_KEY]; TCHAR RegValueName[MAX_REGISTRY_VALUE_NAME]; TCHAR RegValueKey[MEMDB_MAX]; PCTSTR RegValue; TCHAR DefaultUserHive[MAX_TCHAR_PATH]; static TCHAR ReferenceDefaultUserHive[MAX_TCHAR_PATH]; PTSTR p, q; HKEY Key; DWORD Size; PTSTR LogFile; DWORD valueType;
if (Request == REQUEST_QUERYTICKS) {
return TICKS_PERUSER_INIT;
} else if (Request == REQUEST_BEGINUSERPROCESSING) {
//
// Save current state of memdb (to be reloaded for each user)
//
MemDbSave (GetMemDbDat()); return ERROR_SUCCESS;
} else if (Request != REQUEST_RUN && Request != REQUEST_ENDUSERPROCESSING ) { return ERROR_SUCCESS; }
//
// We are now begining to process another user, or we are being
// called one last time after all users are processed. Clean up
// the previous state.
//
if (Data.UserHiveRootOpen) { CloseRegKey (Data.UserHiveRoot); }
if (Data.UserHiveRootCreated) { pSetupRegistryDelnode (HKEY_CURRENT_CONFIG, S_TEMP_USER_KEY); }
if (Data.LastUserWasDefault) { RegUnLoadKey (HKEY_LOCAL_MACHINE, S_TEMP_USER_KEY); }
if (Data.ProfileToDelete[0]) { if (Data.LastUserWasDefault && !Data.DefaultHiveSaved) { //
// Default User hive could not be saved, so restore the file
//
OurMoveFile (Data.ProfileToDelete, Data.TempProfile);
} else {
//
// The original default hive needs to be removed
//
DeleteFile (Data.ProfileToDelete);
LogFile = DuplicatePathString (Data.ProfileToDelete, 5); StringCat (LogFile, TEXT(".log"));
DeleteFile (LogFile);
FreePathString (LogFile); } }
ZeroMemory (&Data, sizeof (Data));
if (Request == REQUEST_ENDUSERPROCESSING) {
if (DefaultHiveLoaded) { rc = RegUnLoadKey (HKEY_LOCAL_MACHINE, S_MAPPED_DEFAULT_USER_KEY); if (rc != ERROR_SUCCESS) { SetLastError (rc); DEBUGMSG ((DBG_ERROR, "Can't unload Default User hive in cleanup")); }
SetFileAttributes (ReferenceDefaultUserHive, FILE_ATTRIBUTE_NORMAL); DeleteFile (ReferenceDefaultUserHive);
DefaultHiveLoaded = FALSE; }
return ERROR_SUCCESS;
}
MYASSERT (Request == REQUEST_RUN);
//
// Initialize globals
//
if (EnumPtr->AccountType != LOGON_USER_SETTINGS) { g_DomainUserName = EnumPtr->FixedDomainName; g_Win9xUserName = EnumPtr->Win9xUserName; g_FixedUserName = EnumPtr->FixedUserName; } else { g_DomainUserName = NULL; g_Win9xUserName = NULL; g_FixedUserName = NULL; }
//
// If default user hive has not been mapped in yet, map it in now.
// This will stay open as a reference.
//
if (!DefaultHiveLoaded) {
Size = ARRAYSIZE(DefaultUserHive)- 12; if (!GetDefaultUserProfileDirectory (DefaultUserHive, &Size)) { LOG (( LOG_ERROR, "Process User: Can't get default user profile directory" ));
return GetLastError(); }
StringCopy (AppendWack (DefaultUserHive), TEXT("ntuser.dat"));
StringCopy (ReferenceDefaultUserHive, DefaultUserHive); StringCat (ReferenceDefaultUserHive, TEXT(".ref"));
SetFileAttributes (ReferenceDefaultUserHive, FILE_ATTRIBUTE_NORMAL); DeleteFile (ReferenceDefaultUserHive);
if (!CopyFile (DefaultUserHive, ReferenceDefaultUserHive, FALSE)) { LOG (( LOG_ERROR, "Process User: Can't copy default user hive %s", DefaultUserHive ));
return GetLastError(); }
rc = RegLoadKey ( HKEY_LOCAL_MACHINE, S_MAPPED_DEFAULT_USER_KEY, ReferenceDefaultUserHive );
if (rc != ERROR_SUCCESS) { SetLastError (rc); LOG (( LOG_ERROR, "Process User: RegLoadKey could not load NT Default User from %s", ReferenceDefaultUserHive )); return rc; }
DefaultHiveLoaded = TRUE; }
//
// Prepare temp registry key
//
ZeroMemory (&Data, sizeof (Data)); EnumPtr->ExtraData = &Data;
switch (EnumPtr->AccountType) {
case DEFAULT_USER_ACCOUNT:
Size = MAX_TCHAR_PATH; GetDefaultUserProfileDirectory (Data.TempProfile, &Size); StringCopy (AppendWack (Data.TempProfile), TEXT("ntuser.dat"));
//
// Move the default user hive to a new file, so we can update
// it with RegSaveKey later.
//
wsprintf ( Data.ProfileToDelete, TEXT("%s.$$$"), Data.TempProfile );
SetFileAttributes (Data.ProfileToDelete, FILE_ATTRIBUTE_NORMAL); DeleteFile (Data.ProfileToDelete);
MYASSERT (!DoesFileExist (Data.ProfileToDelete));
if (!OurMoveFile (Data.TempProfile, Data.ProfileToDelete)) {
rc = GetLastError();
LOG (( LOG_ERROR, "Process User: OurMoveFile failed to move %s to %s", Data.TempProfile, Data.ProfileToDelete ));
return rc;
}
//
// Load the true Default User hive from its new location
//
rc = RegLoadKey ( HKEY_LOCAL_MACHINE, S_TEMP_USER_KEY, Data.ProfileToDelete );
if (rc != ERROR_SUCCESS) { SetLastError (rc); LOG (( LOG_ERROR, "Process User: RegLoadKey could not load NT Default User from %s", Data.ProfileToDelete )); return rc; }
Data.UserHiveRoot = OpenRegKey (HKEY_LOCAL_MACHINE, S_TEMP_USER_KEY); if (!Data.UserHiveRoot) { LOG ((LOG_ERROR, "Process User: RegOpenKey could not open NT Default User hive")); return GetLastError(); }
Data.UserHiveRootOpen = TRUE; Data.LastUserWasDefault = TRUE;
break;
case LOGON_USER_SETTINGS: //
// Set Data.UserHiveRoot to HKU\.Default
//
Data.UserHiveRoot = OpenRegKey (HKEY_USERS, S_DOT_DEFAULT); if (!Data.UserHiveRoot) { LOG ((LOG_ERROR, "Process User: RegOpenKey could not open HKU\\.Default")); return GetLastError(); }
Data.UserHiveRootOpen = TRUE;
//
// Suppress wallpaper if it is an empty string
//
pSuppressEmptyWallpaper();
break;
default: MYASSERT (g_Win9xUserName);
//
// Prepare the string "c:\windows\setup\ntuser.dat"
//
StringCopy (Data.TempProfile, g_TempDir); StringCopy (AppendWack (Data.TempProfile), TEXT("NTUSER.DAT"));
//
// Save this string in ProfileToDelete for cleanup later
//
StringCopy (Data.ProfileToDelete, Data.TempProfile);
//
// Create HKCC\$$$ and set Data.UserHiveRoot
//
rc = TrackedRegCreateKey (HKEY_CURRENT_CONFIG, S_TEMP_USER_KEY, &Data.UserHiveRoot); if (rc != ERROR_SUCCESS) { SetLastError (rc); LOG ((LOG_ERROR, "Process User: WinNTRegCreateKey failed to make %s in HKCC", S_TEMP_USER_KEY)); return rc; }
Data.UserHiveRootCreated = TRUE; Data.UserHiveRootOpen = TRUE;
//
// Set the per-user registry values
//
if (MemDbGetValueEx (&e, MEMDB_CATEGORY_SET_USER_REGISTRY, g_FixedUserName, NULL)) { do {
p = _tcschr (e.szName, TEXT('[')); if (p) { DecodeRuleCharsAB (RegKey, ARRAYSIZE(RegKey), e.szName, p); q = _tcsrchr (RegKey, TEXT('\\')); if (!q[1]) { *q = 0; }
p = _tcsinc (p); q = _tcschr (p, TEXT(']'));
if (q) { DecodeRuleCharsAB (RegValueName, ARRAYSIZE(RegValueName), p, q);
MemDbBuildKeyFromOffset (e.dwValue, RegValueKey, 0, NULL); RegValue = _tcschr (RegValueKey, TEXT('\\')); MYASSERT (RegValue); if (!RegValue) { RegValue = RegValueKey; } else { RegValue = _tcsinc (RegValue); }
if (!MemDbGetValue (RegValueKey, &valueType) || valueType == 0) { valueType = REG_SZ; }
Key = CreateRegKey (Data.UserHiveRoot, RegKey); if (!Key) { DEBUGMSG ((DBG_WHOOPS, "Can't create %s", RegKey)); } else { rc = RegSetValueEx ( Key, RegValueName, 0, valueType, (PBYTE) RegValue, SizeOfString (RegValue) );
CloseRegKey (Key);
DEBUGMSG_IF (( rc != ERROR_SUCCESS, DBG_WHOOPS, "Can't save %s [%s] = %s (rc = %u)", RegKey, RegValueName, RegValue, rc )); } } ELSE_DEBUGMSG ((DBG_WHOOPS, "Key not encoded properly: %s", e.szName)); } ELSE_DEBUGMSG ((DBG_WHOOPS, "Key not encoded properly: %s", e.szName));
} while (MemDbEnumNextValue (&e)); }
break; }
//
// Data.UserHiveRoot is either HKCU\$$$ or HKU\.Default
//
g_hKeyRootNT = Data.UserHiveRoot;
//
// Load in default MemDb state
//
MemDbLoad (GetMemDbDat());
return ERROR_SUCCESS; }
DWORD MigrateUserRegistry ( IN DWORD Request, IN PMIGRATE_USER_ENUM EnumPtr ) { if (Request == REQUEST_QUERYTICKS) {
return TICKS_USER_REGISTRY_MIGRATION;
} else if (Request != REQUEST_RUN) {
return ERROR_SUCCESS;
}
if (!MergeRegistry (S_USERMIG_INF, g_DomainUserName ? g_DomainUserName : S_EMPTY)) { LOG ((LOG_ERROR, "Process User: MergeRegistry failed")); return GetLastError(); }
return ERROR_SUCCESS; }
DWORD MigrateLogonPromptSettings ( IN DWORD Request, IN PMIGRATE_USER_ENUM EnumPtr ) { if (Request == REQUEST_QUERYTICKS) {
return TICKS_LOGON_PROMPT_SETTINGS;
} else if (Request != REQUEST_RUN) {
return ERROR_SUCCESS;
}
if (EnumPtr->AccountType != LOGON_USER_SETTINGS) { return ERROR_SUCCESS; }
MYASSERT (EnumPtr->ExtraData);
return ERROR_SUCCESS; }
DWORD MigrateUserSettings ( IN DWORD Request, IN PMIGRATE_USER_ENUM EnumPtr ) { if (Request == REQUEST_QUERYTICKS) {
return TICKS_USER_SETTINGS;
} else if (Request != REQUEST_RUN) {
return ERROR_SUCCESS;
}
if (EnumPtr->AccountType == LOGON_USER_SETTINGS) { return ERROR_SUCCESS; }
MYASSERT (EnumPtr->ExtraData);
//
// Copy any settings from DOS configuration files that need to be
// saved into the per user configuration.
//
if (EnumPtr->AccountType != DEFAULT_USER_ACCOUNT) {
if (DosMigNt_User (g_hKeyRootNT) != EXIT_SUCCESS) { LOG ((LOG_ERROR,"DosMigNt failed.")); }
}
//
// Pull in all the per-user INI settings (TRUE indicates per-user settings)
//
if (!ProcessIniFileMapping (TRUE)) { LOG ((LOG_ERROR, "Process User: Could not migrate one or more .INI files.")); }
//
// Now look for Short Date format settings
//
pCheckY2KCompliance ();
//
// Restore multimedia settings
//
if (!RestoreMMSettings_User (g_FixedUserName, g_hKeyRootNT)) { LOG ((LOG_ERROR, "Process User: Could not restore multimedia settings.")); }
//
// Create the RAS entries for the user.
//
if (!Ras_MigrateUser (g_FixedUserName, g_hKeyRootNT)) { LOG ((LOG_ERROR,"Ras user migration failed.")); }
//
// Create the TAPI entries that are per user.
//
if (!Tapi_MigrateUser (g_FixedUserName, g_hKeyRootNT)) { LOG ((LOG_ERROR,"Tapi user migration failed.")); }
return ERROR_SUCCESS; }
DWORD SaveMigratedUserHive ( IN DWORD Request, IN PMIGRATE_USER_ENUM EnumPtr ) { PTSTR UserProfile = NULL; PCTSTR UserNameWithSuffix; PSID Sid; LONG rc = ERROR_SUCCESS; PUSERMIGDATA Data; PCTSTR CopyOfProfile; PTSTR Path; MIGRATE_USER_ENUM e;
if (Request == REQUEST_QUERYTICKS) {
return TICKS_SAVE_USER_HIVE;
} else if (Request != REQUEST_RUN) {
return ERROR_SUCCESS;
}
MYASSERT (EnumPtr->ExtraData); Data = EnumPtr->ExtraData;
if (EnumPtr->AccountType == LOGON_USER_SETTINGS) { return ERROR_SUCCESS; }
if (Data->TempProfile[0] && !Data->LastUserWasDefault) {
//
// Save the hive to disk
//
SetFileAttributes (Data->TempProfile, FILE_ATTRIBUTE_NORMAL); DeleteFile (Data->TempProfile);
MYASSERT (Data->UserHiveRootOpen);
rc = RegSaveKey (Data->UserHiveRoot, Data->TempProfile, NULL);
if (rc != ERROR_SUCCESS) { SetLastError (rc); LOG ((LOG_ERROR, "RegSaveKey failed to save %s", Data->TempProfile)); return rc;
} else {
SetFileAttributes (Data->TempProfile, FILE_ATTRIBUTE_HIDDEN);
}
//
// Look up account SID
//
Sid = GetSidForUser (g_FixedUserName); if (!Sid) { DEBUGMSG ((DBG_WARNING, "Could not obtain SID for %s", g_FixedUserName)); return GetLastError(); }
//
// Add the user to the local power users or administrators group
//
if (g_PersonalSKU) { if (EnumPtr->AccountType != ADMINISTRATOR_ACCOUNT) {
LOG_IF (( g_ConfigOptions.MigrateUsersAsPowerUsers, LOG_WARNING, "MigrateUsersAsPowerUsers option is ignored on upgrade to Personal SKU" ));
LOG_IF (( g_ConfigOptions.MigrateUsersAsAdmin, LOG_WARNING, "MigrateUsersAsAdmin option is ignored on upgrade to Personal SKU" ));
if (!AddSidToLocalGroup (Sid, g_AdministratorsGroupStr)) { DEBUGMSG ((DBG_WARNING, "Could not add %s to %s group", g_FixedUserName, g_AdministratorsGroupStr)); } } } else { if (g_ConfigOptions.MigrateUsersAsPowerUsers) {
if (!AddSidToLocalGroup (Sid, g_PowerUsersGroupStr)) { DEBUGMSG ((DBG_WARNING, "Could not add %s to %s group", g_FixedUserName, g_PowerUsersGroupStr)); }
} else if (EnumPtr->AccountType != ADMINISTRATOR_ACCOUNT && g_ConfigOptions.MigrateUsersAsAdmin ) {
if (!AddSidToLocalGroup (Sid, g_AdministratorsGroupStr)) { DEBUGMSG ((DBG_WARNING, "Could not add %s to %s group", g_FixedUserName, g_AdministratorsGroupStr)); } } else { SetClassicLogonType(); } }
__try {
//
// Prepare profile directory
//
UserNameWithSuffix = GetUserProfilePath (g_FixedUserName, &UserProfile); MYASSERT (UserNameWithSuffix); MYASSERT (UserProfile);
if (!UserNameWithSuffix) { rc = GetLastError(); __leave; }
//
// The recommendation here (UserNameWithSuffix) is no longer used, because
// we already created the user profile dir before processing the user.
//
if (!CreateUserProfile ( Sid, UserNameWithSuffix, // User or User.000
Data->TempProfile, NULL, 0 )) { LOG ((LOG_ERROR, "Create User Profile failed")); rc = GetLastError(); __leave; }
//
// Build the final location of the user's hive, so migdlls.c
// can load the hive.
//
wsprintf ( Data->TempProfile, TEXT("%s\\ntuser.dat"), UserProfile ); } __finally { FreePathString (UserProfile); }
} else if (Data->LastUserWasDefault) {
SetFileAttributes (Data->TempProfile, FILE_ATTRIBUTE_NORMAL); DeleteFile (Data->TempProfile);
//
// Save the hive
//
rc = RegSaveKey (Data->UserHiveRoot, Data->TempProfile, NULL);
if (rc != ERROR_SUCCESS) { SetLastError (rc); LOG ((LOG_ERROR, "Process User: RegSaveKey failed to save %s", Data->TempProfile));
} else {
SetFileAttributes (Data->TempProfile, FILE_ATTRIBUTE_HIDDEN);
Data->DefaultHiveSaved = TRUE;
//
// Find Administrator
//
if (EnumFirstUserToMigrate (&e, ENUM_ALL_USERS)) { do { if (e.AccountType == ADMINISTRATOR_ACCOUNT) { break; } } while (EnumNextUserToMigrate (&e)); }
if (e.AccountType == ADMINISTRATOR_ACCOUNT && e.CreateOnly) {
//
// Copy the hive to Administrator if (A) the Administrator is
// not a migrated user, and (B) the hive exists
//
if (GetUserProfilePath (e.FixedUserName, &Path)) {
DeleteDirectoryContents (Path);
SetFileAttributes (Path, FILE_ATTRIBUTE_NORMAL); if (!RemoveDirectory (Path)) { DEBUGMSG ((DBG_ERROR, "Can't remove %s", Path)); } ELSE_DEBUGMSG ((DBG_VERBOSE, "Administrator profile %s removed", Path));
FreePathString (Path); } ELSE_DEBUGMSG ((DBG_WHOOPS, "User %s does not have a profile path", e.FixedUserName)); } } }
if (rc == ERROR_SUCCESS) {
//
// Add hive location to string table
//
CopyOfProfile = PoolMemDuplicateString (g_HivePool, Data->TempProfile);
DEBUGMSG (( DBG_NAUSEA, "ProcessUser: Adding hive location %s for user %s", CopyOfProfile, g_FixedUserName ));
pSetupStringTableAddStringEx ( g_HiveTable, (PTSTR) g_FixedUserName, STRTAB_CASE_INSENSITIVE, (PTSTR) CopyOfProfile, SizeOfString (CopyOfProfile) ); } else {
//
// The hive couldn't be saved for this user!! Tell the user.
//
LOG ((LOG_ERROR, (PCSTR)MSG_PROFILE_ERROR, g_FixedUserName));
}
return rc; }
PCTSTR GetUserProfilePath ( IN PCTSTR AccountName, OUT PTSTR *BufferPtr )
/*++
Routine Description:
Generates the full path to a user's profile. The user profile directory may have an extension (joeuser.001), and we must maintain that extension.
Arguments:
AccountName - Supplies the name of the user (fixed version, without the domain)
BufferPtr - Receives the full path to the user's profile directory, for example:
c:\windows\profiles\joeuser.001
This buffer must be freed with FreePathString.
Return Value:
A pointer to the user name with extension (joeuser.001) or NULL if something went terribly wrong.
--*/
{ PTSTR p; TCHAR ProfileNameWithExt[MEMDB_MAX];
//
// Get the profile path obtained from CreateUserProfile
//
p = (PTSTR) GetProfilePathForUser (AccountName);
if (p) {
*BufferPtr = DuplicatePathString (p, 0);
} else { //
// This is to guard against unexpected errors. The user
// will lose profile folder contents, but they can be recovered.
//
// Create %windir%\<user> (or <ProfileNameWithExt> if it exists)
//
MYASSERT (FALSE); // this should not happen
ProfileNameWithExt[0] = 0; MemDbGetEndpointValueEx ( MEMDB_CATEGORY_USER_PROFILE_EXT, AccountName, NULL, ProfileNameWithExt );
*BufferPtr = JoinPaths (g_WinDir, ProfileNameWithExt[0] ? ProfileNameWithExt : AccountName); }
//
// Return user name with suffix (i.e. joeuser.001)
//
p = _tcsrchr (*BufferPtr, TEXT('\\')); if (p) { p = _tcsinc (p); }
DEBUGMSG ((DBG_VERBOSE, "GetUserProfilePath: Account %s profile extension is %s", AccountName, p));
return p; }
BOOL pCopyDefaultShellFolders ( IN PCTSTR DestRoot ) { TCHAR DefFolders[MAX_TCHAR_PATH];
GetEnvironmentVariable (S_USERPROFILE, DefFolders, MAX_TCHAR_PATH);
return CopyTree ( DefFolders, DestRoot, 0, // no EnumTree ID
COPYTREE_DOCOPY | COPYTREE_NOOVERWRITE, ENUM_ALL_LEVELS, FILTER_ALL, NULL, // no exclude.inf struct
NULL, // no callback
NULL // no error callback
); }
VOID pSuppressEmptyWallpaper( VOID ) { HKEY Key; LONG rc; DWORD Size; TCHAR Buffer[MAX_TCHAR_PATH];
rc = TrackedRegOpenKeyEx95 (g_hKeyRoot95, S_DESKTOP_KEY, 0, KEY_READ, &Key); if (rc == ERROR_SUCCESS) {
Size = sizeof (Buffer); rc = Win95RegQueryValueEx ( Key, S_WALLPAPER, NULL, NULL, (PBYTE) Buffer, &Size );
if (rc == ERROR_SUCCESS) { if (!Buffer[0]) { TCHAR Node[MEMDB_MAX];
wsprintf ( Node, TEXT("%s\\%s\\[%s]"), S_HKR, S_DESKTOP_KEY, S_WALLPAPER );
DEBUGMSG ((DBG_VERBOSE, "Logon wallpaper is (none), suppressing %s", Node));
SuppressWin95Object (Node);
wsprintf ( Node, TEXT("%s\\%s\\[%s]"), S_HKR, S_DESKTOP_KEY, S_WALLPAPER_STYLE );
SuppressWin95Object (Node);
wsprintf ( Node, TEXT("%s\\%s\\[%s]"), S_HKR, S_DESKTOP_KEY, S_TILE_WALLPAPER );
SuppressWin95Object (Node); } ELSE_DEBUGMSG ((DBG_VERBOSE, "Logon wallpaper is '%s'", Buffer)); } ELSE_DEBUGMSG ((DBG_VERBOSE, "Logon wallpaper not specified in desktop key"));
CloseRegKey95 (Key); } ELSE_DEBUGMSG ((DBG_VERBOSE, "Logon wallpaper not specified")); }
DWORD RunPerUserExternalProcesses ( IN DWORD Request, IN PMIGRATE_USER_ENUM EnumPtr ) { LONG Count;
if (Request == REQUEST_QUERYTICKS) { //
// Count the number of entries and multiply by a constant
//
Count = SetupGetLineCount (g_UserMigInf, S_EXTERNAL_PROCESSES);
if (Count < 1) { return 0; }
return Count * TICKS_USER_EXTERN_PROCESSES; }
if (Request != REQUEST_RUN) { return ERROR_SUCCESS; }
//
// Loop through the processes and run each of them
//
RunExternalProcesses (g_UserMigInf, EnumPtr); return ERROR_SUCCESS; }
VOID pCheckY2KCompliance ( VOID ) { HKEY Key95, KeyNT; LONG rc; TCHAR Buffer[100]; DWORD Locale; int Result; PCTSTR ShortDate;
//
// read registry setting for sShortDate from Win9x registry
//
Key95 = OpenRegKey95 (g_hKeyRoot95, S_INTERNATIONAL_KEY); if (Key95) {
ShortDate = GetRegValueString95 (Key95, S_SHORT_DATE_VALUE); if (!ShortDate) { //
// set the new date format
//
GetGlobalCodePage (NULL, &Locale);
Result = GetLocaleInfo ( Locale, LOCALE_SSHORTDATE | LOCALE_NOUSEROVERRIDE, Buffer, sizeof (Buffer) / sizeof (TCHAR) ); if (Result > 0) {
KeyNT = OpenRegKey (g_hKeyRootNT, S_INTERNATIONAL_KEY); if (KeyNT) {
rc = RegSetValueEx ( KeyNT, S_SHORT_DATE_VALUE, 0, REG_SZ, (PCBYTE)Buffer, SizeOfString (Buffer) ); LOG_IF ((rc != ERROR_SUCCESS, LOG_ERROR, "Could not set [sShortDate] default format"));
CloseRegKey (KeyNT); } } ELSE_DEBUGMSG ((DBG_ERROR, "GetLocaleInfo returned 0 for LOCALE_SSHORTDATE | LOCALE_NOUSEROVERRIDE"));
} else {
DEBUGMSG (( DBG_VERBOSE, "HKR\\Control Panel\\International [sShortDate] already set to [%s] for user %s", ShortDate, g_FixedUserName ));
MemFree (g_hHeap, 0, (PVOID)ShortDate); }
CloseRegKey95 (Key95); } }
DWORD RunPerUserUninstallUserProfileCleanupPreparation( IN DWORD Request, IN PMIGRATE_USER_ENUM EnumPtr ) { LONG Count;
if (Request == REQUEST_QUERYTICKS) { //
// Count the number of entries and multiply by a constant
//
Count = SetupGetLineCount (g_UserMigInf, S_UNINSTALL_PROFILE_CLEAN_OUT);
#ifdef PROGRESS_BAR
DEBUGLOGTIME (("RunPerUserUninstallUserProfileCleanupPreparation: FileNumber=%ld", Count)); #endif
if (Count < 1) { return 0; }
return Count * TICKS_USER_UNINSTALL_CLEANUP; }
if (Request != REQUEST_RUN) { return ERROR_SUCCESS; }
//
// Loop through the files and mark them to be deleted during uninstall
//
UninstallUserProfileCleanupPreparation (g_UserMigInf, EnumPtr, FALSE);
return ERROR_SUCCESS; }
|