diff options
Diffstat (limited to 'desktop/win32/source/loader.cxx')
-rw-r--r-- | desktop/win32/source/loader.cxx | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/desktop/win32/source/loader.cxx b/desktop/win32/source/loader.cxx index 23706de032c9..3adf34aa3043 100644 --- a/desktop/win32/source/loader.cxx +++ b/desktop/win32/source/loader.cxx @@ -329,6 +329,104 @@ int officeloader_impl(bool bAllowConsole) return fSuccess ? dwExitCode : -1; } +int unopkgloader_impl(bool bAllowConsole) +{ + WCHAR szTargetFileName[MAX_PATH]; + WCHAR szIniDirectory[MAX_PATH]; + desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory); + + STARTUPINFOW aStartupInfo{}; + aStartupInfo.cb = sizeof(aStartupInfo); + GetStartupInfoW(&aStartupInfo); + + DWORD dwExitCode = DWORD(-1); + + size_t iniDirLen = wcslen(szIniDirectory); + WCHAR cwd[MAX_PATH]; + DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd); + if (cwdLen >= MAX_PATH) { + cwdLen = 0; + } + WCHAR redirect[MAX_PATH]; + DWORD dummy; + bool hasRedirect = + tools::buildPath( + redirect, szIniDirectory, szIniDirectory + iniDirLen, + MY_STRING(L"redirect.ini")) != nullptr && + (GetBinaryTypeW(redirect, &dummy) || // cheaper check for file existence? + GetLastError() != ERROR_FILE_NOT_FOUND); + LPWSTR cl1 = GetCommandLineW(); + WCHAR* cl2 = new WCHAR[ + wcslen(cl1) + + (hasRedirect + ? (MY_LENGTH(L" \"-env:INIFILENAME=vnd.sun.star.pathname:") + + iniDirLen + MY_LENGTH(L"redirect.ini\"")) + : 0) + + MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen + MY_LENGTH(L"\"") + 1]; + // 4 * cwdLen: each char preceded by backslash, each trailing backslash + // doubled + WCHAR* p = desktop_win32::commandLineAppend(cl2, cl1); + if (hasRedirect) { + p = desktop_win32::commandLineAppend( + p, MY_STRING(L" \"-env:INIFILENAME=vnd.sun.star.pathname:")); + p = desktop_win32::commandLineAppend(p, szIniDirectory); + p = desktop_win32::commandLineAppend(p, MY_STRING(L"redirect.ini\"")); + } + p = desktop_win32::commandLineAppend(p, MY_STRING(L" \"-env:OOO_CWD=")); + if (cwdLen == 0) { + p = desktop_win32::commandLineAppend(p, MY_STRING(L"0")); + } + else { + p = desktop_win32::commandLineAppend(p, MY_STRING(L"2")); + p = desktop_win32::commandLineAppendEncoded(p, cwd); + } + desktop_win32::commandLineAppend(p, MY_STRING(L"\"")); + + PROCESS_INFORMATION aProcessInfo; + + bool fSuccess = CreateProcessW( + szTargetFileName, + cl2, + nullptr, + nullptr, + TRUE, + bAllowConsole ? 0 : DETACHED_PROCESS, + nullptr, + szIniDirectory, + &aStartupInfo, + &aProcessInfo); + + delete[] cl2; + + if (fSuccess) + { + DWORD dwWaitResult; + + do + { + // On Windows XP it seems as the desktop calls WaitForInputIdle after "OpenWidth" so we have to do so + // as if we where processing any messages + + dwWaitResult = MsgWaitForMultipleObjects(1, &aProcessInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS); + + if (WAIT_OBJECT_0 + 1 == dwWaitResult) + { + MSG msg; + + PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE); + } + } while (WAIT_OBJECT_0 + 1 == dwWaitResult); + + dwExitCode = 0; + GetExitCodeProcess(aProcessInfo.hProcess, &dwExitCode); + + CloseHandle(aProcessInfo.hProcess); + CloseHandle(aProcessInfo.hThread); + } + + return dwExitCode; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |