1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_desktop.hxx" 26 #define UNICODE 27 #define _UNICODE 28 29 #define WIN32_LEAN_AND_MEAN 30 #if defined _MSC_VER 31 #pragma warning(push, 1) 32 #endif 33 #include <windows.h> 34 #include <shellapi.h> 35 #if defined _MSC_VER 36 #pragma warning(pop) 37 #endif 38 39 #include <tchar.h> 40 41 #include <malloc.h> 42 #include <string.h> 43 #include <stdlib.h> 44 #include <systools/win32/uwinapi.h> 45 46 #include "tools/pathutils.hxx" 47 #include "../extendloaderenvironment.hxx" 48 49 //--------------------------------------------------------------------------- 50 51 static int GenericMain() 52 { 53 TCHAR szTargetFileName[MAX_PATH]; 54 TCHAR szIniDirectory[MAX_PATH]; 55 STARTUPINFO aStartupInfo; 56 57 desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory); 58 59 ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) ); 60 aStartupInfo.cb = sizeof(aStartupInfo); 61 62 GetStartupInfo( &aStartupInfo ); 63 64 DWORD dwExitCode = (DWORD)-1; 65 66 PROCESS_INFORMATION aProcessInfo; 67 68 size_t iniDirLen = wcslen(szIniDirectory); 69 WCHAR cwd[MAX_PATH]; 70 DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd); 71 if (cwdLen >= MAX_PATH) { 72 cwdLen = 0; 73 } 74 WCHAR redirect[MAX_PATH]; 75 DWORD dummy; 76 bool hasRedirect = 77 tools::buildPath( 78 redirect, szIniDirectory, szIniDirectory + iniDirLen, 79 MY_STRING(L"redirect.ini")) != NULL && 80 (GetBinaryType(redirect, &dummy) || // cheaper check for file existence? 81 GetLastError() != ERROR_FILE_NOT_FOUND); 82 LPTSTR cl1 = GetCommandLine(); 83 WCHAR * cl2 = new WCHAR[ 84 wcslen(cl1) + 85 (hasRedirect 86 ? (MY_LENGTH(L" \"-env:INIFILENAME=vnd.sun.star.pathname:") + 87 iniDirLen + MY_LENGTH(L"redirect.ini\"")) 88 : 0) + 89 MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen + MY_LENGTH(L"\"") + 1]; 90 // 4 * cwdLen: each char preceded by backslash, each trailing backslash 91 // doubled 92 WCHAR * p = desktop_win32::commandLineAppend(cl2, cl1); 93 if (hasRedirect) { 94 p = desktop_win32::commandLineAppend( 95 p, MY_STRING(L" \"-env:INIFILENAME=vnd.sun.star.pathname:")); 96 p = desktop_win32::commandLineAppend(p, szIniDirectory); 97 p = desktop_win32::commandLineAppend(p, MY_STRING(L"redirect.ini\"")); 98 } 99 p = desktop_win32::commandLineAppend(p, MY_STRING(L" \"-env:OOO_CWD=")); 100 if (cwdLen == 0) { 101 p = desktop_win32::commandLineAppend(p, MY_STRING(L"0")); 102 } else { 103 p = desktop_win32::commandLineAppend(p, MY_STRING(L"2")); 104 p = desktop_win32::commandLineAppendEncoded(p, cwd); 105 } 106 desktop_win32::commandLineAppend(p, MY_STRING(L"\"")); 107 108 BOOL fSuccess = CreateProcess( 109 szTargetFileName, 110 cl2, 111 NULL, 112 NULL, 113 TRUE, 114 0, 115 NULL, 116 szIniDirectory, 117 &aStartupInfo, 118 &aProcessInfo ); 119 120 delete[] cl2; 121 122 if ( fSuccess ) 123 { 124 DWORD dwWaitResult; 125 126 do 127 { 128 // On Windows XP it seems as the desktop calls WaitForInputIdle after "OpenWidth" so we have to do so 129 // as if we where processing any messages 130 131 dwWaitResult = MsgWaitForMultipleObjects( 1, &aProcessInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS ); 132 133 if ( WAIT_OBJECT_0 + 1 == dwWaitResult ) 134 { 135 MSG msg; 136 137 PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ); 138 } 139 } while ( WAIT_OBJECT_0 + 1 == dwWaitResult ); 140 141 dwExitCode = 0; 142 GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode ); 143 144 CloseHandle( aProcessInfo.hProcess ); 145 CloseHandle( aProcessInfo.hThread ); 146 } 147 148 return dwExitCode; 149 } 150 151 //--------------------------------------------------------------------------- 152 153 #ifdef __MINGW32__ 154 int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) 155 #else 156 int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int ) 157 #endif 158 { 159 return GenericMain(); 160 } 161 162 //--------------------------------------------------------------------------- 163 164 #ifdef __MINGW32__ 165 int __cdecl main() 166 #else 167 int __cdecl _tmain() 168 #endif 169 { 170 return GenericMain(); 171 } 172 173