[Libreoffice-commits] core.git: 2 commits - desktop/Executable_unopkg_bin.mk desktop/Executable_unopkg_com.mk desktop/Executable_unopkg.mk desktop/win32 extensions/source

Mike Kaganski (via logerrit) logerrit at kemper.freedesktop.org
Thu Jan 23 05:20:56 UTC 2020


 desktop/Executable_unopkg.mk                     |    2 
 desktop/Executable_unopkg_bin.mk                 |    2 
 desktop/Executable_unopkg_com.mk                 |   11 
 desktop/win32/source/guiloader/genericloader.cxx |  133 -------
 desktop/win32/source/guistdio/guistdio.inc       |  437 -----------------------
 desktop/win32/source/guistdio/unopkgio.cxx       |   24 -
 desktop/win32/source/loader.cxx                  |   98 +++++
 desktop/win32/source/loader.hxx                  |    3 
 desktop/win32/source/officeloader/unopkg_com.cxx |   19 +
 desktop/win32/source/officeloader/unopkg_exe.cxx |   19 +
 extensions/source/logging/consolehandler.cxx     |   39 --
 11 files changed, 154 insertions(+), 633 deletions(-)

New commits:
commit 9a1610f8290f723e801864f9037d4467efd02d1a
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Wed Jan 22 22:57:02 2020 +0300
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Thu Jan 23 06:20:32 2020 +0100

    Revert "unopkg: Correctly display log messages on Windows"
    
    https://gerrit.libreoffice.org/c/core/+/87210 makes unopkg proper
    console application, which doesn't need old complexity of sending
    UTF-16 strings to console redirected to pipes, so this workaround
    is not needed anymore.
    
    This reverts commit 015e9f780bc133788f79868bb7fb0b1d4e81f5f3.
    
    Change-Id: I9ab49df2b9c9cb841e591c07fcea191119dbe382
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87217
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/extensions/source/logging/consolehandler.cxx b/extensions/source/logging/consolehandler.cxx
index d213f5aab002..d1455baa3178 100644
--- a/extensions/source/logging/consolehandler.cxx
+++ b/extensions/source/logging/consolehandler.cxx
@@ -31,15 +31,9 @@
 #include <cppuhelper/compbase.hxx>
 #include <cppuhelper/basemutex.hxx>
 #include <cppuhelper/supportsservice.hxx>
-#include <osl/thread.hxx>
 
 #include <stdio.h>
 
-#ifdef _WIN32
-#include <prewin.h>
-#include <postwin.h>
-#endif
-
 namespace logging
 {
     using ::com::sun::star::logging::XConsoleHandler;
@@ -221,38 +215,10 @@ namespace logging
     void SAL_CALL ConsoleHandler::flush(  )
     {
         MethodGuard aGuard( *this );
-#ifndef _WIN32
         fflush( stdout );
         fflush( stderr );
-#endif
-    }
-
-    namespace
-    {
-    void lcl_printConsole(const OString& sText)
-    {
-#ifdef _WIN32
-        DWORD nWrittenChars = 0;
-        OUString s = OStringToOUString(sText, RTL_TEXTENCODING_ASCII_US);
-        WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), s.getStr(), s.getLength() * 2,
-                  &nWrittenChars, nullptr);
-#else
-        fprintf(stdout, "%s\n", sText.getStr());
-#endif
     }
 
-    void lcl_printConsoleError(const OString& sText)
-    {
-#ifdef _WIN32
-        DWORD nWrittenChars = 0;
-        OUString s = OStringToOUString(sText, RTL_TEXTENCODING_ASCII_US);
-        WriteFile(GetStdHandle(STD_ERROR_HANDLE), s.getStr(), s.getLength() * 2,
-                  &nWrittenChars, nullptr);
-#else
-        fprintf(stderr, "%s\n", sText.getStr());
-#endif
-    }
-    } // namespace
 
     sal_Bool SAL_CALL ConsoleHandler::publish( const LogRecord& _rRecord )
     {
@@ -263,9 +229,10 @@ namespace logging
             return false;
 
         if ( _rRecord.Level >= m_nThreshold )
-            lcl_printConsoleError(sEntry);
+            fprintf( stderr, "%s\n", sEntry.getStr() );
         else
-            lcl_printConsole(sEntry);
+            fprintf( stdout, "%s\n", sEntry.getStr() );
+
         return true;
     }
 
commit ab0942240507e9be81dbe43e8d69b7f9273b124f
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Wed Jan 22 22:13:25 2020 +0300
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Thu Jan 23 06:20:22 2020 +0100

    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 at collabora.com>
    Tested-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/desktop/Executable_unopkg.mk b/desktop/Executable_unopkg.mk
index f1b6d6be6db9..28a753a570f5 100644
--- a/desktop/Executable_unopkg.mk
+++ b/desktop/Executable_unopkg.mk
@@ -21,7 +21,7 @@ $(eval $(call gb_Executable_use_system_win32_libs,unopkg,\
 ))
 
 $(eval $(call gb_Executable_add_exception_objects,unopkg,\
-    desktop/win32/source/guiloader/genericloader \
+    desktop/win32/source/officeloader/unopkg_exe \
 ))
 
 $(eval $(call gb_Executable_add_default_nativeres,unopkg))
diff --git a/desktop/Executable_unopkg_bin.mk b/desktop/Executable_unopkg_bin.mk
index d2e1175be236..f66d5ec25e0f 100644
--- a/desktop/Executable_unopkg_bin.mk
+++ b/desktop/Executable_unopkg_bin.mk
@@ -9,7 +9,7 @@
 
 $(eval $(call gb_Executable_Executable,unopkg_bin))
 
-$(eval $(call gb_Executable_set_targettype_gui,unopkg_bin,YES))
+$(eval $(call gb_Executable_set_targettype_gui,unopkg_bin,NO))
 
 $(eval $(call gb_Executable_set_include,unopkg_bin,\
     $$(INCLUDE) \
diff --git a/desktop/Executable_unopkg_com.mk b/desktop/Executable_unopkg_com.mk
index 616a757a7fa8..022479f05bbc 100644
--- a/desktop/Executable_unopkg_com.mk
+++ b/desktop/Executable_unopkg_com.mk
@@ -11,8 +11,17 @@ $(eval $(call gb_Executable_Executable,unopkg_com))
 
 $(eval $(call gb_Executable_set_targettype_gui,unopkg_com,NO))
 
+$(eval $(call gb_Executable_use_static_libraries,unopkg_com,\
+    ooopathutils \
+    winloader \
+))
+
+$(eval $(call gb_Executable_use_system_win32_libs,unopkg_com,\
+    shell32 \
+))
+
 $(eval $(call gb_Executable_add_exception_objects,unopkg_com,\
-    desktop/win32/source/guistdio/unopkgio \
+    desktop/win32/source/officeloader/unopkg_com \
 ))
 
 $(eval $(call gb_Executable_add_default_nativeres,unopkg_com))
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: */


More information about the Libreoffice-commits mailing list