|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
dll.c
Abstract:
main file for the cross language migration tool
Author:
Xiaofeng Zang (xiaoz) 17-Sep-2001 Created
Revision History:
<alias> <date> <comments>
--*/
#include "StdAfx.h"
#include "clmt.h"
#include <winbase.h>
#include "clmtmsg.h"
BOOL CheckOS(DWORD); HRESULT DoRegistryAnalyze(); LONG AddEventSource(VOID); LONG CLMTReportEvent(WORD, WORD, DWORD, WORD, LPCTSTR*); void Deinit(BOOL); HRESULT DoCLMTCureProgramFiles(); HRESULT DoCLMTCleanUpAfterFirstReboot(); HRESULT DoCLMTCleanUpAfterDotNetUpgrade(); HRESULT DeleteUnwantedFilesPerUser(HKEY, LPCTSTR, LPCTSTR, LPTSTR); HRESULT DeleteUnwantedFiles(HINF, LPCTSTR); HRESULT AddRunValueToRegistry(LPCTSTR); INT DoCLMTDisplayAccountChangeDialog(); BOOL CALLBACK AccountChangeDlgProc(HWND, UINT, WPARAM, LPARAM); HRESULT UpdateHardLinkInfoPerUser(HKEY, LPCTSTR, LPCTSTR, LPTSTR); VOID RemoveFromRunKey(LPCTSTR);
/*++
Routine Description:
main entry point for the program
Arguments: if dwUndo != 0, we are in undo mode, otherwise...
Return Value:
TRUE - if succeeds --*/
LONG DoMig(DWORD dwMode) { HRESULT hr; HINF hMigrateInf = INVALID_HANDLE_VALUE; TCHAR szInfFile[MAX_PATH],*p; UINT iYesNo; DWORD dwRunStatus; DWORD dwCurrentState; DWORD dwNextState; TCHAR szProfileRoot[MAX_PATH]; DWORD cchLen; BOOL bOleInit = FALSE; DWORD dwOrgWinstationsState = 1; TCHAR szBackupDir[2*MAX_PATH]; TCHAR szRunOnce[2*MAX_PATH]; TCHAR szRun[2 * MAX_PATH]; HANDLE hExe = GetModuleHandle(NULL); UINT nRet; BOOL bMsgPopuped = FALSE; BOOL bWinStationChanged = FALSE; ULONG uErrMsgID; LONG err; TCHAR szSecDatabase[MAX_PATH]; BOOL bCleanupFailed; INT iRet; LCID lcid;
DPF(APPmsg, L"DoMig with dwMode = %d", dwMode);
//
// Only one instance of CLMT is allowed to run on the system
//
if (!IsOneInstance()) { return FALSE; }
//
// Only users with admin privilege can run the tool
//
if (!CheckAdminPrivilege()) { return FALSE; }
//
// Check if there are other tasks running on the system, quit CLMT
//
if (dwMode == CLMT_DOMIG && (!IsDebuggerPresent() && !g_fNoAppChk) && DisplayTaskList()) { return ERROR_SUCCESS; }
//
// Display Start Up dialog
//
if (dwMode == CLMT_DOMIG) { iRet = ShowStartUpDialog(); if (iRet == ID_STARTUP_DLG_CANCEL) { return ERROR_SUCCESS; } }
//
// Check to see if the operation is legal or not
//
hr = CheckCLMTStatus(&dwCurrentState, &dwNextState, &uErrMsgID); if (SUCCEEDED(hr)) { if (hr == S_OK) { DPF(dlInfo, TEXT("Operation [0x%X] is legal with current machine state [0x%X]"), g_dwRunningStatus, dwCurrentState); SetCLMTStatus(g_dwRunningStatus); } else { DPF(dlFail, TEXT("Operation [0x%X] is illegal with current machine state [0x%X]"), g_dwRunningStatus, dwCurrentState);
DoMessageBox(GetConsoleWindow(), uErrMsgID, IDS_MAIN_TITLE, MB_OK | MB_SYSTEMMODAL);
return FALSE; } } else { DPF(dlError, TEXT("Error occurred when trying to check CLMT and machine status - hr = 0x%X"), hr); return FALSE; }
//
// Verify the system if it is eligible to run CLMT
//
if (!CheckSystemCriteria()) { DPF(APPerr, TEXT("System Verification Failed!")); hr = E_FAIL; bMsgPopuped = TRUE; goto Exit; }
hr = InitDebugSupport(dwMode); if (FAILED(hr)) { DPF (APPerr, L"DLL.C: InitDebugSupport! Error: %d (%#x)", hr, hr); goto Exit; }
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(hr)) { DPF (APPerr, L"DLL.C: CoInitialize Failed! Error: %d (%#x)\n", hr, hr); goto Exit; } else { bOleInit = TRUE; }
// Initialize global variables
if (!InitGlobals(dwMode)) { hr = E_OUTOFMEMORY; DPF (APPerr, L"DLL.C: InitGlobal failure, out of memory!"); goto Exit; }
//we do not care the return value for LogMachineInfo
LogMachineInfo();
// Block new TS connections to be made during running CLMT
hr = DisableWinstations(1, &dwOrgWinstationsState); if (SUCCEEDED(hr)) { bWinStationChanged = TRUE; } else { //BUGBUG:Xiaoz:Add DLG pop up for failure
DPF (APPerr, L"DLL.C: Block new TS session failed: %d (%#x)\n", hr, hr); goto Exit; }
if (g_dwRunningStatus == CLMT_REMINDER) { BOOL bIsNTFS; hr = IsSysVolNTFS(&bIsNTFS); if ( (S_OK == hr) && !bIsNTFS) { //make sure hr is S_FALSE so that it will not pop up reboot dlg
hr = S_FALSE; DoMessageBox(GetConsoleWindow(), IDS_ASKING_CONVERT_TO_NTFS, IDS_MAIN_TITLE, MB_OK|MB_SYSTEMMODAL); goto Exit; } hr = S_FALSE; DoMessageBox(GetConsoleWindow(), IDS_REMIND_HARDLINK, IDS_MAIN_TITLE, MB_OK|MB_SYSTEMMODAL); goto Exit; } else if ( (g_dwRunningStatus == CLMT_CURE_PROGRAM_FILES) || (g_dwRunningStatus == CLMT_CURE_ALL) || (g_dwRunningStatus == CLMT_CURE_AND_CLEANUP) ) { hr = EnsureDoItemInfFile(g_szToDoINFFileName,ARRAYSIZE(g_szToDoINFFileName)); if (SUCCEEDED(hr)) { WritePrivateProfileSection(TEXT("Folder.ObjectRename"),NULL,g_szToDoINFFileName); WritePrivateProfileSection(TEXT("REG.Update.Sys"),NULL,g_szToDoINFFileName); WritePrivateProfileSection(TEXT("UserGrp.ObjectRename"),NULL,g_szToDoINFFileName); WritePrivateProfileSection(TEXT("LNK"),NULL,g_szToDoINFFileName); } LoopUser(UpdateHardLinkInfoPerUser); hr = DoCLMTCureProgramFiles(); if (hr == S_OK) { // We are done with curing Program Files hard link
CLMTSetMachineState(CLMT_STATE_PROGRAMFILES_CURED);
// remove "/CURE" rom Run registry key
RemoveFromRunKey(TEXT("/CURE"));
// Make sure hr = S_FALSE so that it will not pop up reboot dlg
hr = S_FALSE; }
if (g_dwRunningStatus == CLMT_CURE_AND_CLEANUP) { // Do the cleanup also if machine is already upgraded to .NET
// This scenario will happen only when Win2K FAT --> .NET FAT
// then run /CURE /FINAL in .NET
if (IsDotNet()) { CheckCLMTStatus(&dwCurrentState, &dwNextState, &uErrMsgID);
hr = DoCLMTCleanUpAfterDotNetUpgrade(); if (hr == S_OK) { CLMTSetMachineState(dwNextState);
// Remove "/FINAL" from Run registry key
RemoveFromRunKey(TEXT("/FINAL"));
// Make sure hr = S_FALSE so that it will not pop up reboot dlg
hr = S_FALSE; } } }
goto Exit; } else if (g_dwRunningStatus == CLMT_CLEANUP_AFTER_UPGRADE) { hr = DoCLMTCleanUpAfterDotNetUpgrade(); if (hr == S_OK) { // If the cleanup finished successfully
CLMTSetMachineState(dwNextState);
// Make sure hr = S_FALSE so that it will not pop up reboot dlg
hr = S_FALSE; }
goto Exit; }
hr = GetInfFilePath(szInfFile, ARRAYSIZE(szInfFile)); if (FAILED(hr)) { DPF(APPerr,TEXT("[CLMT : get inf file name failed !")); DoMessageBox(GetConsoleWindow(), IDS_CREATE_INF_FAILURE, IDS_MAIN_TITLE, MB_OK|MB_SYSTEMMODAL); bMsgPopuped = TRUE; goto Exit; }
hr = UpdateINFFileSys(szInfFile); if (FAILED(hr)) { DPF(APPerr,TEXT("CLMT : can not update per system settings in %s!"),szInfFile); switch (hr) { case E_NOTIMPL: DoMessageBox(GetDesktopWindow(), IDS_LANG_NOTSUPPORTED, IDS_MAIN_TITLE, MB_OK|MB_SYSTEMMODAL); break; default: DoMessageBox(GetConsoleWindow(), IDS_GENERAL_WRITE_FAILURE, IDS_MAIN_TITLE, MB_OK|MB_SYSTEMMODAL); break; } bMsgPopuped = TRUE; goto Exit; }
hMigrateInf = SetupOpenInfFile(szInfFile, NULL, INF_STYLE_WIN4, NULL); if (hMigrateInf != INVALID_HANDLE_VALUE) { g_hInf = hMigrateInf; } else { DPF(APPerr,TEXT("CLMT : can not open inf file %s!"),szInfFile); DoMessageBox(GetConsoleWindow(), IDS_OPEN_INF_FAILURE, IDS_MAIN_TITLE, MB_OK|MB_SYSTEMMODAL); hr = E_FAIL; bMsgPopuped = TRUE; goto Exit; }
//Copy myself to %windir%\$CLMT_BACKUP$ for future use, eg, runonce
if (!GetSystemWindowsDirectory(szBackupDir, ARRAYSIZE(szBackupDir))) { //BUGBUG:Xiaoz:Add DLG pop up for failure
DPF(APPerr, TEXT("Failed to get WINDIR")); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
ConcatenatePaths(szBackupDir,CLMT_BACKUP_DIR,ARRAYSIZE(szBackupDir)); if (S_OK != (hr = CopyMyselfTo(szBackupDir))) { //If can not copy, we will bail out, since most likely error is disk full
DPF(APPerr,TEXT("CLMT : can not copy clmt.exe to %s, error code = %d"),szBackupDir,HRESULT_CODE(hr)); goto Exit; }
//
// Run Winnt32 /Checkupgrade to check the system compatibility
//
if (g_fRunWinnt32) { if (!IsUserOKWithCheckUpgrade()) { hr = S_FALSE; goto Exit; } }
hr = EnsureDoItemInfFile(g_szToDoINFFileName,MAX_PATH); if (FAILED(hr)) { //BUGBUG:Xiaoz:Add DLG pop up for failure
DPF(APPerr,TEXT("CLMT : can not create global Todo list INF file !")); goto Exit; }
#ifdef NEVER
err = SDBCleanup(szSecDatabase,ARRAYSIZE(szSecDatabase),&bCleanupFailed); if ( (err != ERROR_SUCCESS) || bCleanupFailed ) { TCHAR szErrorMessage[2*MAX_PATH],szErrorTemplate[MAX_PATH],szCaption[MAX_PATH]; LoadString((HINSTANCE)g_hInstDll, IDS_SDBERROR, szErrorTemplate, ARRAYSIZE(szErrorTemplate)-1); hr = StringCchPrintf(szErrorMessage,ARRAYSIZE(szErrorMessage),szErrorTemplate,szSecDatabase); LoadString(g_hInstDll, IDS_MAIN_TITLE, szCaption, ARRAYSIZE(szCaption)-1); MessageBox(GetConsoleWindow(),szErrorMessage,szCaption, MB_OK|MB_SYSTEMMODAL); bMsgPopuped = TRUE; hr = E_FAIL; goto Exit; } #endif
#ifdef CONSOLE_UI
wprintf(TEXT("Analyzing all user shell folders ......\n")); #endif
hr = DoShellFolderRename(hMigrateInf,NULL,TEXT("System")); if (FAILED(hr)) { //BUGBUG:Xiaoz:Add DLG pop up for failure
DPF (APPerr, L"DLL.C: DoShellFolderRename Failed! Error: %d (%#x)\n", hr, hr); goto Exit; }
#ifdef CONSOLE_UI
wprintf(TEXT("Analyzing per user shell folders ......\n")); #endif
if (!LoopUser(MigrateShellPerUser)) { //BUGBUG:Xiaoz:Add DLG pop up for failure
DPF (APPerr, L"DLL.C: LoopUser with MigrateShellPerUser Failed"); hr = E_FAIL; goto Exit; } #ifdef CONSOLE_UI
wprintf(TEXT("Analyzing user and group name changes ......\n")); #endif
hr = UsrGrpAndDoc_and_SettingsRename(hMigrateInf,TRUE); if (FAILED(hr)) { //BUGBUG:Xiaoz:Add DLG pop up for failure
DPF (APPerr, L"DLL.C: UsrGrpAndDoc_and_SettingsRename Failed! Error: %d (%#x)", hr, hr); goto Exit; } if (!LoopUser(MigrateRegSchemesPerUser)) { //BUGBUG:Xiaoz:Add DLG pop up for failure
DPF (APPerr, L"DLL.C: LoopUser with MigrateRegSchemesPerUser Failed"); goto Exit; }
hr = MigrateRegSchemesPerSystem(hMigrateInf); if (FAILED(hr)) { //BUGBUG:Xiaoz:Add DLG pop up for failure
DPF (APPerr, L"DLL.C: MigrateRegSchemesPerSystem Failed! Error: %d (%#x)\n", hr, hr); goto Exit; }
#ifdef CONSOLE_UI
wprintf(TEXT("Analyzing IIS metabase ......\n")); #endif
hr = MigrateMetabaseSettings(hMigrateInf); if (FAILED(hr)) { //BUGBUG:Xiaoz:Add DLG pop up for failure
DPF (APPerr, L"DLL.C: MigrateMetabaseSettings! Error: %d (%#x)\n", hr, hr); goto Exit; }
hr = MetabaseAnalyze(NULL, &g_StrReplaceTable, TRUE); if (FAILED(hr)) { //BUGBUG:Xiaoz:Add DLG pop up for failure
DPF (APPerr, L"DLL.C: MetabaseAnalyze Failed! Error: %d (%#x)\n", hr, hr); goto Exit; }
// This EnumUserProfile will be enable after RC 1
//
//hr = EnumUserProfile(AnalyzeMiscProfilePathPerUser);
//if (FAILED(hr))
//{
// DPF (APPerr, L"DLL.C: EnumUserProfile with AnalyzeMiscProfilePathPerUser Failed");
// goto Exit;
//}
#ifdef CONSOLE_UI
wprintf(TEXT("Analyzing the entire registry ......\n")); #endif
hr = DoRegistryAnalyze(); if (FAILED(hr)) { //BUGBUG:Xiaoz:Add DLG pop up for failure
DPF (APPerr, L"DLL.C: DoRegistryAnalyze Failed! Error: %d (%#x)\n", hr, hr); goto Exit; }
#ifdef CONSOLE_UI
//wprintf(TEXT("Analyzing lnk files under profile directories ......\n"));
wprintf(TEXT("Analyzing LNK files under profile directories, please wait as this may\n")); wprintf(TEXT("take a few minutes ......\n")); #endif
//make sure the link file under profile dirrectory is updated
cchLen = ARRAYSIZE(szProfileRoot); if (GetProfilesDirectory(szProfileRoot,&cchLen)) { if (!MyEnumFiles(szProfileRoot,TEXT("lnk"),LnkFileUpdate)) { //BUGBUG:Xiaoz:Add DLG pop up for failure
hr = HRESULT_FROM_WIN32(GetLastError()); DPF (APPerr, L"DLL.C: EnumFiles Lnk File Failed! Error: %d (%#x)\n", hr, hr); goto Exit; } }
if (GetEnvironmentVariable(L"windir", szProfileRoot, MAX_PATH)) { hr = StringCchCat(szProfileRoot, MAX_PATH, TEXT("\\security\\templates")); if (!MyEnumFiles(szProfileRoot,TEXT("inf"),SecTempUpdate)) { //BUGBUG:Xiaoz:Add DLG pop up for failure
hr = HRESULT_FROM_WIN32(GetLastError()); DPF (APPerr, L"DLL.C: EnumFiles security template File Failed! Error: %d (%#x)\n", hr, hr); goto Exit; } }
hr = FolderMove(hMigrateInf,TEXT("Generic.Folder.ObjectRename.PerSystem"),TRUE); if (FAILED(hr)) { DPF (APPerr, L"DLL.C: FolderMove Failed! Error: %d (%#x)\n", hr, hr); goto Exit; }
FRSUpdate(); Ex2000Update();
// Analyze the services reconfiguration
DoServicesAnalyze();
// Add event log source to registry
AddEventSource();
// Log an event into event log
CLMTReportEvent(EVENTLOG_INFORMATION_TYPE, STATUS_SEVERITY_INFORMATIONAL, MSG_CLMT_STARTED, 0, NULL);
// Display the Administrator Account Change dialog
GetSavedInstallLocale(&lcid); if (lcid != 0x411) { // we ignore displaying this dialog on JPN
iRet = DoCLMTDisplayAccountChangeDialog(); if (iRet == ID_STARTUP_DLG_CANCEL) { iRet = DoMessageBox(GetConsoleWindow(), IDS_CONFIRM_OPERATION, IDS_MAIN_TITLE, MB_OKCANCEL); if (iRet == IDCANCEL) { goto Exit; } } }
//
// Do the critical system changes here...
//
nRet = (UINT) DialogBoxParam(hExe, MAKEINTRESOURCE(IDD_UPDATESYSTEM), GetConsoleWindow(), (DLGPROC) DoCriticalDlgProc, (LPARAM) NULL); if (nRet == ID_UPDATE_DONE) { hr = S_OK; } else { hr = S_FALSE; }
// Set machine state after operation is done
if (hr == S_OK) { // Add cure program files switch to Run key
AddRunValueToRegistry(TEXT("/CURE /FINAL"));
// Set machine to next state
CLMTSetMachineState(dwNextState);
// Tool has finished, report to event log
CLMTReportEvent(EVENTLOG_INFORMATION_TYPE, STATUS_SEVERITY_INFORMATIONAL, MSG_CLMT_FINISHED, 0, NULL); }
Exit: if (bWinStationChanged) { // Return the WinStations status to original state
DisableWinstations(dwOrgWinstationsState, NULL); }
if (hMigrateInf != INVALID_HANDLE_VALUE) { SetupCloseInfFile(hMigrateInf); g_hInf = INVALID_HANDLE_VALUE ; } Deinit(bOleInit); CloseDebug(); EnablePrivilege(SE_SHUTDOWN_NAME,FALSE); EnablePrivilege(SE_BACKUP_NAME,FALSE); EnablePrivilege(SE_RESTORE_NAME,FALSE); EnablePrivilege(SE_SYSTEM_ENVIRONMENT_NAME,FALSE); if (hr == S_OK) { ReStartSystem(EWX_REBOOT); } else if ( FAILED(hr) && !bMsgPopuped) { DoMessageBox(GetConsoleWindow(), IDS_FATALERROR, IDS_MAIN_TITLE, MB_OK|MB_SYSTEMMODAL); } return HRESULT_CODE(hr); }
//-----------------------------------------------------------------------------
//
// Function: MigrateShellPerUser
//
// Synopsis: Rename shell folders for each user
//
// Returns: HRESULT
//
// History: 03/08/2002 Rerkboos Add log + code clean up
//
// Notes: None.
//
//-----------------------------------------------------------------------------
HRESULT MigrateShellPerUser( HKEY hKeyUser, LPCTSTR UserName, LPCTSTR DomainName, LPTSTR UserSid ) { TCHAR InfoBuff[1000]; HINF hMigrateInf = INVALID_HANDLE_VALUE; TCHAR szInfFile[MAX_PATH]; HRESULT hr;
DPF(APPmsg, TEXT("Enter MigrateShellPerUser:"));
// Get per-user temporary INF file name
hr = GetInfFilePath(szInfFile, ARRAYSIZE(szInfFile)); if (SUCCEEDED(hr)) { // Update per-syste data to temp INF file
hr = UpdateINFFileSys(szInfFile); if (SUCCEEDED(hr)) { // Update per-user data to temp INF file
hr = UpdateINFFilePerUser(szInfFile, UserName, UserSid, FALSE); if (SUCCEEDED(hr)) { DPF(APPmsg, TEXT("Per-user INF file was updated successfully")); } else { DPF(APPerr, TEXT("Failed to update per-user data in INF")); } } else { DPF(APPerr, TEXT("Failed to update per-system data in INF")); } } else { DPF(APPerr, TEXT("Faild to get per-user INF file name")); }
#ifdef CONSOLE_UI
wprintf(TEXT("analyzing settings for user %s \n"), UserName); #endif
if (SUCCEEDED(hr)) { // Open per-user INF file
hMigrateInf = SetupOpenInfFile(szInfFile, NULL, INF_STYLE_WIN4, NULL); if (hMigrateInf != INVALID_HANDLE_VALUE) { // Rename shell folders for the user
hr = DoShellFolderRename(hMigrateInf, hKeyUser, (LPTSTR) UserName); SetupCloseInfFile(hMigrateInf); DeleteFile(szInfFile); if (SUCCEEDED(hr)) { DPF(APPmsg, TEXT("Rename per-user shell folders successfully")); } else { DPF(APPerr, TEXT("Rename per-user shell folders Failed")); } } else { hr = HRESULT_FROM_WIN32(GetLastError()); DPF(APPerr, TEXT("Failed to open per-user INF file")); } }
DPF(APPmsg, TEXT("Exit MigrateShellPerUser:"));
return hr; }
/*++
Routine Description:
This routine initializes the global variables used in the program
Arguments: Return Value:
TRUE - if succeeds --*/ BOOL InitGlobals(DWORD dwRunStatus) { BOOL bRet = TRUE; int i, n; DWORD dwMachineState; HRESULT hr;
// Get the module handle to ourself
g_hInstDll = GetModuleHandle(NULL);
// Check if the machine has not run CLMT yet
hr = CLMTGetMachineState(&dwMachineState); g_bBeforeMig = (SUCCEEDED(hr) && dwMachineState == CLMT_STATE_ORIGINAL);
//Init the global string search-replacement table
if(!InitStrRepaceTable()) { DoMessageBox(GetConsoleWindow(), IDS_OUT_OF_MEMORY, IDS_MAIN_TITLE, MB_OK|MB_SYSTEMMODAL); bRet = FALSE; }
return bRet; }
/*++
Routine Description:
This routine checks the various OS properties to make sure that the tool cab be run
Arguments: Return Value:
TRUE - if the clmt tool can be run on the current platform . --*/
BOOL CheckOS(DWORD dwMode) { TCHAR Text[MAX_PATH]; BOOL bRet = TRUE; LCID lcid; HRESULT hr; BOOL bIsAdmin; OSVERSIONINFOEX osviex;
if (FAILED(StringCchPrintf (Text, ARRAYSIZE(Text), TEXT("Global\\%s"), TEXT("CLMT Is Running")))) { bRet = FALSE; goto Cleanup; }
g_hMutex = CreateMutex(NULL,FALSE,Text);
if ((g_hMutex == NULL) && (GetLastError() == ERROR_PATH_NOT_FOUND)) { g_hMutex = CreateMutex(NULL,FALSE,TEXT("CLMT Is Running")); if(g_hMutex == NULL) { //
// An error (like out of memory) has occurred.
// Bail now.
//
DoMessageBox(GetConsoleWindow(), IDS_OUT_OF_MEMORY, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; } }
//
// Make sure we are the only process with a handle to our named mutex.
//
if ((g_hMutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) { DoMessageBox(GetConsoleWindow(), IDS_ALREADY_RUNNING, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; }
if (dwMode == CLMT_DOMIG) { if (!IsNT5()) { DoMessageBox(GetConsoleWindow(), IDS_NT5, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; }
if (IsDomainController()) { //
// If this machine is a domain controller, we need W2K SP2
//
ZeroMemory(&osviex, sizeof(OSVERSIONINFOEX)); osviex.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); GetVersionEx((LPOSVERSIONINFO) &osviex); bRet = (osviex.wServicePackMajor >= 2 ? TRUE : FALSE); if (!bRet) { DoMessageBox(GetConsoleWindow(), IDS_NT5SP2, IDS_MAIN_TITLE, MB_OK); goto Cleanup; }
//
// Also pop up the message asking admin to take machine
// off the network if it is in DC replication servers
//
DoMessageBox(GetConsoleWindow(), IDS_DC_REPLICA_OFFLINE, IDS_MAIN_TITLE, MB_OK); } } else if (dwMode == CLMT_CLEANUP_AFTER_UPGRADE) { if (!IsDotNet()) { bRet = FALSE; goto Cleanup; } } else { //for undo code here
//BUGBUG:XIAOZ Adding code here
}
if (IsNEC98()) { DoMessageBox(GetConsoleWindow(), IDS_NEC98, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; }
if (IsIA64()) { DoMessageBox(GetConsoleWindow(), IDS_IA64, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; }
if (IsOnTSClient()) { DoMessageBox(GetConsoleWindow(), IDS_ON_TS_CLIENT, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; }
//if (IsTSServiceRunning() && IsTSConnectionEnabled())
//{
// DoMessageBox(GetConsoleWindow(), IDS_TS_ENABLED, IDS_MAIN_TITLE, MB_OK);
// bRet = FALSE;
// goto Cleanup;
//}
if (IsOtherSessionOnTS()) { DoMessageBox(GetConsoleWindow(), IDS_TS_CLOSE_SESSION, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; }
bIsAdmin = IsAdmin(); if (dwMode == CLMT_DOMIG) { if (!bIsAdmin) { DoMessageBox(GetConsoleWindow(), IDS_ADMIN, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; }
if (g_fRunWinnt32) { if (!IsUserOKWithCheckUpgrade()) { bRet = FALSE; goto Cleanup; } } hr = GetSavedInstallLocale(&lcid); if (HRESULT_CODE(hr) == ERROR_FILE_NOT_FOUND) { hr = SaveInstallLocale(); if (FAILED(hr)) { bRet = FALSE; } } } else if ( (dwMode == CLMT_CURE_PROGRAM_FILES) || (dwMode == CLMT_CURE_ALL) ) { if (!bIsAdmin) { DoMessageBox(GetConsoleWindow(), IDS_ADMIN, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; } } else if (dwMode == CLMT_CLEANUP_AFTER_UPGRADE) { if (!bIsAdmin) { DoMessageBox(GetConsoleWindow(), IDS_ADMIN_LOGON_DOTNET, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; } }
if(!DoesUserHavePrivilege(SE_SHUTDOWN_NAME) || !DoesUserHavePrivilege(SE_BACKUP_NAME) || !DoesUserHavePrivilege(SE_RESTORE_NAME) || !DoesUserHavePrivilege(SE_SYSTEM_ENVIRONMENT_NAME)) { DoMessageBox(GetConsoleWindow(), IDS_ADMIN, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; } if(!EnablePrivilege(SE_SHUTDOWN_NAME,TRUE) || !EnablePrivilege(SE_BACKUP_NAME,TRUE) || !EnablePrivilege(SE_RESTORE_NAME,TRUE) || !EnablePrivilege(SE_SYSTEM_ENVIRONMENT_NAME,TRUE)) { DoMessageBox(GetConsoleWindow(), IDS_ADMIN, IDS_MAIN_TITLE, MB_OK); bRet = FALSE; goto Cleanup; }
//else //This means undo which we do not need user to provide .net CD
//{
// DWORD dwStatusinReg;
// hr = CLMTGetMachineState(&dwStatusinReg);
// if ( (hr != S_OK) || (CLMT_STATE_MIGRATION_DONE != dwStatusinReg))
// {
// DPF (APPerr, L"DLL.C: can not get the CLMT status from registry or you have not run the clmt tools!");
// //BUGBUG:XIAOZ:ADD a DLG here
// bRet = FALSE;
// goto Cleanup;
// }
//}
Cleanup: return bRet; }
/*++
Routine Description:
This routine does system wide registry search and replace, the string replace table is in global variable g_StrReplaceTable
Arguments:
hKeyUser - user registry key handle UserName - user name that hKeyUser belongs to DomainName - domain name the UserName belongs to Return Value:
TRUE - if succeeds. --*/
HRESULT DoRegistryAnalyze() { LPTSTR lpUser,lpSearchStr,lpReplaceStr,lpFullPath; UINT i; //TCHAR szExcludeList[] = TEXT("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\0\0");
TCHAR szExcludeList[] = TEXT("HKLM\\Software\\Microsoft\\Shared Tools\\Stationery\0\0"); LPTSTR lpszExcludeList = NULL; HRESULT hr ;
{ HKEY hkey; LONG lRes; lRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\DRM"), 0,KEY_ALL_ACCESS,&hkey); if (ERROR_SUCCESS == lRes) { hr = RegistryAnalyze(hkey,NULL,NULL,&g_StrReplaceTable,lpszExcludeList,REG_SZ, TEXT("HKLM\\SOFTWARE\\Microsoft\\DRM"),TRUE); RegCloseKey(hkey); } } if (!LoopUser(UpdateRegPerUser)) { hr = E_FAIL; } else { lpszExcludeList = malloc(MultiSzLen(szExcludeList)*sizeof(TCHAR)); if (lpszExcludeList) { memmove((LPBYTE)lpszExcludeList,(LPBYTE)szExcludeList,MultiSzLen(szExcludeList)*sizeof(TCHAR)); //hr = RegistryAnalyze(HKEY_LOCAL_MACHINE,NULL,NULL,&g_StrReplaceTable,lpszExcludeList,FALSE,NULL);
hr = RegistryAnalyze(HKEY_LOCAL_MACHINE,NULL,NULL,&g_StrReplaceTable,NULL,FALSE,NULL,TRUE); free(lpszExcludeList); } else { hr = E_OUTOFMEMORY; } } return hr; }
//-----------------------------------------------------------------------
//
// Function: AddEventSource
//
// Descrip: Add EventLog source to registry
//
// Returns: Win32 Error Code
//
// Notes:
//
// History: 03/05/2002 rerkboos Created
//
// Notes: none.
//
//-----------------------------------------------------------------------
LONG AddEventSource(VOID) { HKEY hKey; LONG lRet; TCHAR szMessageFile[MAX_PATH+1];
if (GetModuleFileName(NULL, szMessageFile, ARRAYSIZE(szMessageFile)-1)) { szMessageFile[ARRAYSIZE(szMessageFile)-1] = TEXT('\0'); lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\CLMT"), 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL); if (lRet == ERROR_SUCCESS) { lRet = RegSetValueEx(hKey, TEXT("EventMessageFile"), 0, REG_EXPAND_SZ, (LPBYTE) szMessageFile, sizeof(szMessageFile)); if (lRet == ERROR_SUCCESS) { DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
lRet = RegSetValueEx(hKey, TEXT("TypesSupported"), 0, REG_DWORD, (LPBYTE) &dwData, sizeof(dwData)); }
RegCloseKey(hKey); } } else { lRet = GetLastError(); }
return lRet; }
//-----------------------------------------------------------------------
//
// Function: ReportEvent
//
// Descrip: Report event to Event Log
//
// Returns: Win32 Error Code
//
// Notes:
//
// History: 03/05/2002 rerkboos Created
//
// Notes: none.
//
//-----------------------------------------------------------------------
LONG CLMTReportEvent( WORD wType, // Event type
WORD wCategory, // Event category
DWORD dwEventID, // Event identifier
WORD wNumSubstitute, // Number of strings to merge
LPCTSTR *lplpMessage // Pointer to message string array
) { HANDLE hEventLog; LONG lRet; TCHAR szUserName[UNLEN + 1]; DWORD cchUserName = ARRAYSIZE(szUserName);
hEventLog = RegisterEventSource(NULL, TEXT("CLMT")); if (hEventLog) { // Get the user name who run the tool
if (GetUserName(szUserName, &cchUserName)) { LPVOID lpSidCurrentUser; DWORD cbSid; TCHAR szDomainName[MAX_PATH]; DWORD cbDomainName = ARRAYSIZE(szDomainName) * sizeof(TCHAR); SID_NAME_USE sidNameUse;
// Allocate enough memory for largest possible SID
cbSid = SECURITY_MAX_SID_SIZE; lpSidCurrentUser = MEMALLOC(cbSid);
if (lpSidCurrentUser) { if (LookupAccountName(NULL, szUserName, (PSID) lpSidCurrentUser, &cbSid, szDomainName, &cbDomainName, &sidNameUse)) { if (ReportEvent(hEventLog, wType, wCategory, dwEventID, (PSID) lpSidCurrentUser, wNumSubstitute, 0, lplpMessage, NULL)) { lRet = ERROR_SUCCESS; } else { lRet = GetLastError(); } } else { lRet = GetLastError(); }
MEMFREE(lpSidCurrentUser); } } else { if (ReportEvent(hEventLog, wType, wCategory, dwEventID, NULL, wNumSubstitute, 0, lplpMessage, NULL)) { lRet = ERROR_SUCCESS; } else { lRet = GetLastError(); } }
DeregisterEventSource(hEventLog); } else { lRet = GetLastError(); }
return lRet; }
void Deinit(BOOL bOleInit) { if (g_hMutex) { CloseHandle(g_hMutex); } if (INVALID_HANDLE_VALUE != g_hInf) { SetupCloseInfFile(g_hInf); } DeInitStrRepaceTable();
if (bOleInit) { CoUninitialize(); } }
//-----------------------------------------------------------------------
//
// Function: DoCLMTCleanUpAfterFirstReboot
//
// Descrip: Do the clean up after the machine has been run CLMT and
// reboot (before upgraded to .NET)
//
// Returns: S_OK if cure Program Files successfully
// S_FALSE if Program Files cannot be cured (no error)
// Else if error occurred
//
// History: 07/18/2002 rerkboos Created
//
// Notes: none.
//
//-----------------------------------------------------------------------
HRESULT DoCLMTCureProgramFiles() { HRESULT hr; BOOL bIsNTFS; LONG lRet; HKEY hRunKey;
hr = IsSysVolNTFS(&bIsNTFS); if ((S_OK == hr) && !bIsNTFS) { hr = S_FALSE; DoMessageBox(GetConsoleWindow(), IDS_ASKING_CONVERT_TO_NTFS, IDS_MAIN_TITLE, MB_OK | MB_SYSTEMMODAL); goto EXIT; }
hr = INFCreateHardLink(INVALID_HANDLE_VALUE, FOLDER_CREATE_HARDLINK, TRUE); if (FAILED(hr)) { DPF(APPerr, L"DLL.C: INFCreateHardLink returned error: %d (%#x)\n", hr, hr); hr = S_FALSE; } else { hr = S_OK; }
EXIT: return hr; }
//-----------------------------------------------------------------------
//
// Function: DoCLMTCleanUpAfterFirstReboot
//
// Descrip: Do the clean up after the machine has been run CLMT and
// reboot (before upgraded to .NET)
//
// Returns: S_OK if no error occured
//
// History: 07/18/2002 rerkboos Created
//
// Notes: none.
//
//-----------------------------------------------------------------------
HRESULT DoCLMTCleanUpAfterFirstReboot() { HRESULT hr; TCHAR szInfFile[MAX_PATH]; HKEY hRunKey; LONG lRet;
g_hInf = INVALID_HANDLE_VALUE;
// Load INF
hr = GetInfFilePath(szInfFile, ARRAYSIZE(szInfFile)); if (SUCCEEDED(hr)) { hr = UpdateINFFileSys(szInfFile); if (SUCCEEDED(hr)) { g_hInf = SetupOpenInfFile(szInfFile, NULL, INF_STYLE_WIN4, NULL); if (g_hInf == INVALID_HANDLE_VALUE) { hr = HRESULT_FROM_WIN32(GetLastError()); } } }
if (FAILED(hr)) { return hr; }
//
// do the per-system clean up stuffs here...
//
// Close the current INF file to update settings in INF
// Here, each callback function of LoopUser() must call UpdateINFFilePerUser
// to update per-user settings
SetupCloseInfFile(g_hInf); g_hInf = INVALID_HANDLE_VALUE;
//
// do the per-user clean up stuffs here...
//
LoopUser(DeleteUnwantedFilesPerUser);
// Cleanup the variables
if (g_hInf != INVALID_HANDLE_VALUE) { SetupCloseInfFile(g_hInf); g_hInf = INVALID_HANDLE_VALUE; }
// Return S_FALSE because we don't want to reboot the machine
return S_FALSE; }
//-----------------------------------------------------------------------
//
// Function: DoCLMTCleanUpAfterDotNetUpgrade
//
// Descrip: Do the clean up after the machine has been run CLMT and
// upgraded to .NET
//
// Returns: S_OK if no error occured
//
// History: 07/09/2002 rerkboos Created
//
// Notes: none.
//
//-----------------------------------------------------------------------
HRESULT DoCLMTCleanUpAfterDotNetUpgrade() { HRESULT hr = S_OK; TCHAR szInfFile[MAX_PATH]; TCHAR szToDoInfFile[MAX_PATH]; HKEY hRunKey; LONG lRet;
g_hInf = INVALID_HANDLE_VALUE; g_hInfDoItem = INVALID_HANDLE_VALUE;
DPF(APPmsg, TEXT("[Enter CleanupAfterDotNetUpgrade]")); //
// Load Migrate INF
//
hr = GetInfFilePath(szInfFile, ARRAYSIZE(szInfFile)); if (SUCCEEDED(hr)) { hr = UpdateINFFileSys(szInfFile); if (SUCCEEDED(hr)) { g_hInf = SetupOpenInfFile(szInfFile, NULL, INF_STYLE_WIN4, NULL); if (g_hInf == INVALID_HANDLE_VALUE) { hr = HRESULT_FROM_WIN32(GetLastError()); } } }
if (g_hInf == INVALID_HANDLE_VALUE) { return hr; }
//
// Load ClmtDo.inf
//
if (GetSystemWindowsDirectory(szToDoInfFile, ARRAYSIZE(szToDoInfFile))) { if (ConcatenatePaths(szToDoInfFile, CLMT_BACKUP_DIR, ARRAYSIZE(szToDoInfFile))) { if (ConcatenatePaths(szToDoInfFile, TEXT("CLMTDO.INF"), ARRAYSIZE(szToDoInfFile))) { g_hInfDoItem = SetupOpenInfFile(szToDoInfFile, NULL, INF_STYLE_WIN4, NULL); } } }
if (g_hInfDoItem == INVALID_HANDLE_VALUE) { hr = HRESULT_FROM_WIN32(GetLastError()); return hr; }
//
// Do the CLMT Cleanup (Per System) stuffs here...
//
ResetServicesStatus(g_hInfDoItem, TEXT_SERVICE_STATUS_CLEANUP_SECTION); ResetServicesStartUp(g_hInfDoItem, TEXT_SERVICE_STARTUP_CLEANUP_SECTION);
DeleteUnwantedFiles(g_hInf, TEXT("Folders.PerSystem.Cleanup"));
INFVerifyHardLink(g_hInfDoItem,TEXT("Folder.HardLink"));
// Close the current INF file to update settings in INF
// Each Call back function of LoopUser() must call UpdateINFFilePerUser
// to update per-user settings
SetupCloseInfFile(g_hInf); g_hInf = INVALID_HANDLE_VALUE;
// Close ClmtDo.inf handle, as we don't need it anymore
SetupCloseInfFile(g_hInfDoItem);
//
// Do the CLMT Cleanup (Per User) stuffs here...
//
LoopUser(DeleteUnwantedFilesPerUser);
// Remove CLMT from registry Run key
lRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT_RUN_KEY, &hRunKey); if (lRet == ERROR_SUCCESS) { RemoveFromRunKey(TEXT("/FINAL")); RegCloseKey(hRunKey); }
//
// Cleanup the variables
//
if (g_hInf != INVALID_HANDLE_VALUE) { SetupCloseInfFile(g_hInf); }
DPF(APPmsg, TEXT("[Exit CleanupAfterDotNetUpgrade]"));
return S_OK; }
//-----------------------------------------------------------------------
//
// Function: DeleteUnwantedFiles
//
// Descrip: Delete unwanted files and directories after the machine
// has been upgraded to .NET. The list of files/directories
// are listed in INF.
// File/directory will be deleted if and only if Loc file name
// does not match the expected English file name. This prevents
// deleting English file/directory.
//
// Returns: S_OK if no error occured
//
// History: 07/09/2002 rerkboos Created
//
// Notes: Format in INF:
// <FileType>, <Loc File to be deleted>, <Expected Eng File>
//
// FileType:- 0 = Directory
// 1 = File
//
//-----------------------------------------------------------------------
HRESULT DeleteUnwantedFiles( HINF hInf, LPCTSTR lpInfSection ) { HRESULT hr = S_OK; BOOL bRet = TRUE; LONG lLineCount; LONG lLineIndex; INT iFileType; TCHAR szFileName[2 * MAX_PATH]; TCHAR szEngFileName[2 * MAX_PATH]; INFCONTEXT context;
if (hInf == INVALID_HANDLE_VALUE || lpInfSection == NULL) { return E_INVALIDARG; }
// Read the list of services to be reset from INF
lLineCount = SetupGetLineCount(hInf, lpInfSection); if (lLineCount >= 0) { for (lLineIndex = 0 ; lLineIndex < lLineCount && bRet ; lLineIndex++) { bRet = SetupGetLineByIndex(hInf, lpInfSection, (DWORD) lLineIndex, &context); if (bRet) { bRet = SetupGetIntField(&context, 1, &iFileType) && SetupGetStringField(&context, 2, szFileName, ARRAYSIZE(szFileName), NULL) && SetupGetStringField(&context, 3, szEngFileName, ARRAYSIZE(szEngFileName), NULL); if (bRet && MyStrCmpI(szFileName, szEngFileName) != LSTR_EQUAL) { switch (iFileType) { case 0: // Directories
hr = DeleteDirectory(szFileName); if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_PATH_NOT_FOUND) { goto EXIT; }
break;
case 1: // Files
hr = MyDeleteFile(szFileName); if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_PATH_NOT_FOUND) { goto EXIT; }
break; } } } } }
hr = (bRet ? S_OK : HRESULT_FROM_WIN32(GetLastError()));
EXIT: return hr; }
//-----------------------------------------------------------------------
//
// Function: DeleteUnwantedFilesPerUser
//
// Descrip: This is a call back function for LoopUser().
//
// Returns: S_OK if no error occured
//
// History: 07/09/2002 rerkboos Created
//
// Notes: Format in INF:
// <FileType>, <Loc File to be deleted>, <Expected Eng File>
//
// FileType:- 0 = Directory
// 1 = File
//
//-----------------------------------------------------------------------
HRESULT DeleteUnwantedFilesPerUser( HKEY hKeyUser, LPCTSTR UserName, LPCTSTR DomainName, LPTSTR UserSid ) { HRESULT hr = S_OK;
hr = UpdateINFFilePerUser(g_szInfFile, UserName ,UserSid , FALSE); if (SUCCEEDED(hr)) { g_hInf = SetupOpenInfFile(g_szInfFile, NULL, INF_STYLE_WIN4, NULL); if (g_hInf != INVALID_HANDLE_VALUE) { // Delete files/directories here
hr = DeleteUnwantedFiles(g_hInf, TEXT("Folders.PerUser.Cleanup"));
// Close Inf file for this user
SetupCloseInfFile(g_hInf); g_hInf = INVALID_HANDLE_VALUE; } else { hr = HRESULT_FROM_WIN32(GetLastError()); } }
return hr; }
//-----------------------------------------------------------------------
//
// Function: AddRunValueToRegistry
//
// Descrip: This will add "CLMT /switch" to Run key. So CLMT can
// do the cleanup stuffs after next reboot.
//
// Returns: S_OK if no error occured
//
// History: 07/29/2002 rerkboos Created
//
// Notes: lpCmdSwitch should be supplied in format "/something"
//
//-----------------------------------------------------------------------
HRESULT AddRunValueToRegistry( LPCTSTR lpCmdSwitch ) { HRESULT hr = S_FALSE; TCHAR szBackupDir[MAX_PATH]; TCHAR szRun[MAX_PATH];
DPF(dlInfo, TEXT("Add CLMT with switch '%s' to Run key"), lpCmdSwitch);
if (GetSystemWindowsDirectory(szBackupDir, ARRAYSIZE(szBackupDir))) { if (ConcatenatePaths(szBackupDir, CLMT_BACKUP_DIR, ARRAYSIZE(szBackupDir))) { hr = StringCchCopy(szRun, ARRAYSIZE(szRun), szBackupDir); if (SUCCEEDED(hr)) { if (ConcatenatePaths(szRun, TEXT("\\CLMT.EXE "), ARRAYSIZE(szRun))) { hr = StringCchCat(szRun, ARRAYSIZE(szRun), lpCmdSwitch); if (SUCCEEDED(hr)) { SetRunValue(TEXT_CLMT_RUN_VALUE, szRun); } } } } }
return hr; }
//-----------------------------------------------------------------------
//
// Function: DoCLMTDisplayAccountChangeDialog
//
// Descrip: Display the dialog notify user of Administrator account
// name change.
//
// Returns: n/a
//
// History: 07/29/2002 rerkboos Created
//
// Notes: none.
//
//-----------------------------------------------------------------------
INT DoCLMTDisplayAccountChangeDialog() { return (INT) DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_STARTUP_DLG), GetConsoleWindow(), (DLGPROC) AccountChangeDlgProc, (LPARAM) NULL); }
//-----------------------------------------------------------------------------
//
// Function: AccountChangeDlgProc
//
// Synopsis: Dialog box procedure
//
// Returns:
//
// History: 9/02/2002 rerkboos created
//
// Notes: none
//
//-----------------------------------------------------------------------------
BOOL CALLBACK AccountChangeDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { BOOL bRet; DWORD dwErr; TCHAR szOldAdminName[64]; TCHAR szAdminChange[1024]; LPTSTR lpArgs[1];
switch (uMsg) { case WM_INITDIALOG: // Init the dialog
ShowWindow(hwndDlg, SW_SHOWNORMAL);
bRet = GetUserNameChangeLog(TEXT("Administrator"), szOldAdminName, ARRAYSIZE(szOldAdminName)); if (bRet) { lpArgs[0] = szOldAdminName;
dwErr = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, MSG_CLMT_ADMIN_ACCT_CHANGE, 0, szAdminChange, ARRAYSIZE(szAdminChange), (va_list *) lpArgs); } else { dwErr = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, MSG_CLMT_ACCT_CHANGE, 0, szAdminChange, ARRAYSIZE(szAdminChange), NULL); }
SendMessage(GetDlgItem(hwndDlg, ID_STARTUP_DLG_INFO), WM_SETTEXT, wParam, (LPARAM) szAdminChange);
case WM_COMMAND: // Handle command buttons
switch (wParam) { case ID_STARTUP_DLG_NEXT: EndDialog(hwndDlg, ID_STARTUP_DLG_NEXT); break;
case ID_STARTUP_DLG_CANCEL: EndDialog(hwndDlg, ID_STARTUP_DLG_CANCEL); break;
case ID_STARTUP_DLG_README: ShowReadMe(); break; } break;
case WM_CLOSE: EndDialog(hwndDlg, ID_STARTUP_DLG_CANCEL); break;
default: break; }
return FALSE; }
HRESULT UpdateHardLinkInfoPerUser( HKEY hKeyUser, LPCTSTR UserName, LPCTSTR DomainName, LPTSTR UserSid) { HRESULT hr; HINF hInf;
if (!MyStrCmpI(UserSid,TEXT("Default_User_SID"))) { return S_OK; } hr = EnsureDoItemInfFile(g_szToDoINFFileName,ARRAYSIZE(g_szToDoINFFileName)); if (FAILED(hr)) { goto Cleanup; } hr = UpdateINFFilePerUser(g_szToDoINFFileName, UserName , UserSid, FALSE); hInf = SetupOpenInfFile(g_szToDoINFFileName, NULL, INF_STYLE_WIN4,NULL); if (hInf != INVALID_HANDLE_VALUE) { INT LineCount,LineNo; INFCONTEXT InfContext;
LineCount = (UINT)SetupGetLineCount(hInf,TEXT("Folder.HardLink.Peruser")); if ((LONG)LineCount > 0) { for (LineNo = 0; LineNo < LineCount; LineNo++) { BOOL b0, b1, b2, b3; TCHAR szKeyName[MAX_PATH], szType[10], szFileName[MAX_PATH+1], szExistingFileName[MAX_PATH+1];
if (!SetupGetLineByIndex(hInf,TEXT("Folder.HardLink.Peruser"),LineNo,&InfContext)) { continue; } b0 = SetupGetStringField(&InfContext,0,szKeyName,ARRAYSIZE(szKeyName),NULL); b1 = SetupGetStringField(&InfContext,1,szType,ARRAYSIZE(szType),NULL); b2 = SetupGetStringField(&InfContext,2,szFileName,ARRAYSIZE(szFileName),NULL); b3 = SetupGetStringField(&InfContext,3,szExistingFileName,ARRAYSIZE(szExistingFileName),NULL); if (!b0 || !b1 || !b2 || !b3) { continue; }
AddHardLinkEntry(szFileName,szExistingFileName,szType,NULL,NULL,szKeyName); } } SetupCloseInfFile(hInf); } Cleanup : return hr; }
VOID RemoveFromRunKey( LPCTSTR lpCLMTOption // Option to be deleted from Run key
) { HKEY hRunKey; LONG lRet; TCHAR szRunValue[MAX_PATH]; DWORD cbRunValue; DWORD dwType;
// Remove CLMT from registry Run key
lRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT_RUN_KEY, &hRunKey); if (lRet == ERROR_SUCCESS) { cbRunValue = sizeof(szRunValue);
lRet = RegQueryValueEx(hRunKey, TEXT_CLMT_RUN_VALUE, NULL, &dwType, (LPBYTE) szRunValue, &cbRunValue); if (lRet == ERROR_SUCCESS) { RemoveSubString(szRunValue, lpCLMTOption);
// Search if there is another option or not
// If none, we can safely delete Run key
if (StrChr(szRunValue, TEXT('/')) == NULL) { RegDeleteValue(hRunKey, TEXT_CLMT_RUN_VALUE); } else { // Other option exists, save the new Run value to registry
RegSetValueEx(hRunKey, TEXT_CLMT_RUN_VALUE, 0, REG_SZ, (CONST BYTE *) szRunValue, lstrlen(szRunValue) * sizeof(TCHAR)); } }
RegCloseKey(hRunKey); } }
|