int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */,int /* nCmdShow */) { g_hInstance = (HINSTANCE)hInstance; #ifndef _UNICODE g_IsNT = IsItWindowsNT(); #endif InitCommonControls(); UString archiveName, switches; #ifdef _SHELL_EXECUTE UString executeFile, executeParameters; #endif NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches); UString fullPath; NDLL::MyGetModuleFileName(g_hInstance, fullPath); switches.Trim(); bool assumeYes = false; if (switches.Left(2).CompareNoCase(UString(L"-y")) == 0) { assumeYes = true; switches = switches.Mid(2); switches.Trim(); } AString config; if (!ReadDataString(fullPath, kStartID, kEndID, config)) { if (!assumeYes) ShowErrorMessage(L"Can't load config info"); return 1; } UString dirPrefix = L"." WSTRING_PATH_SEPARATOR; UString appLaunched; bool showProgress = true; if (!config.IsEmpty()) { CObjectVector<CTextConfigPair> pairs; if (!GetTextConfig(config, pairs)) { if (!assumeYes) ShowErrorMessage(L"Config failed"); return 1; } UString friendlyName = GetTextConfigValue(pairs, L"Title"); UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt"); UString progress = GetTextConfigValue(pairs, L"Progress"); if (progress.CompareNoCase(L"no") == 0) showProgress = false; int index = FindTextConfigItem(pairs, L"Directory"); if (index >= 0) dirPrefix = pairs[index].String; if (!installPrompt.IsEmpty() && !assumeYes) { if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO | MB_ICONQUESTION) != IDYES) return 0; } appLaunched = GetTextConfigValue(pairs, L"RunProgram"); #ifdef _SHELL_EXECUTE executeFile = GetTextConfigValue(pairs, L"ExecuteFile"); executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters") + switches; #endif } NFile::NDirectory::CTempDirectory tempDir; if (!tempDir.Create(kTempDirPrefix)) { if (!assumeYes) ShowErrorMessage(L"Can not create temp folder archive"); return 1; } CCodecs *codecs = new CCodecs; CMyComPtr<IUnknown> compressCodecsInfo = codecs; HRESULT result = codecs->Load(); if (result != S_OK) { ShowErrorMessage(L"Can not load codecs"); return 1; } UString tempDirPath = GetUnicodeString(tempDir.GetPath()); { bool isCorrupt = false; UString errorMessage; HRESULT result = ExtractArchive(codecs, fullPath, tempDirPath, showProgress, isCorrupt, errorMessage); if (result != S_OK) { if (!assumeYes) { if (result == S_FALSE || isCorrupt) { errorMessage = NWindows::MyLoadStringW(IDS_EXTRACTION_ERROR_MESSAGE); result = E_FAIL; } if (result != E_ABORT && !errorMessage.IsEmpty()) ::MessageBoxW(0, errorMessage, NWindows::MyLoadStringW(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR); } return 1; } } CCurrentDirRestorer currentDirRestorer; if (!SetCurrentDirectory(tempDir.GetPath())) return 1; HANDLE hProcess = 0; #ifdef _SHELL_EXECUTE if (!executeFile.IsEmpty()) { CSysString filePath = GetSystemString(executeFile); SHELLEXECUTEINFO execInfo; execInfo.cbSize = sizeof(execInfo); execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; execInfo.hwnd = NULL; execInfo.lpVerb = NULL; execInfo.lpFile = filePath; if (!switches.IsEmpty()) executeParameters += switches; CSysString parametersSys = GetSystemString(executeParameters); if (parametersSys.IsEmpty()) execInfo.lpParameters = NULL; else execInfo.lpParameters = parametersSys; execInfo.lpDirectory = NULL; execInfo.nShow = SW_SHOWNORMAL; execInfo.hProcess = 0; /* BOOL success = */ ::ShellExecuteEx(&execInfo); UINT32 result = (UINT32)(UINT_PTR)execInfo.hInstApp; if(result <= 32) { if (!assumeYes) ShowErrorMessage(L"Can not open file"); return 1; } hProcess = execInfo.hProcess; } else #endif { if (appLaunched.IsEmpty()) { appLaunched = L"setup.exe"; if (!NFile::NFind::DoesFileExist(GetSystemString(appLaunched))) { if (!assumeYes) ShowErrorMessage(L"Can not find setup.exe"); return 1; } } { UString s2 = tempDirPath; NFile::NName::NormalizeDirPathPrefix(s2); appLaunched.Replace(L"%%T" WSTRING_PATH_SEPARATOR, s2); } appLaunched.Replace(L"%%T", tempDirPath); if (!switches.IsEmpty()) { appLaunched += L' '; appLaunched += switches; } STARTUPINFO startupInfo; startupInfo.cb = sizeof(startupInfo); startupInfo.lpReserved = 0; startupInfo.lpDesktop = 0; startupInfo.lpTitle = 0; startupInfo.dwFlags = 0; startupInfo.cbReserved2 = 0; startupInfo.lpReserved2 = 0; PROCESS_INFORMATION processInformation; CSysString appLaunchedSys = GetSystemString(dirPrefix + appLaunched); BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys, NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */, &startupInfo, &processInformation); if (createResult == 0) { if (!assumeYes) ShowLastErrorMessage(); return 1; } ::CloseHandle(processInformation.hThread); hProcess = processInformation.hProcess; } if (hProcess != 0) { WaitForSingleObject(hProcess, INFINITE); ::CloseHandle(hProcess); } return 0; }
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Disable current directory from being in the search path. // This call does not help with implicitly loaded DLLs. if (!RemoveCurrentDirFromSearchPath()) { WCHAR minOSTitle[512] = { '\0' }; WCHAR minOSText[512] = { '\0' }; LoadStringW(NULL, IDS_MIN_OS_TITLE, minOSTitle, sizeof(minOSTitle) / sizeof(minOSTitle[0])); LoadStringW(NULL, IDS_MIN_OS_TEXT, minOSText, sizeof(minOSText) / sizeof(minOSText[0])); MessageBoxW(NULL, minOSText, minOSTitle, MB_OK | MB_ICONERROR); return 1; } g_hInstance = (HINSTANCE)hInstance; #ifndef _UNICODE g_IsNT = IsItWindowsNT(); #endif InitCommonControls(); UString archiveName, switches; #ifdef _SHELL_EXECUTE UString executeFile, executeParameters; #endif NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches); UString fullPath; NDLL::MyGetModuleFileName(g_hInstance, fullPath); switches.Trim(); bool assumeYes = false; if (switches.Left(2).CompareNoCase(UString(L"-y")) == 0) { assumeYes = true; switches = switches.Mid(2); switches.Trim(); } /* BEGIN Mozilla customizations */ bool showProgress = true; if (switches.Left(3).CompareNoCase(UString(L"-ms")) == 0 || switches.Left(4).CompareNoCase(UString(L"/INI")) == 0 || switches.Left(2).CompareNoCase(UString(L"/S")) == 0) showProgress = false; /* END Mozilla customizations */ AString config; if (!ReadDataString(fullPath, kStartID, kEndID, config)) { if (!assumeYes) MyMessageBox(L"Can't load config info"); return 1; } UString dirPrefix = L".\\"; UString appLaunched; if (!config.IsEmpty()) { CObjectVector<CTextConfigPair> pairs; if (!GetTextConfig(config, pairs)) { if (!assumeYes) MyMessageBox(L"Config failed"); return 1; } UString friendlyName = GetTextConfigValue(pairs, L"Title"); UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt"); UString progress = GetTextConfigValue(pairs, L"Progress"); if (progress.CompareNoCase(L"no") == 0) showProgress = false; int index = FindTextConfigItem(pairs, L"Directory"); if (index >= 0) dirPrefix = pairs[index].String; if (!installPrompt.IsEmpty() && !assumeYes) { if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO | MB_ICONQUESTION) != IDYES) return 0; } appLaunched = GetTextConfigValue(pairs, L"RunProgram"); #ifdef _SHELL_EXECUTE executeFile = GetTextConfigValue(pairs, L"ExecuteFile"); executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters") + switches; #endif } NFile::NDirectory::CTempDirectory tempDir; if (!tempDir.Create(kTempDirPrefix)) { if (!assumeYes) MyMessageBox(L"Can not create temp folder archive"); return 1; } COpenCallbackGUI openCallback; UString tempDirPath = GetUnicodeString(tempDir.GetPath()); bool isCorrupt = false; UString errorMessage; HRESULT result = ExtractArchive(fullPath, tempDirPath, &openCallback, showProgress, isCorrupt, errorMessage); if (result != S_OK) { if (!assumeYes) { if (result == S_FALSE || isCorrupt) { errorMessage = NWindows::MyLoadStringW(IDS_EXTRACTION_ERROR_MESSAGE); result = E_FAIL; } if (result != E_ABORT && !errorMessage.IsEmpty()) ::MessageBoxW(0, errorMessage, NWindows::MyLoadStringW(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR); } return 1; } CCurrentDirRestorer currentDirRestorer; if (!SetCurrentDirectory(tempDir.GetPath())) return 1; HANDLE hProcess = 0; #ifdef _SHELL_EXECUTE if (!executeFile.IsEmpty()) { CSysString filePath = GetSystemString(executeFile); SHELLEXECUTEINFO execInfo; execInfo.cbSize = sizeof(execInfo); execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; execInfo.hwnd = NULL; execInfo.lpVerb = NULL; execInfo.lpFile = filePath; if (!switches.IsEmpty()) executeParameters += switches; CSysString parametersSys = GetSystemString(executeParameters); if (parametersSys.IsEmpty()) execInfo.lpParameters = NULL; else execInfo.lpParameters = parametersSys; execInfo.lpDirectory = NULL; execInfo.nShow = SW_SHOWNORMAL; execInfo.hProcess = 0; bool success = BOOLToBool(::ShellExecuteEx(&execInfo)); result = (UINT32)execInfo.hInstApp; if(result <= 32) { if (!assumeYes) MyMessageBox(L"Can not open file"); return 1; } hProcess = execInfo.hProcess; } else #endif { if (appLaunched.IsEmpty()) { appLaunched = L"setup.exe"; if (!NFile::NFind::DoesFileExist(GetSystemString(appLaunched))) { if (!assumeYes) MyMessageBox(L"Can not find setup.exe"); return 1; } } { UString s2 = tempDirPath; NFile::NName::NormalizeDirPathPrefix(s2); appLaunched.Replace(L"%%T\\", s2); } appLaunched.Replace(L"%%T", tempDirPath); if (!switches.IsEmpty()) { appLaunched += L' '; appLaunched += switches; } STARTUPINFO startupInfo; startupInfo.cb = sizeof(startupInfo); startupInfo.lpReserved = 0; startupInfo.lpDesktop = 0; startupInfo.lpTitle = 0; startupInfo.dwFlags = 0; startupInfo.cbReserved2 = 0; startupInfo.lpReserved2 = 0; PROCESS_INFORMATION processInformation; CSysString appLaunchedSys = GetSystemString(dirPrefix + appLaunched); BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys, NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */, &startupInfo, &processInformation); if (createResult == 0) { if (!assumeYes) ShowLastErrorMessage(); return 1; } ::CloseHandle(processInformation.hThread); hProcess = processInformation.hProcess; } if (hProcess != 0) { WaitForSingleObject(hProcess, INFINITE); ::CloseHandle(hProcess); } return 0; }