BOOL CDiskInfoApp::InitInstance() { BOOL flagEarthlight = FALSE; BOOL flagStartupExit = FALSE; m_FlagCopyExit = FALSE; int defaultDisk = -1; HANDLE hMutex = NULL; INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); CWinApp::InitInstance(); GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); // IE Version Check. /* if(GetFileVersion(_T("Shdocvw.dll")) < 471) { AfxMessageBox(_T("CrystalDiskInfo is required IE 6.0 or later.")); } */ // CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // for WMI error SetErrorMode(SEM_FAILCRITICALERRORS); // Init m_Ini TCHAR *ptrEnd; TCHAR ini[MAX_PATH]; ::GetModuleFileName(NULL, ini, MAX_PATH); if((ptrEnd = _tcsrchr(ini, '.')) != NULL) { *ptrEnd = '\0'; _tcscat_s(ini, MAX_PATH, _T(".ini")); } m_Ini = ini; #ifdef SUISHO_SHIZUKU_SUPPORT m_Ini.Replace(_T("DiskInfoS.ini"), _T("DiskInfo.ini")); m_Ini.Replace(_T("DiskInfoSx64.ini"), _T("DiskInfoX64.ini")); #endif CString cstr; DWORD debugMode = GetPrivateProfileInt(_T("Setting"), _T("DebugMode"), 0, m_Ini); SetDebugMode(debugMode); cstr.Format(_T("%d"), debugMode); WritePrivateProfileString(_T("Setting"), _T("DebugMode"), cstr, m_Ini); int argc = 0; int index = 0; LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); if(argc > 1) { CString cstr; cstr = argv[1]; if(cstr.CompareNoCase(_T("/Earthlight")) == 0) { flagEarthlight = TRUE; if(argc > 2) { defaultDisk = _tstoi(argv[2]); } } if(cstr.CompareNoCase(_T("/Startup")) == 0) { int time = 0; time = GetPrivateProfileInt(_T("Setting"), _T("StartupWaitTime"), 30, m_Ini); if(time >= 0) { Sleep(time * 1000); } TCHAR str[MAX_PATH]; ::GetModuleFileName(NULL, str, MAX_PATH); ShellExecute(NULL, NULL, str, NULL, NULL, SW_SHOWNORMAL); return FALSE; } if(cstr.CompareNoCase(_T("/Exit")) == 0) { flagStartupExit = TRUE; } if(cstr.CompareNoCase(_T("/Copy")) == 0) { m_SaveAsText = m_Ini; m_SaveAsText.Replace(_T("ini"), _T("txt")); } if(cstr.CompareNoCase(_T("/CopyExit")) == 0) { m_SaveAsText = m_Ini; m_SaveAsText.Replace(_T("ini"), _T("txt")); m_FlagCopyExit = TRUE; } } // DEBUG // flagEarthlight = TRUE; if(! flagEarthlight) { DebugPrint(_T("CreateMutex")); hMutex = ::CreateMutex(NULL, FALSE, PROJECT_NAME); if(GetLastError() == ERROR_ALREADY_EXISTS) { DebugPrint(_T("ERROR_ALREADY_EXISTS")); return FALSE; } } CString DefaultTheme; CString DefaultLanguage; TCHAR tmp[MAX_PATH]; GetModuleFileName(NULL, tmp, MAX_PATH); if((ptrEnd = _tcsrchr(tmp, '\\')) != NULL) { *ptrEnd = '\0'; } m_ExeDir.Format(_T("%s\\"), tmp); m_ThemeDir.Format(_T("%s\\%s"), tmp, THEME_DIR); m_LangDir.Format(_T("%s\\%s"), tmp, LANGUAGE_DIR); m_SmartDir.Format(_T("%s\\%s"), tmp, SMART_DIR); m_GadgetDir.Format(_T("%s\\%s"), tmp, GADGET_DIR); if(IsDotNet4()) { m_AlertMailPath.Format(_T("%s\\%s"), tmp, ALERT_MAIL_4_PATH); } else if(IsDotNet2()) { m_AlertMailPath.Format(_T("%s\\%s"), tmp, ALERT_MAIL_PATH); } else { m_AlertMailPath = _T(""); } m_OpusDecPath.Format(_T("%s\\%s"), tmp, OPUS_DEC_PATH); #ifdef SUISHO_SHIZUKU_SUPPORT m_ShizukuVoicePath.Format(_T("%s\\%s"), tmp, SHIZUKU_VOICE_PATH); #endif m_ThemeIndex = MENU_THEME_INDEX; m_LangIndex = MENU_LANG_INDEX; DefaultTheme.Format(_T("%s\\%s"), tmp, DEFAULT_THEME); DefaultLanguage.Format(_T("%s\\%s"), tmp, DEFAULT_LANGUAGE); OSVERSIONINFOEX osvi; BOOL bosVersionInfoEx; ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if(!(bosVersionInfoEx = GetVersionEx((OSVERSIONINFO *)&osvi))) { osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx((OSVERSIONINFO *)&osvi); } if((BOOL)GetPrivateProfileInt(_T("Workaround"), _T("IE8MODE"), 0, m_Ini)) { m_GraphDlgPath.Format(_T("%s\\") DIALOG_DIR GRAPH_DIALOG_IE8, tmp); if(! IsFileExistEx(m_GraphDlgPath, GRAPH_DIALOG_IE8)) { return FALSE; } } else { m_GraphDlgPath.Format(_T("%s\\") DIALOG_DIR GRAPH_DIALOG, tmp); if(! IsFileExistEx(m_GraphDlgPath, GRAPH_DIALOG)) { return FALSE; } } m_OptionDlgPath.Format(_T("%s\\") DIALOG_DIR OPTION_DIALOG, tmp); // if(! IsFileExistEx(DefaultTheme, DEFAULT_THEME)) { return FALSE; } if(! IsFileExistEx(DefaultLanguage, DEFAULT_LANGUAGE)) { return FALSE; } // for Windows NT family #ifdef _UNICODE if(! IsCurrentUserLocalAdministrator()) { if(osvi.dwMajorVersion < 6) { AfxMessageBox(_T("CrystalDiskInfo is required Administrator Privileges.")); } RunAsRestart(); return FALSE; } #endif BOOL flagAfxOleInit = FALSE; if(flagEarthlight) { CGraphDlg dlg(NULL, defaultDisk); m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); } else { // No Server Busy Dialog!! DebugPrint(_T("AfxOleInit()")); if(AfxOleInit()) { flagAfxOleInit = TRUE; DebugPrint(_T("AfxOleGetMessageFilter()->SetMessagePendingDelay")); AfxOleGetMessageFilter()->SetMessagePendingDelay(60 * 1000); DebugPrint(_T("AfxOleGetMessageFilter()->EnableNotRespondingDialog(FALSE)")); AfxOleGetMessageFilter()->EnableNotRespondingDialog(FALSE); DebugPrint(_T("AfxOleGetMessageFilter()->EnableBusyDialog(FALSE)")); AfxOleGetMessageFilter()->EnableBusyDialog(FALSE); } else { DebugPrint(_T("CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);")); CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); } CDiskInfoDlg dlg(NULL, flagStartupExit); m_pMainWnd = &dlg; BOOL flagReExec = FALSE; DebugPrint(_T("dlg.DoModal()")); if(dlg.DoModal() == RE_EXEC) { flagReExec = TRUE; } ::ReleaseMutex(hMutex); ::CloseHandle(hMutex); if(flagReExec) { TCHAR str[MAX_PATH]; ::GetModuleFileName(NULL, str, MAX_PATH); ShellExecute(NULL, NULL, str, NULL, NULL, SW_SHOWNORMAL); } } if(! flagAfxOleInit) { DebugPrint(_T("CoUninitialize();")); CoUninitialize(); } return FALSE; }
void MasterInstaller_t::Run() { try { m_nPhase = -1; g_Log.Start(); if (!CreateMutex()) return; DoUniversalFixes(); if (g_OSVersion >= OSVersion_t::Win2k) { // Because the API function GetSystemDefaultUILanguage does not exist // on Windows 98 or lower, we must not assume it is present. Instead, // we must interrogate the Kernel32.dll. // Get Windows system folder path: _TCHAR * pszSystemFolder = GetFolderPathNew(CSIDL_SYSTEM); if (pszSystemFolder) { // Generate full path of Kernel32.dll: _TCHAR * pszKernel32Dll = MakePath(pszSystemFolder, _T("Kernel32.dll")); // Get a handle to the DLL: HMODULE hmodKernel32 = LoadLibrary(pszKernel32Dll); // Delete garbage: delete[] pszSystemFolder; pszSystemFolder = NULL; delete[] pszKernel32Dll; pszKernel32Dll = NULL; // Check if we were successful: if (hmodKernel32) { typedef DWORD (WINAPI * GetSystemDefaultUILanguageFn)(void); GetSystemDefaultUILanguageFn _GetSystemDefaultUILanguage; // Now get a pointer to the function we want to use: _GetSystemDefaultUILanguage = (GetSystemDefaultUILanguageFn)GetProcAddress(hmodKernel32, "GetSystemDefaultUILanguage"); if (_GetSystemDefaultUILanguage) g_langidWindowsLanguage = _GetSystemDefaultUILanguage(); // While we have the handle to Kernel32.dll open, we'll do some // other tests to see if the g_OSVersion is accurate, or whether // it was duped because of the program being run in a different // compatibility mode, which can happen to a naïve user on Vista: if (g_OSVersion < OSVersion_t::Vista && NULL != GetProcAddress(hmodKernel32, "GetLocaleInfoEx")) { // OS is really Vista or higher, but we're duped into thinking it's less: g_Log.Write(_T("OS version is reported as %s, yet GetLocaleInfoEx function exists in Kernel32.dll, indicating version 6.0 (Vista) or higher."), g_OSVersion.Numeric()); HandleError(kFatal, false, IDC_ERROR_OS_VERSION_LIE_VISTA); } FreeLibrary(hmodKernel32); hmodKernel32 = NULL; } } } g_fAdministrator = IsCurrentUserLocalAdministrator(); g_Log.Write(_T("Admin privileges: %s."), (g_fAdministrator? _T("true") : _T("false"))); m_ppmProductManager = CreateProductManager(); if (!m_ppmProductManager) { HandleError(kFatal, false, IDC_ERROR_INTERNAL, _T("cannot instantiate Product Manager")); } // See if we were interrupted last time around: if (g_ProgRecord.RecordExists()) { // We were previously terminated in the middle of something, so let's see where: m_nPhase = g_ProgRecord.ReadPhase(); g_Log.Write(_T("Discovered previous progress record: Phase=%d."), m_nPhase); // Check validity of saved record: if (m_nPhase < 0 || m_nPhase >= phaseMaxPhases) { HandleError(kNonFatal, false, IDC_ERROR_CORRUPT_RECORD); // Remove our data from registry altogether: g_ProgRecord.RemoveData(false); // Now run ourself again! ReRun(); // Does not return } } if (m_nPhase == -1) { g_Log.Write(_T("Clean start established.")); // This is a clean start. Check if user must start from first CD in set: if (!g_fStartFromAnyCd) { // Clean start should only happen from CD 1, or possibly if user has copied // stuff to hard drive, so if we are currently running off a CD with no startup, // we must tell user to insert CD index 0. if (g_DiskManager.CheckCdPresent(0, true) == DiskManager_t::knUserQuit) throw UserQuitException; } m_nPhase = phaseChoices; } // Create event so that later we can signal to our sub-threads that we're shutting down: m_hShutDown = CreateEvent(NULL, true, false, NULL); if (!m_hShutDown) g_Log.Write(_T("Failed to create ShutDown event.")); // Get a pointer to the Help function in the InstallerHelp2.dll: g_Log.Write(_T("Attempting to load InstallerHelp2.dll.")); m_hmodInstallerHelp2 = LoadLibrary(_T("InstallerHelp2.dll")); if (m_hmodInstallerHelp2) { g_Log.Write(_T("Loaded InstallerHelp2.dll.")); Help = (HelpFn)GetProcAddress(m_hmodInstallerHelp2, "Help"); if (!Help) { FreeLibrary(m_hmodInstallerHelp2); m_hmodInstallerHelp2 = NULL; g_Log.Write(_T("Failed to get pointer to Help function.")); } } else g_Log.Write(_T("InstallerHelp2.dll not present.")); // Flag to indicate third-party stuff is to be included. User may get a chance to reset // this later: m_fInstallRequiredProducts = true; bool fShowDependencies = false; if (m_nPhase == phaseChoices) { g_ProgRecord.WritePhase(m_nPhase); g_Log.Write(_T("Starting user choices phase.")); SelectMainProducts(); if (m_rgiChosenMainProducts.GetCount() == 0 && !m_fInstallRequiredProducts) { // User didn't select anything, so quit: g_Log.Write(_T("User didn't select anything.")); MessageBox(NULL, FetchString(IDC_MESSAGE_NOTHING_SELECTED), g_pszTitle, MB_OK); throw UserQuitException; } // Check if any selected item has a prerequisite or requirement that has a // language requirement we can't meet: TestAndReportLanguageConflicts(m_rgiChosenMainProducts); // Save user's selection(s): g_ProgRecord.WriteMainSelectionList(m_rgiChosenMainProducts); m_nPhase = phaseMain; fShowDependencies = true; if (g_fManualInstall) g_Log.Write(_T("Manual mode: not testing for prerequisites of chosen products.")); else { // Display Prerequisites, if any: g_Log.Write(_T("Testing for prerequisites of chosen products:")); g_Log.Indent(); if (m_ppmProductManager->PrerequisitesNeeded(m_rgiChosenMainProducts)) { g_Log.Unindent(); // There are some prerequisites: g_Log.Write(_T("Prerequisites are needed.")); // Display report dialog: _TCHAR * pszTitle = new_sprintf(_T("%s - %s"), g_pszTitle, FetchString(IDC_MESSAGE_PREREQUISITES)); _TCHAR * pszIntro = new_sprintf(FetchString(IDC_MESSAGE_PREREQUISITE_INTRO), g_pszTitle, g_pszTitle); _TCHAR * pszContinue = new_sprintf(FetchString(IDC_MESSAGE_CONTINUE)); m_ppmProductManager->ShowReport(pszTitle, pszIntro, pszContinue, true, true, IProductManager::rptPrerequisitesShort, true, &m_rgiChosenMainProducts); delete[] pszTitle; delete[] pszIntro; delete[] pszContinue; } // End if any pre-requisite products are needed. else { g_Log.Unindent(); g_Log.Write(_T("No prerequisites are needed.")); } } } else if (m_nPhase == phaseMain) // We were running previously { // Retrieve remains of user's previous selection(s) g_ProgRecord.ReadMainSelectionList(m_rgiChosenMainProducts); g_Log.Write(_T("Remains of user's previous selection(s):")); for (int i = 0; i < m_rgiChosenMainProducts.GetCount(); i++) { g_Log.Write(_T("%d: %s"), i, m_ppmProductManager->GetName(m_rgiChosenMainProducts[i])); } } if (m_nPhase == phaseMain) { // Save status of installing main installers: g_Log.Write(_T("Starting Main phase.")); g_ProgRecord.WritePhase(m_nPhase); ShowStatusDialog(); DisplayStatusText(0, FetchString(IDC_MESSAGE_INITIALIZING)); DisplayStatusText(1, _T("")); while (m_rgiChosenMainProducts.GetCount() > 0) { CheckIfStopRequested(); // Get index of next chosen product to be installed: int iCurrentProduct = m_rgiChosenMainProducts[0]; // Install prerequisite software, unless in manual mode: if (!InstallPrerequisites(iCurrentProduct) && !g_fManualInstall) { // Could not install all prerequisites, so there's no point in continuing // with this product: m_rgiChosenMainProducts.RemoveNthItem(0); g_ProgRecord.WriteMainSelectionList(m_rgiChosenMainProducts); g_Log.Write( _T("Removed %s from chosen main products due to prerequisite failure."), m_ppmProductManager->GetName(iCurrentProduct)); continue; // go to next product. } CheckIfStopRequested(); // See if this product requires a pending reboot to be flushed first: TestAndPerformPendingReboot(iCurrentProduct); // Remove current product from selection list: g_Log.Write(_T("Removing %s from chosen main products prior to installation."), m_ppmProductManager->GetName(m_rgiChosenMainProducts[0])); m_rgiChosenMainProducts.RemoveNthItem(0); // Record current selection list: g_ProgRecord.WriteMainSelectionList(m_rgiChosenMainProducts); // Install product. m_ppmProductManager->InstallProduct(iCurrentProduct); // Any error that occurred will already have been reported to the user, so we // can just continue. } // End while there are more than 0 chosen products left g_Log.Write(_T("Finished installing main products.")); m_nPhase = phaseDependencies; fShowDependencies = true; } CheckIfStopRequested(); // Install dependent software, unless in manual mode: if (m_nPhase == phaseDependencies && m_fInstallRequiredProducts && !g_fManualInstall) { g_Log.Write(_T("Starting dependent software phase.")); g_ProgRecord.WritePhase(m_nPhase); // Determine the software dependencies: IndexList_t rgiRequiredProducts; ShowStatusDialog(); DisplayStatusText(0, FetchString(IDC_MESSAGE_DEPENDENCIES)); DisplayStatusText(1, _T("")); g_Log.Write(_T("Testing for initial active requirements...")); g_Log.Indent(); m_ppmProductManager->GetActiveRequirements(rgiRequiredProducts); g_Log.Unindent(); g_Log.Write(_T("... Done (initial active requirements)")); // See if there are any dependencies we need to show: if (fShowDependencies && rgiRequiredProducts.GetCount() > 0) { g_Log.Write(_T("Informing user of needed software.")); // Display dependency report dialog: _TCHAR * pszTitle = new_sprintf(_T("%s - %s"), g_pszTitle, FetchString(IDC_MESSAGE_REQUIREMENTS)); _TCHAR * pszIntro = new_sprintf(FetchString(IDC_MESSAGE_REQUIREMENT_INTRO), g_pszTitle, g_pszTitle); _TCHAR * pszContinue = new_sprintf(FetchString(IDC_MESSAGE_CONTINUE)); m_ppmProductManager->ShowReport(pszTitle, pszIntro, pszContinue, true, true, IProductManager::rptRequirementsShort, true); delete[] pszTitle; delete[] pszIntro; delete[] pszContinue; ShowStatusDialog(); } // Check if any required product has a prerequisite or requirement that has a // language requirement we can't meet: TestAndReportLanguageConflicts(rgiRequiredProducts, true); while (rgiRequiredProducts.GetCount() > 0) { CheckIfStopRequested(); // Get index of next required product: int iCurrentProduct = rgiRequiredProducts.RemoveNthItem(0); // It is remotely possible that an earlier installation means we no longer need // The current product, so let's just check: IndexList_t rgiTempCurrentNeeds; g_Log.Write(_T("Testing active requirements to see if %s is still needed..."), m_ppmProductManager->GetName(iCurrentProduct)); g_Log.Indent(); m_ppmProductManager->GetActiveRequirements(rgiTempCurrentNeeds); g_Log.Unindent(); g_Log.Write(_T("...Done (requirements)")); if (!rgiTempCurrentNeeds.Contains(iCurrentProduct)) { // Product is no longer needed g_Log.Write(_T("Product %s is no longer a requirement."), m_ppmProductManager->GetName(iCurrentProduct)); continue; // Product is already removed from requirements list. } // Inform user of number of products remaining: DisplayStatusText(2, FetchString(IDC_MESSAGE_REMAINING), rgiRequiredProducts.GetCount()); // Install prerequisites for current product: if (!InstallPrerequisites(iCurrentProduct)) continue; // Failed, so go to next product. CheckIfStopRequested(); // See if this product requires a pending reboot to be flushed first: TestAndPerformPendingReboot(iCurrentProduct); g_Log.Write(_T("About to install %s."), m_ppmProductManager->GetName(iCurrentProduct)); m_ppmProductManager->InstallProduct(iCurrentProduct); // No need to deal with an error - it has already been reported, // so we can just carry on with the next product. } // End while there are more than 0 required products left } CheckIfStopRequested(); _TCHAR * pszWksp = NULL; bool fShowFinalMessage = true; if (m_ppmProductManager->ShowFinalReport() || !g_fShowInstallCompleteMessage) fShowFinalMessage = false; else // No error report needed pszWksp = new_sprintf(FetchString(IDC_MESSAGE_FINISHED), g_pszTitle); UINT uType = MB_OK; // Default Message Box button. // See if there is a pending reboot: if (g_fRebootPending) { fShowFinalMessage = true; new_sprintf_concat(pszWksp, 0, _T("\n\n%s"), FetchString(IDC_MESSAGE_PENDING_REBOOT)); uType = MB_OKCANCEL; } HideStatusDialog(); int nResult = IDCANCEL; if (fShowFinalMessage && !g_fSilent) nResult = MessageBox(NULL, pszWksp, g_pszTitle, uType); delete[] pszWksp; pszWksp = NULL; if (g_fRebootPending && nResult == IDOK) { g_ProgRecord.RemoveData(false); Reboot(); } } catch (UserQuitException_t &) { // User asked to quit, so just quit quietly. } catch (...) { // Some fatal error, which has probably already been reported, but we'll try to put the // log info into the Clipboard: bool fWritten = g_Log.WriteClipboard(); HideStatusDialog(); if (fWritten) MessageBox(NULL, FetchString(IDC_MESSAGE_LOG_IN_CLIPBOARD), g_pszTitle, MB_OK); } g_ProgRecord.RemoveData(false); }