summaryrefslogtreecommitdiff
path: root/desktop/win32
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2020-01-22 22:13:25 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2020-01-23 06:20:22 +0100
commitab0942240507e9be81dbe43e8d69b7f9273b124f (patch)
tree851f54873eb0be0b4d9f1c3b298908c9fda0f80e /desktop/win32
parent5bbe2c9891c2d295ef77d0791cf3decf09c58c65 (diff)
Make unopkg.com proper launcher for unopkg.bin on Windows
... like implemented in 506173a7f42f34821238a63f3f8c7362c9fae9d9 for soffice.bin. Previously unopkg.com prepared some communication pipes, and launched unopkg.exe, which in turn launched unopkg.bin (both GUI subsystem apps), and when the latter sent output to console, it was redirected to the pipes, and finally sent to console by unopkg.com (details in dropped desktop/win32/source/guistdio/guistdio.inc). The implementation made it impossible to use standard console output function from c/c++ standard libraries; WinAPI had to be used. Special API had been implemented for that: dp_misc::writeConsole*, and still part of output was garbled. Commit 015e9f780bc133788f79868bb7fb0b1d4e81f5f3 tried to workaround that, effectively making loghandler unusable outside of unopkg. This change makes unopkg.com a console subsystem clone of unopkg.exe, and unopkg.bin is now also console application. This allows to cleanup and unify its output in a follow-up commit. Change-Id: I3b299e09f8a11a72883b06442b0e95131ffaac5f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87210 Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'desktop/win32')
-rw-r--r--desktop/win32/source/guiloader/genericloader.cxx133
-rw-r--r--desktop/win32/source/guistdio/guistdio.inc437
-rw-r--r--desktop/win32/source/guistdio/unopkgio.cxx24
-rw-r--r--desktop/win32/source/loader.cxx98
-rw-r--r--desktop/win32/source/loader.hxx3
-rw-r--r--desktop/win32/source/officeloader/unopkg_com.cxx19
-rw-r--r--desktop/win32/source/officeloader/unopkg_exe.cxx19
7 files changed, 139 insertions, 594 deletions
diff --git a/desktop/win32/source/guiloader/genericloader.cxx b/desktop/win32/source/guiloader/genericloader.cxx
deleted file mode 100644
index be83ebe8effc..000000000000
--- a/desktop/win32/source/guiloader/genericloader.cxx
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <tools/pathutils.hxx>
-#include "../loader.hxx"
-
-static int GenericMain()
-{
- WCHAR szTargetFileName[MAX_PATH];
- WCHAR szIniDirectory[MAX_PATH];
- STARTUPINFOW aStartupInfo;
-
- desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory);
-
- ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
- aStartupInfo.cb = sizeof(aStartupInfo);
-
- GetStartupInfoW( &aStartupInfo );
-
- DWORD dwExitCode = DWORD(-1);
-
- PROCESS_INFORMATION aProcessInfo;
-
- 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"\""));
-
- bool fSuccess = CreateProcessW(
- szTargetFileName,
- cl2,
- nullptr,
- nullptr,
- TRUE,
- 0,
- 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;
-}
-
-int WINAPI wWinMain( HINSTANCE, HINSTANCE, LPWSTR, int )
-{
- return GenericMain();
-}
-
-int __cdecl wmain()
-{
- return GenericMain();
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/guistdio/guistdio.inc b/desktop/win32/source/guistdio/guistdio.inc
deleted file mode 100644
index 9dd85d90f44b..000000000000
--- a/desktop/win32/source/guistdio/guistdio.inc
+++ /dev/null
@@ -1,437 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <systools/win32/uwinapi.h>
-
-#include <stdio.h>
-#include <sal/macros.h>
-
-#include <memory>
-
-#ifdef UNOPKG
-
-DWORD passOutputToConsole(HANDLE readPipe, HANDLE console)
-{
- BYTE aBuffer[1024];
- DWORD dwRead = 0;
- HANDLE hReadPipe = readPipe;
- DWORD dwWritten;
-
- //Indicates that we read an odd number of bytes. That is, we only read half of the last
- //wchar_t
- bool bIncompleteWchar = false;
- //fprintf, fwprintf will both send char data without the terminating zero.
- //fwprintf converts the unicode string first.
- //We expect here to receive unicode without the terminating zero.
- //unopkg and the extension manager code MUST
- //use dp_misc::writeConsole instead of using fprintf, etc.
-
- DWORD dwToRead = sizeof(aBuffer);
- BYTE * pBuffer = aBuffer;
- while ( ReadFile( hReadPipe, pBuffer, dwToRead, &dwRead, nullptr ) )
- {
- //If the previous ReadFile call read an odd number of bytes, then the last one was
- //put at the front of the buffer. We increase the number of read bytes by one to reflect
- //that one byte.
- if (bIncompleteWchar)
- dwRead++;
- //We must make sure that only complete wchar_t|s are written. WriteConsolse takes
- //the number of wchar_t|s as argument. ReadFile, however, reads bytes.
- bIncompleteWchar = (dwRead % 2) != 0;
- if (bIncompleteWchar)
- {
- //To test this case, give aBuffer a small odd size, e.g. aBuffer[3]
- //The last byte, which is the incomplete wchar_t (half of it), will not be written.
- (void) WriteConsoleW( console, aBuffer,
- (dwRead - 1) / 2, &dwWritten, nullptr );
-
- //Move the last byte to the front of the buffer, so that it is the start of the
- //next string
- aBuffer[0] = aBuffer[dwRead - 1];
-
- //Make sure that ReadFile does not overwrite the first byte the next time
- dwToRead = sizeof(aBuffer) - 1;
- pBuffer = aBuffer + 1;
-
- }
- else
- { //We have read an even number of bytes. Therefore, we do not put the last incomplete
- //wchar_t at the front of the buffer. We will use the complete buffer the next time
- //when ReadFile is called.
- dwToRead = sizeof(aBuffer);
- pBuffer = aBuffer;
- (void) WriteConsoleW( console,
- aBuffer, dwRead / 2, &dwWritten, nullptr );
- }
- }
-
- return 0;
-}
-
-#endif
-
-#ifdef UNOPKG
-DWORD WINAPI OutputThread( LPVOID pParam )
-{
- return passOutputToConsole(static_cast<HANDLE>(pParam), GetStdHandle( STD_OUTPUT_HANDLE ));
-}
-
-#else
-DWORD WINAPI OutputThread( LPVOID pParam )
-{
- BYTE aBuffer[256];
- DWORD dwRead = 0;
- HANDLE hReadPipe = (HANDLE)pParam;
- while ( ReadFile( hReadPipe, &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
- {
- DWORD dwWritten;
-
- (void) WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), aBuffer, dwRead, &dwWritten, NULL );
- }
-
- return 0;
-}
-#endif
-
-// Thread that reads from child process standard error pipe
-
-
-#ifdef UNOPKG
-DWORD WINAPI ErrorThread( LPVOID pParam )
-{
- return passOutputToConsole(static_cast<HANDLE>(pParam), GetStdHandle( STD_ERROR_HANDLE ));
-}
-
-#else
-DWORD WINAPI ErrorThread( LPVOID pParam )
-{
- BYTE aBuffer[256];
- DWORD dwRead = 0;
- HANDLE hReadPipe = (HANDLE)pParam;
-
- while ( ReadFile( hReadPipe, &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
- {
- DWORD dwWritten;
-
- (void) WriteFile( GetStdHandle( STD_ERROR_HANDLE ), aBuffer, dwRead, &dwWritten, NULL );
- }
-
- return 0;
-}
-#endif
-
-// Thread that writes to child process standard input pipe
-
-#ifdef UNOPKG
-
-DWORD WINAPI InputThread( LPVOID pParam )
-{
- DWORD dwRead = 0;
- HANDLE hWritePipe = static_cast<HANDLE>(pParam);
- char* readBuf = nullptr;
- try
- {
- //We need to read in the complete input until we encounter a new line before
- //converting to Unicode. This is necessary because the input string can use
- //characters of one, two, and more bytes. If the last character is not
- //complete, then it will not be converted properly.
-
- //Find out how a new line (0xd 0xa) looks like with the used code page.
- //Characters may have one or multiple bytes and different byte ordering
- //can be used (little and big endian);
- int cNewLine = WideCharToMultiByte(
- GetConsoleCP(), 0, L"\r\n", 2, nullptr, 0, nullptr, nullptr);
- auto mbBuff = std::make_unique<char[]>(cNewLine);
- WideCharToMultiByte(
- GetConsoleCP(), 0, L"\r\n", 2, mbBuff.get(), cNewLine, nullptr, nullptr);
-
- const DWORD dwBufferSize = 256;
- readBuf = static_cast<char*>(malloc(dwBufferSize));
- if (!readBuf)
- throw std::bad_alloc();
- int readAll = 0;
- DWORD curBufSize = dwBufferSize;
-
- while ( ReadFile( GetStdHandle( STD_INPUT_HANDLE ),
- readBuf + readAll,
- curBufSize - readAll, &dwRead, nullptr ) )
- {
- readAll += dwRead;
- int lastBufSize = curBufSize;
- //Grow the buffer if necessary
- if (readAll > curBufSize * 0.7)
- {
- curBufSize *= 2;
- if (auto p = static_cast<char *>(realloc(readBuf, curBufSize)))
- readBuf = p;
- else
- {
- throw std::bad_alloc();
- }
- }
-
- //If the buffer was filled completely then
- //there could be more input coming. But if we read from the console
- //and the console input fits exactly in the buffer, then the next
- //ReadFile would block until the users presses return, etc.
- //Therefore we check if last character is a new line.
- //To test this, set dwBufferSize to 4 and enter "no". This should produce
- //4 bytes with most code pages.
- if ( readAll == lastBufSize
- && memcmp(readBuf + lastBufSize - cNewLine, mbBuff.get(), cNewLine) != 0)
- {
- //The buffer was completely filled and the last byte(s) are no
- //new line, so there is more to come.
- continue;
- }
- //Obtain the size of the buffer for the converted string.
- int sizeWBuf = MultiByteToWideChar(
- GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, nullptr, 0);
-
- auto wideBuf = std::make_unique<wchar_t[]>(sizeWBuf);
-
- //Do the conversion.
- MultiByteToWideChar(
- GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, wideBuf.get(), sizeWBuf);
-
- DWORD dwWritten;
- (void)WriteFile( hWritePipe, wideBuf.get(), sizeWBuf * 2, &dwWritten, nullptr );
-
- readAll = 0;
- }
- }
- catch (...)
- {}
- free(readBuf);
- return 0;
-}
-#else
-DWORD WINAPI InputThread( LPVOID pParam )
-{
- BYTE aBuffer[256];
- DWORD dwRead = 0;
- HANDLE hWritePipe = (HANDLE)pParam;
-
- while ( ReadFile( GetStdHandle( STD_INPUT_HANDLE ), &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
- {
- DWORD dwWritten;
- (void) WriteFile( hWritePipe, aBuffer, dwRead, &dwWritten, NULL );
- }
-
- return 0;
-}
-#endif
-
-
-// Thread that waits until child process reached input idle
-
-
-DWORD WINAPI WaitForUIThread( LPVOID pParam )
-{
-#ifndef UNOPKG
- HANDLE hProcess = (HANDLE)pParam;
-
- if ( !wgetenv( L"UNOPKG" ) )
- WaitForInputIdle( hProcess, INFINITE );
-#else
- (void) pParam;
-#endif
-
- return 0;
-}
-
-
-
-// Ctrl-Break handler that terminates the child process if Ctrl-C was pressed
-
-
-HANDLE hTargetProcess = INVALID_HANDLE_VALUE;
-
-BOOL WINAPI CtrlBreakHandler(
- DWORD // control signal type
-)
-{
- TerminateProcess( hTargetProcess, 255 );
- return TRUE;
-}
-
-int wmain( int, wchar_t** )
-{
- WCHAR szTargetFileName[MAX_PATH] = L"";
- STARTUPINFOW aStartupInfo;
- PROCESS_INFORMATION aProcessInfo;
-
- ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
- aStartupInfo.cb = sizeof(aStartupInfo);
- aStartupInfo.dwFlags = STARTF_USESTDHANDLES;
-
- // Create an output pipe where the write end is inheritable
-
- HANDLE hOutputRead, hOutputWrite;
-
- if ( CreatePipe( &hOutputRead, &hOutputWrite, nullptr, 0 ) )
- {
- HANDLE hTemp;
-
- DuplicateHandle( GetCurrentProcess(), hOutputWrite, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
- CloseHandle( hOutputWrite );
- hOutputWrite = hTemp;
-
- aStartupInfo.hStdOutput = hOutputWrite;
- }
-
- // Create an error pipe where the write end is inheritable
-
- HANDLE hErrorRead, hErrorWrite;
-
- if ( CreatePipe( &hErrorRead, &hErrorWrite, nullptr, 0 ) )
- {
- HANDLE hTemp;
-
- DuplicateHandle( GetCurrentProcess(), hErrorWrite, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
- CloseHandle( hErrorWrite );
- hErrorWrite = hTemp;
-
- aStartupInfo.hStdError = hErrorWrite;
- }
-
- // Create an input pipe where the read end is inheritable
-
- HANDLE hInputRead, hInputWrite;
-
- if ( CreatePipe( &hInputRead, &hInputWrite, nullptr, 0 ) )
- {
- HANDLE hTemp;
-
- DuplicateHandle( GetCurrentProcess(), hInputRead, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
- CloseHandle( hInputRead );
- hInputRead = hTemp;
-
- aStartupInfo.hStdInput = hInputRead;
- }
-
- // Get image path with same name but with .exe extension
-
- WCHAR szModuleFileName[MAX_PATH];
-
- GetModuleFileNameW( nullptr, szModuleFileName, MAX_PATH );
- WCHAR *lpLastDot = wcsrchr( szModuleFileName, '.' );
- if ( lpLastDot && 0 == wcsicmp( lpLastDot, L".COM" ) )
- {
- size_t len = lpLastDot - szModuleFileName;
- wcsncpy( szTargetFileName, szModuleFileName, len );
- wcsncpy( szTargetFileName + len, L".EXE", SAL_N_ELEMENTS(szTargetFileName) - len );
- }
-
- // Create process with same command line, environment and stdio handles which
- // are directed to the created pipes
-
- bool fSuccess = CreateProcessW(
- szTargetFileName,
- GetCommandLineW(),
- nullptr,
- nullptr,
- TRUE,
- 0,
- nullptr,
- nullptr,
- &aStartupInfo,
- &aProcessInfo );
-
- if ( fSuccess )
- {
- // These pipe ends are inherited by the child process and no longer used
- CloseHandle( hOutputWrite );
- CloseHandle( hErrorWrite );
- CloseHandle( hInputRead );
-
- // Set the Ctrl-Break handler
- hTargetProcess = aProcessInfo.hProcess;
- SetConsoleCtrlHandler( CtrlBreakHandler, TRUE );
-
- // Create threads that redirect remote pipe io to current process's console stdio
-
- DWORD dwOutputThreadId, dwErrorThreadId, dwInputThreadId;
-
- HANDLE hOutputThread = CreateThread( nullptr, 0, OutputThread, static_cast<LPVOID>(hOutputRead), 0, &dwOutputThreadId );
- HANDLE hErrorThread = CreateThread( nullptr, 0, OutputThread, static_cast<LPVOID>(hErrorRead), 0, &dwErrorThreadId );
- HANDLE hInputThread = CreateThread( nullptr, 0, InputThread, static_cast<LPVOID>(hInputWrite), 0, &dwInputThreadId );
-
- // Create thread that wait until child process entered input idle
-
- DWORD dwWaitForUIThreadId;
- HANDLE hWaitForUIThread = CreateThread( nullptr, 0, WaitForUIThread, static_cast<LPVOID>(aProcessInfo.hProcess), 0, &dwWaitForUIThreadId );
-
- HANDLE hObjects[] =
- {
- hTargetProcess,
- hWaitForUIThread,
- hOutputThread,
- hErrorThread
- };
-
- #ifdef UNOPKG
- WaitForMultipleObjects( SAL_N_ELEMENTS(hObjects), hObjects, TRUE, INFINITE );
- #else
- bool bDetach = false;
- int nOpenPipes = 2;
- do
- {
- DWORD dwWaitResult = WaitForMultipleObjects( SAL_N_ELEMENTS(hObjects), hObjects, FALSE, INFINITE );
-
- switch ( dwWaitResult )
- {
- case WAIT_OBJECT_0: // The child process has terminated
- case WAIT_OBJECT_0 + 1: // The child process entered input idle
- bDetach = true;
- break;
- case WAIT_OBJECT_0 + 2: // The remote end of stdout pipe was closed
- case WAIT_OBJECT_0 + 3: // The remote end of stderr pipe was closed
- bDetach = --nOpenPipes <= 0;
- break;
- default: // Something went wrong
- bDetach = true;
- break;
- }
- } while( !bDetach );
-
-#endif
-
- CloseHandle( hOutputThread );
- CloseHandle( hErrorThread );
- CloseHandle( hInputThread );
- CloseHandle( hWaitForUIThread );
-
- DWORD dwExitCode = 0;
- GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode );
- CloseHandle( aProcessInfo.hProcess );
- CloseHandle( aProcessInfo.hThread );
-
- return dwExitCode;
- }
-
- return -1;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/guistdio/unopkgio.cxx b/desktop/win32/source/guistdio/unopkgio.cxx
deleted file mode 100644
index d7a7aff984ac..000000000000
--- a/desktop/win32/source/guistdio/unopkgio.cxx
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-
-#define UNOPKG
-#include "guistdio.inc"
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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: */
diff --git a/desktop/win32/source/loader.hxx b/desktop/win32/source/loader.hxx
index dfa8f0c971a0..aed76b168798 100644
--- a/desktop/win32/source/loader.hxx
+++ b/desktop/win32/source/loader.hxx
@@ -82,6 +82,9 @@ void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory);
// Implementation of the process guarding soffice.bin
int officeloader_impl(bool bAllowConsole);
+// Implementation of the process guarding unopkg.bin
+int unopkgloader_impl(bool bAllowConsole);
+
}
#endif
diff --git a/desktop/win32/source/officeloader/unopkg_com.cxx b/desktop/win32/source/officeloader/unopkg_com.cxx
new file mode 100644
index 000000000000..a93ac60365e6
--- /dev/null
+++ b/desktop/win32/source/officeloader/unopkg_com.cxx
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include "../loader.hxx"
+
+int main(int /*argc*/, char** /*argv*/)
+{
+ // let unopkg.bin use unopkg.com's console
+ return desktop_win32::unopkgloader_impl(true);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/officeloader/unopkg_exe.cxx b/desktop/win32/source/officeloader/unopkg_exe.cxx
new file mode 100644
index 000000000000..40b1afa09280
--- /dev/null
+++ b/desktop/win32/source/officeloader/unopkg_exe.cxx
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include "../loader.hxx"
+
+int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
+{
+ // no console for unopkg.bin when started by unopkg.exe
+ return desktop_win32::unopkgloader_impl(false);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */