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