/* SPDX-License-Identifier: GPL-3.0-or-later Copyright © 2015-2022 Amebis */ #include "pch.h" /// /// Main function /// int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hInstance); UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(nCmdShow); TCHAR szArchProc[MAX_PATH]; if (!GetEnvironmentVariable(TEXT("PROCESSOR_ARCHITECTURE"), szArchProc, _countof(szArchProc))) szArchProc[0] = 0; szArchProc[_countof(szArchProc) - 1] = 0; TCHAR szArchWin[MAX_PATH]; if (!GetEnvironmentVariable(TEXT("PROCESSOR_ARCHITEW6432"), szArchWin, _countof(szArchWin))) szArchWin[0] = 0; szArchWin[_countof(szArchWin) - 1] = 0; // If PROCESSOR_ARCHITEW6432 is defined, this is a Windows-on-Windows // guest of some kind. szArchWin is the host's architecture and szArchProc // is the current process' architecture. // If PROCESSOR_ARCHITEW6432 is not defined, then PROCESSOR_ARCHITECTURE // is both the process and OS architecture. if (szArchWin[0] == 0) memcpy_s(szArchWin, sizeof(szArchWin), szArchProc, sizeof(szArchProc)); // If PROCESSOR_ARCHITECTURE is not defined, then either we're running on // Windows 9x or something is messing with the environment. Make the // Windows 9x assumption. if (szArchProc[0] == 0) { memcpy_s(szArchProc, sizeof(szArchProc), TEXT("x86"), sizeof(TEXT("x86"))); memcpy_s(szArchWin , sizeof(szArchWin ), TEXT("x86"), sizeof(TEXT("x86"))); } LPCTSTR pszPlatSuffix; if (_tcsicmp(szArchWin, TEXT("amd64")) == 0) pszPlatSuffix = TEXT("-amd64"); else if (_tcsicmp(szArchWin, TEXT("arm64")) == 0) pszPlatSuffix = TEXT("-arm64"); else pszPlatSuffix = TEXT("-x86"); // Get temporary folder path. static const LPTSTR pszTempFolderDefault = TEXT(""); LPTSTR pszTempFolder; DWORD dwLength; if ((dwLength = GetEnvironmentVariable(TEXT("TEMP"), NULL, 0)) != 0 && (pszTempFolder = (LPTSTR)LocalAlloc(LMEM_FIXED, (dwLength + 2)*sizeof(TCHAR))) != NULL) // +1 for trailing backslash when missing, +1 for zero terminator { dwLength = ::GetEnvironmentVariable(TEXT("TEMP"), pszTempFolder, dwLength); if (pszTempFolder[dwLength - 1] != TEXT('\\')) { // Append trailing backslash. pszTempFolder[dwLength ] = TEXT('\\'); pszTempFolder[dwLength + 1] = 0; } } else pszTempFolder = pszTempFolderDefault; // Format msiexec's command line. LPTSTR pszParams; DWORD_PTR aArgs[] = { (DWORD_PTR)TEXT(ZRCOLA_INSTALL_LANG), (DWORD_PTR)pszPlatSuffix, (DWORD_PTR)pszTempFolder, }; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING, TEXT("/i \"https://prenos.amebis.si/ZRCola/_latest/ZRCola%1%2.msi\" /l* \"%3ZRCola%1%2.log\""), 0, 0, (LPTSTR)&pszParams, 1, (va_list*)aArgs); // Launch installation. int iResult = (int)ShellExecute(NULL, NULL, TEXT("msiexec.exe"), pszParams, NULL, SW_SHOWNORMAL) > 32; // Clean up. LocalFree(pszParams); if (pszTempFolder != pszTempFolderDefault) LocalFree(pszTempFolder); ExitProcess(iResult ? 0 : 2); }