1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_desktop.hxx" 30 #define UNICODE 31 #define _UNICODE 32 33 #define WIN32_LEAN_AND_MEAN 34 #if defined _MSC_VER 35 #pragma warning(push, 1) 36 #endif 37 #include <windows.h> 38 #include <shellapi.h> 39 #if defined _MSC_VER 40 #pragma warning(pop) 41 #endif 42 43 #include <tchar.h> 44 45 #include <malloc.h> 46 #include <string.h> 47 #include <stdlib.h> 48 #include <systools/win32/uwinapi.h> 49 50 #include "tools/pathutils.hxx" 51 #include "../extendloaderenvironment.hxx" 52 53 //--------------------------------------------------------------------------- 54 55 static int GenericMain() 56 { 57 TCHAR szTargetFileName[MAX_PATH]; 58 TCHAR szIniDirectory[MAX_PATH]; 59 STARTUPINFO aStartupInfo; 60 61 desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory); 62 63 ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) ); 64 aStartupInfo.cb = sizeof(aStartupInfo); 65 66 GetStartupInfo( &aStartupInfo ); 67 68 DWORD dwExitCode = (DWORD)-1; 69 70 PROCESS_INFORMATION aProcessInfo; 71 72 size_t iniDirLen = wcslen(szIniDirectory); 73 WCHAR cwd[MAX_PATH]; 74 DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd); 75 if (cwdLen >= MAX_PATH) { 76 cwdLen = 0; 77 } 78 WCHAR redirect[MAX_PATH]; 79 DWORD dummy; 80 bool hasRedirect = 81 tools::buildPath( 82 redirect, szIniDirectory, szIniDirectory + iniDirLen, 83 MY_STRING(L"redirect.ini")) != NULL && 84 (GetBinaryType(redirect, &dummy) || // cheaper check for file existence? 85 GetLastError() != ERROR_FILE_NOT_FOUND); 86 LPTSTR cl1 = GetCommandLine(); 87 WCHAR * cl2 = new WCHAR[ 88 wcslen(cl1) + 89 (hasRedirect 90 ? (MY_LENGTH(L" \"-env:INIFILENAME=vnd.sun.star.pathname:") + 91 iniDirLen + MY_LENGTH(L"redirect.ini\"")) 92 : 0) + 93 MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen + MY_LENGTH(L"\"") + 1]; 94 // 4 * cwdLen: each char preceded by backslash, each trailing backslash 95 // doubled 96 WCHAR * p = desktop_win32::commandLineAppend(cl2, cl1); 97 if (hasRedirect) { 98 p = desktop_win32::commandLineAppend( 99 p, MY_STRING(L" \"-env:INIFILENAME=vnd.sun.star.pathname:")); 100 p = desktop_win32::commandLineAppend(p, szIniDirectory); 101 p = desktop_win32::commandLineAppend(p, MY_STRING(L"redirect.ini\"")); 102 } 103 p = desktop_win32::commandLineAppend(p, MY_STRING(L" \"-env:OOO_CWD=")); 104 if (cwdLen == 0) { 105 p = desktop_win32::commandLineAppend(p, MY_STRING(L"0")); 106 } else { 107 p = desktop_win32::commandLineAppend(p, MY_STRING(L"2")); 108 p = desktop_win32::commandLineAppendEncoded(p, cwd); 109 } 110 desktop_win32::commandLineAppend(p, MY_STRING(L"\"")); 111 112 BOOL fSuccess = CreateProcess( 113 szTargetFileName, 114 cl2, 115 NULL, 116 NULL, 117 TRUE, 118 0, 119 NULL, 120 szIniDirectory, 121 &aStartupInfo, 122 &aProcessInfo ); 123 124 delete[] cl2; 125 126 if ( fSuccess ) 127 { 128 DWORD dwWaitResult; 129 130 do 131 { 132 // On Windows XP it seems as the desktop calls WaitForInputIdle after "OpenWidth" so we have to do so 133 // as if we where processing any messages 134 135 dwWaitResult = MsgWaitForMultipleObjects( 1, &aProcessInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS ); 136 137 if ( WAIT_OBJECT_0 + 1 == dwWaitResult ) 138 { 139 MSG msg; 140 141 PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ); 142 } 143 } while ( WAIT_OBJECT_0 + 1 == dwWaitResult ); 144 145 dwExitCode = 0; 146 GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode ); 147 148 CloseHandle( aProcessInfo.hProcess ); 149 CloseHandle( aProcessInfo.hThread ); 150 } 151 152 return dwExitCode; 153 } 154 155 //--------------------------------------------------------------------------- 156 157 #ifdef __MINGW32__ 158 int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) 159 #else 160 int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int ) 161 #endif 162 { 163 return GenericMain(); 164 } 165 166 //--------------------------------------------------------------------------- 167 168 #ifdef __MINGW32__ 169 int __cdecl main() 170 #else 171 int __cdecl _tmain() 172 #endif 173 { 174 return GenericMain(); 175 } 176 177