1*2722ceddSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2722ceddSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2722ceddSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2722ceddSAndrew Rist  * distributed with this work for additional information
6*2722ceddSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2722ceddSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2722ceddSAndrew Rist  * "License"); you may not use this file except in compliance
9*2722ceddSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*2722ceddSAndrew Rist  *
11*2722ceddSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*2722ceddSAndrew Rist  *
13*2722ceddSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2722ceddSAndrew Rist  * software distributed under the License is distributed on an
15*2722ceddSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2722ceddSAndrew Rist  * KIND, either express or implied.  See the License for the
17*2722ceddSAndrew Rist  * specific language governing permissions and limitations
18*2722ceddSAndrew Rist  * under the License.
19*2722ceddSAndrew Rist  *
20*2722ceddSAndrew Rist  *************************************************************/
21*2722ceddSAndrew Rist 
22*2722ceddSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_desktop.hxx"
26cdf0e10cSrcweir #define UNICODE
27cdf0e10cSrcweir #define _UNICODE
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <cstddef>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #define WIN32_LEAN_AND_MEAN
32cdf0e10cSrcweir #if defined _MSC_VER
33cdf0e10cSrcweir #pragma warning(push, 1)
34cdf0e10cSrcweir #endif
35cdf0e10cSrcweir #include <windows.h>
36cdf0e10cSrcweir #include <shellapi.h>
37cdf0e10cSrcweir #if defined _MSC_VER
38cdf0e10cSrcweir #pragma warning(pop)
39cdf0e10cSrcweir #endif
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include <tchar.h>
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #include <malloc.h>
44cdf0e10cSrcweir #include <string.h>
45cdf0e10cSrcweir #include <stdlib.h>
46cdf0e10cSrcweir #include <systools/win32/uwinapi.h>
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #include "rtl/string.h"
49cdf0e10cSrcweir 
50cdf0e10cSrcweir #include "../../../source/inc/exithelper.hxx"
51cdf0e10cSrcweir #include "../extendloaderenvironment.hxx"
52cdf0e10cSrcweir 
53cdf0e10cSrcweir #define PIPE_PREFIX					TEXT("\\\\.\\pipe\\OSL_PIPE_")
54cdf0e10cSrcweir #define	PIPE_POSTFIX				TEXT("_SingleOfficeIPC_")
55cdf0e10cSrcweir #define PIPE_TERMINATION_SEQUENCE	"InternalIPC::ProcessingDone"
56cdf0e10cSrcweir 
ConvertSidToStringSid(PSID pSid,LPTSTR * StringSid)57cdf0e10cSrcweir BOOL WINAPI ConvertSidToStringSid( PSID pSid, LPTSTR* StringSid )
58cdf0e10cSrcweir {
59cdf0e10cSrcweir     PSID_IDENTIFIER_AUTHORITY psia;
60cdf0e10cSrcweir     DWORD dwSubAuthorities;
61cdf0e10cSrcweir     DWORD dwSidRev=SID_REVISION;
62cdf0e10cSrcweir     DWORD dwCounter;
63cdf0e10cSrcweir     DWORD dwSidSize;
64cdf0e10cSrcweir 
65cdf0e10cSrcweir     // Validate the binary SID.
66cdf0e10cSrcweir 
67cdf0e10cSrcweir     if(!IsValidSid(pSid)) return FALSE;
68cdf0e10cSrcweir 
69cdf0e10cSrcweir     // Get the identifier authority value from the SID.
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     psia = GetSidIdentifierAuthority(pSid);
72cdf0e10cSrcweir 
73cdf0e10cSrcweir     // Get the number of subauthorities in the SID.
74cdf0e10cSrcweir 
75cdf0e10cSrcweir     dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
76cdf0e10cSrcweir 
77cdf0e10cSrcweir     // Compute the buffer length.
78cdf0e10cSrcweir     // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
79cdf0e10cSrcweir 
80cdf0e10cSrcweir     dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
81cdf0e10cSrcweir 
82cdf0e10cSrcweir 	*StringSid = (LPTSTR)LocalAlloc( LMEM_FIXED, dwSidSize );
83cdf0e10cSrcweir 
84cdf0e10cSrcweir     // Add 'S' prefix and revision number to the string.
85cdf0e10cSrcweir 
86cdf0e10cSrcweir     dwSidSize=wsprintf(*StringSid, TEXT("S-%lu-"), dwSidRev );
87cdf0e10cSrcweir 
88cdf0e10cSrcweir     // Add a SID identifier authority to the string.
89cdf0e10cSrcweir 
90cdf0e10cSrcweir     if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
91cdf0e10cSrcweir     {
92cdf0e10cSrcweir         dwSidSize+=wsprintf(*StringSid + lstrlen(*StringSid),
93cdf0e10cSrcweir                     TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
94cdf0e10cSrcweir                     (USHORT)psia->Value[0],
95cdf0e10cSrcweir                     (USHORT)psia->Value[1],
96cdf0e10cSrcweir                     (USHORT)psia->Value[2],
97cdf0e10cSrcweir                     (USHORT)psia->Value[3],
98cdf0e10cSrcweir                     (USHORT)psia->Value[4],
99cdf0e10cSrcweir                     (USHORT)psia->Value[5]);
100cdf0e10cSrcweir     }
101cdf0e10cSrcweir     else
102cdf0e10cSrcweir     {
103cdf0e10cSrcweir         dwSidSize+=wsprintf(*StringSid + lstrlen(*StringSid),
104cdf0e10cSrcweir                     TEXT("%lu"),
105cdf0e10cSrcweir                     (ULONG)(psia->Value[5]      )   +
106cdf0e10cSrcweir                     (ULONG)(psia->Value[4] <<  8)   +
107cdf0e10cSrcweir                     (ULONG)(psia->Value[3] << 16)   +
108cdf0e10cSrcweir                     (ULONG)(psia->Value[2] << 24)   );
109cdf0e10cSrcweir     }
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     // Add SID subauthorities to the string.
112cdf0e10cSrcweir     //
113cdf0e10cSrcweir     for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
114cdf0e10cSrcweir     {
115cdf0e10cSrcweir         dwSidSize+=wsprintf(*StringSid + dwSidSize, TEXT("-%lu"),
116cdf0e10cSrcweir                     *GetSidSubAuthority(pSid, dwCounter) );
117cdf0e10cSrcweir     }
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     return TRUE;
120cdf0e10cSrcweir }
121cdf0e10cSrcweir 
122cdf0e10cSrcweir 
123cdf0e10cSrcweir //---------------------------------------------------------------------------
124cdf0e10cSrcweir 
GetCommandArgs(int * pArgc)125cdf0e10cSrcweir static LPTSTR	*GetCommandArgs( int *pArgc )
126cdf0e10cSrcweir {
127cdf0e10cSrcweir #ifdef UNICODE
128cdf0e10cSrcweir 	return CommandLineToArgvW( GetCommandLineW(), pArgc );
129cdf0e10cSrcweir #else
130cdf0e10cSrcweir 	*pArgc = __argc;
131cdf0e10cSrcweir 	return __argv;
132cdf0e10cSrcweir #endif
133cdf0e10cSrcweir }
134cdf0e10cSrcweir 
135cdf0e10cSrcweir //---------------------------------------------------------------------------
136cdf0e10cSrcweir 
137cdf0e10cSrcweir namespace {
138cdf0e10cSrcweir 
writeArgument(HANDLE pipe,char prefix,WCHAR const * argument)139cdf0e10cSrcweir bool writeArgument(HANDLE pipe, char prefix, WCHAR const * argument) {
140cdf0e10cSrcweir     CHAR szBuffer[4096];
141cdf0e10cSrcweir     int n = WideCharToMultiByte(
142cdf0e10cSrcweir         CP_UTF8, 0, argument, -1, szBuffer, sizeof (szBuffer), NULL, NULL);
143cdf0e10cSrcweir     char b[1 + 2 * ((sizeof szBuffer) - 1)]; // hopefully does not overflow
144cdf0e10cSrcweir     b[0] = prefix;
145cdf0e10cSrcweir     char * p = b + 1;
146cdf0e10cSrcweir     for (int i = 0; i < n - 1; ++i) { // cannot underflow (n >= 0)
147cdf0e10cSrcweir         char c = szBuffer[i];
148cdf0e10cSrcweir         switch (c) {
149cdf0e10cSrcweir         case '\0':
150cdf0e10cSrcweir             *p++ = '\\';
151cdf0e10cSrcweir             *p++ = '0';
152cdf0e10cSrcweir             break;
153cdf0e10cSrcweir         case ',':
154cdf0e10cSrcweir             *p++ = '\\';
155cdf0e10cSrcweir             *p++ = ',';
156cdf0e10cSrcweir             break;
157cdf0e10cSrcweir         case '\\':
158cdf0e10cSrcweir             *p++ = '\\';
159cdf0e10cSrcweir             *p++ = '\\';
160cdf0e10cSrcweir             break;
161cdf0e10cSrcweir         default:
162cdf0e10cSrcweir             *p++ = c;
163cdf0e10cSrcweir             break;
164cdf0e10cSrcweir         }
165cdf0e10cSrcweir     }
166cdf0e10cSrcweir     DWORD w;
167cdf0e10cSrcweir     return WriteFile(pipe, b, p - b, &w, NULL);
168cdf0e10cSrcweir }
169cdf0e10cSrcweir 
170cdf0e10cSrcweir }
171cdf0e10cSrcweir 
172cdf0e10cSrcweir #ifdef __MINGW32__
WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int)173cdf0e10cSrcweir int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int )
174cdf0e10cSrcweir #else
175cdf0e10cSrcweir int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
176cdf0e10cSrcweir #endif
177cdf0e10cSrcweir {
178cdf0e10cSrcweir 	TCHAR				szTargetFileName[MAX_PATH] = TEXT("");
179cdf0e10cSrcweir     TCHAR               szIniDirectory[MAX_PATH];
180cdf0e10cSrcweir 	TCHAR				szPerfTuneIniFile[MAX_PATH] = TEXT("");
181cdf0e10cSrcweir 	STARTUPINFO			aStartupInfo;
182cdf0e10cSrcweir 
183cdf0e10cSrcweir     desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory);
184cdf0e10cSrcweir 
185cdf0e10cSrcweir 	ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
186cdf0e10cSrcweir 	aStartupInfo.cb = sizeof(aStartupInfo);
187cdf0e10cSrcweir 
188cdf0e10cSrcweir 	GetStartupInfo( &aStartupInfo );
189cdf0e10cSrcweir 	// Get image path with same name but with .bin extension
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 	TCHAR				szModuleFileName[MAX_PATH];
192cdf0e10cSrcweir 
193cdf0e10cSrcweir 	GetModuleFileName( NULL, szModuleFileName, MAX_PATH );
194cdf0e10cSrcweir 	_TCHAR	*lpLastSlash = _tcsrchr( szModuleFileName, '\\' );
195cdf0e10cSrcweir 	if ( lpLastSlash )
196cdf0e10cSrcweir 	{
197cdf0e10cSrcweir 		size_t len = lpLastSlash - szModuleFileName + 1;
198cdf0e10cSrcweir 		_tcsncpy( szPerfTuneIniFile, szModuleFileName, len );
199cdf0e10cSrcweir 		_tcsncpy( szPerfTuneIniFile + len, _T("perftune.ini"), sizeof(szPerfTuneIniFile)/sizeof(szPerfTuneIniFile[0]) - len );
200cdf0e10cSrcweir 	}
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 	// Create process with same command line, environment and stdio handles which
203cdf0e10cSrcweir 	// are directed to the created pipes
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 	DWORD	dwExitCode = (DWORD)-1;
206cdf0e10cSrcweir 
207cdf0e10cSrcweir 	BOOL	fSuccess = FALSE;
208cdf0e10cSrcweir 	LPTSTR	lpCommandLine = NULL;
209cdf0e10cSrcweir     int argc = 0;
210cdf0e10cSrcweir     LPTSTR * argv = NULL;
211cdf0e10cSrcweir     bool bFirst = true;
212cdf0e10cSrcweir     WCHAR cwd[MAX_PATH];
213cdf0e10cSrcweir     DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd);
214cdf0e10cSrcweir     if (cwdLen >= MAX_PATH) {
215cdf0e10cSrcweir         cwdLen = 0;
216cdf0e10cSrcweir     }
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 	do
219cdf0e10cSrcweir 	{
220cdf0e10cSrcweir 		TCHAR	szKey[32];
221cdf0e10cSrcweir 
222cdf0e10cSrcweir 		GetPrivateProfileString(
223cdf0e10cSrcweir 			TEXT("PerformanceTuning"),
224cdf0e10cSrcweir 			TEXT("FastPipeCommunication"),
225cdf0e10cSrcweir 			TEXT("0"),
226cdf0e10cSrcweir 			szKey,
227cdf0e10cSrcweir 			elementsof(szKey),
228cdf0e10cSrcweir 			szPerfTuneIniFile
229cdf0e10cSrcweir 			);
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 		if ( 0 == _tcscmp( szKey, TEXT("1") ) )
232cdf0e10cSrcweir 		{
233cdf0e10cSrcweir 			HANDLE	hProcessToken;
234cdf0e10cSrcweir 
235cdf0e10cSrcweir 			if ( OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hProcessToken ) )
236cdf0e10cSrcweir 			{
237cdf0e10cSrcweir 				TCHAR	szPipeName[4096];
238cdf0e10cSrcweir 
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 				DWORD	dwTokenLength = 0;
241cdf0e10cSrcweir 
242cdf0e10cSrcweir 
243cdf0e10cSrcweir 				fSuccess = GetTokenInformation( hProcessToken, TokenUser, NULL, dwTokenLength, &dwTokenLength );
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 				PVOID	pTokenInfo = _alloca(dwTokenLength);
246cdf0e10cSrcweir 				fSuccess = GetTokenInformation( hProcessToken, TokenUser, pTokenInfo, dwTokenLength, &dwTokenLength );
247cdf0e10cSrcweir 				CloseHandle( hProcessToken );
248cdf0e10cSrcweir 
249cdf0e10cSrcweir 				PSID pSid = ((PTOKEN_USER)pTokenInfo)->User.Sid;
250cdf0e10cSrcweir 				LPTSTR	szUserIdent = NULL;
251cdf0e10cSrcweir 				TCHAR	szSUPD[11] = TEXT("0");
252cdf0e10cSrcweir 
253cdf0e10cSrcweir 				fSuccess = ConvertSidToStringSid( pSid, &szUserIdent );
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 				_tcsncpy( szPipeName, PIPE_PREFIX, elementsof(szPipeName) );
256cdf0e10cSrcweir 				_tcsncat( szPipeName, szUserIdent, elementsof(szPipeName) - _tcslen(szPipeName) - 1 );
257cdf0e10cSrcweir 				_tcsncat( szPipeName, PIPE_POSTFIX, elementsof(szPipeName) - _tcslen(szPipeName) - 1 );
258cdf0e10cSrcweir 				_tcsncat( szPipeName, _ultot( SUPD, szSUPD, 10), elementsof(szPipeName) - _tcslen(szPipeName) - 1 );
259cdf0e10cSrcweir 
260cdf0e10cSrcweir 				LocalFree( szUserIdent );
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 				HANDLE	hPipe = CreateFile(
263cdf0e10cSrcweir 									szPipeName,
264cdf0e10cSrcweir 									GENERIC_READ|GENERIC_WRITE,
265cdf0e10cSrcweir 									FILE_SHARE_READ | FILE_SHARE_WRITE,
266cdf0e10cSrcweir 									NULL,
267cdf0e10cSrcweir 									OPEN_EXISTING,
268cdf0e10cSrcweir 									FILE_ATTRIBUTE_NORMAL,
269cdf0e10cSrcweir 									NULL);
270cdf0e10cSrcweir 
271cdf0e10cSrcweir 				if ( INVALID_HANDLE_VALUE != hPipe )
272cdf0e10cSrcweir 				{
273cdf0e10cSrcweir 					DWORD	dwBytesWritten;
274cdf0e10cSrcweir 					int	argc = 0;
275cdf0e10cSrcweir 					LPWSTR	*argv = CommandLineToArgvW( GetCommandLine(), &argc );
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 					fSuccess = WriteFile( hPipe, RTL_CONSTASCII_STRINGPARAM("InternalIPC::Arguments"), &dwBytesWritten, NULL );
278cdf0e10cSrcweir                     if (fSuccess) {
279cdf0e10cSrcweir                         if (cwdLen > 0) {
280cdf0e10cSrcweir                             fSuccess = writeArgument(hPipe, '2', cwd);
281cdf0e10cSrcweir                         } else {
282cdf0e10cSrcweir                             fSuccess = WriteFile(
283cdf0e10cSrcweir                                 hPipe, RTL_CONSTASCII_STRINGPARAM("0"),
284cdf0e10cSrcweir                                 &dwBytesWritten, NULL);
285cdf0e10cSrcweir                         }
286cdf0e10cSrcweir                     }
287cdf0e10cSrcweir 					for ( int argn = 1; fSuccess && argn < argc; argn++ )
288cdf0e10cSrcweir 					{
289cdf0e10cSrcweir                         fSuccess = writeArgument(hPipe, ',', argv[argn]);
290cdf0e10cSrcweir 					}
291cdf0e10cSrcweir 
292cdf0e10cSrcweir 					if ( fSuccess )
293cdf0e10cSrcweir 					{
294cdf0e10cSrcweir 						fSuccess = WriteFile(  hPipe, "", 1, &dwBytesWritten, NULL );
295cdf0e10cSrcweir 						if ( fSuccess )
296cdf0e10cSrcweir 						{
297cdf0e10cSrcweir 							DWORD	dwBytesRead = 0;
298cdf0e10cSrcweir 							char	*pBuffer = (char *)_alloca( sizeof(PIPE_TERMINATION_SEQUENCE) );
299cdf0e10cSrcweir 							fSuccess = ReadFile( hPipe, pBuffer, sizeof(PIPE_TERMINATION_SEQUENCE) - 1, &dwBytesRead, NULL );
300cdf0e10cSrcweir 							if ( fSuccess )
301cdf0e10cSrcweir 							{
302cdf0e10cSrcweir 								pBuffer[dwBytesRead] = 0;
303cdf0e10cSrcweir 								if ( 0 != strcmp( PIPE_TERMINATION_SEQUENCE, pBuffer ) )
304cdf0e10cSrcweir 									fSuccess = FALSE;
305cdf0e10cSrcweir 							}
306cdf0e10cSrcweir 						}
307cdf0e10cSrcweir 					}
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 					CloseHandle( hPipe );
310cdf0e10cSrcweir 
311cdf0e10cSrcweir 					return fSuccess ? 0 : -1;
312cdf0e10cSrcweir 				}
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 			}
315cdf0e10cSrcweir 		}
316cdf0e10cSrcweir 
317cdf0e10cSrcweir         if ( bFirst ) {
318cdf0e10cSrcweir             argv = GetCommandArgs(&argc);
319cdf0e10cSrcweir             std::size_t n = wcslen(argv[0]) + 2;
320cdf0e10cSrcweir             for (int i = 1; i < argc; ++i) {
321cdf0e10cSrcweir                 n += wcslen(argv[i]) + 3;
322cdf0e10cSrcweir             }
323cdf0e10cSrcweir             n += MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen +
324cdf0e10cSrcweir                 MY_LENGTH(L"\"") + 1;
325cdf0e10cSrcweir                 // 4 * cwdLen: each char preceded by backslash, each trailing
326cdf0e10cSrcweir                 // backslash doubled
327cdf0e10cSrcweir             lpCommandLine = new WCHAR[n];
328cdf0e10cSrcweir         }
329cdf0e10cSrcweir         WCHAR * p = desktop_win32::commandLineAppend(
330cdf0e10cSrcweir             lpCommandLine, MY_STRING(L"\""));
331cdf0e10cSrcweir         p = desktop_win32::commandLineAppend(p, argv[0]);
332cdf0e10cSrcweir         for (int i = 1; i < argc; ++i) {
333cdf0e10cSrcweir             if (bFirst || ::desktop::ExitHelper::E_NORMAL_RESTART == dwExitCode || wcsncmp(argv[i], MY_STRING(L"-env:")) == 0) {
334cdf0e10cSrcweir                 p = desktop_win32::commandLineAppend(p, MY_STRING(L"\" \""));
335cdf0e10cSrcweir                 p = desktop_win32::commandLineAppend(p, argv[i]);
336cdf0e10cSrcweir             }
337cdf0e10cSrcweir         }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir         p = desktop_win32::commandLineAppend(
340cdf0e10cSrcweir             p, MY_STRING(L"\" \"-env:OOO_CWD="));
341cdf0e10cSrcweir         if (cwdLen == 0) {
342cdf0e10cSrcweir             p = desktop_win32::commandLineAppend(p, MY_STRING(L"0"));
343cdf0e10cSrcweir         } else {
344cdf0e10cSrcweir             p = desktop_win32::commandLineAppend(p, MY_STRING(L"2"));
345cdf0e10cSrcweir             p = desktop_win32::commandLineAppendEncoded(p, cwd);
346cdf0e10cSrcweir         }
347cdf0e10cSrcweir         desktop_win32::commandLineAppend(p, MY_STRING(L"\""));
348cdf0e10cSrcweir         bFirst = false;
349cdf0e10cSrcweir 
350cdf0e10cSrcweir 		TCHAR	szParentProcessId[64]; // This is more than large enough for a 128 bit decimal value
351cdf0e10cSrcweir 		BOOL    bHeadlessMode( FALSE );
352cdf0e10cSrcweir 
353cdf0e10cSrcweir         {
354cdf0e10cSrcweir             // Check command line arguments for "-headless" parameter. We only
355cdf0e10cSrcweir             // set the environment variable "ATTACHED_PARENT_PROCESSID" for the headless
356cdf0e10cSrcweir             // mode as self-destruction of the soffice.bin process can lead to
357cdf0e10cSrcweir             // certain side-effects (log-off can result in data-loss, ".lock" is not deleted.
358cdf0e10cSrcweir             // See 138244 for more information.
359cdf0e10cSrcweir             int		argc;
360cdf0e10cSrcweir 		    LPTSTR	*argv = GetCommandArgs( &argc );
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 		    if ( argc > 1 )
363cdf0e10cSrcweir 		    {
364cdf0e10cSrcweir 			    int n;
365cdf0e10cSrcweir 
366cdf0e10cSrcweir 			    for ( n = 1; n < argc; n++ )
367cdf0e10cSrcweir 			    {
368cdf0e10cSrcweir 		            if ( 0 == _tcsnicmp( argv[n], _T("-headless"), 9 ) )
369cdf0e10cSrcweir                         bHeadlessMode = TRUE;
370cdf0e10cSrcweir 			    }
371cdf0e10cSrcweir             }
372cdf0e10cSrcweir         }
373cdf0e10cSrcweir 
374cdf0e10cSrcweir         if ( _ltot( (long)GetCurrentProcessId(),szParentProcessId, 10 ) && bHeadlessMode )
375cdf0e10cSrcweir 			SetEnvironmentVariable( TEXT("ATTACHED_PARENT_PROCESSID"), szParentProcessId );
376cdf0e10cSrcweir 
377cdf0e10cSrcweir 		PROCESS_INFORMATION	aProcessInfo;
378cdf0e10cSrcweir 
379cdf0e10cSrcweir 		fSuccess = CreateProcess(
380cdf0e10cSrcweir 			szTargetFileName,
381cdf0e10cSrcweir 			lpCommandLine,
382cdf0e10cSrcweir 			NULL,
383cdf0e10cSrcweir 			NULL,
384cdf0e10cSrcweir 			TRUE,
385cdf0e10cSrcweir 			0,
386cdf0e10cSrcweir 			NULL,
387cdf0e10cSrcweir 			szIniDirectory,
388cdf0e10cSrcweir 			&aStartupInfo,
389cdf0e10cSrcweir 			&aProcessInfo );
390cdf0e10cSrcweir 
391cdf0e10cSrcweir 		if ( fSuccess )
392cdf0e10cSrcweir 		{
393cdf0e10cSrcweir 			DWORD	dwWaitResult;
394cdf0e10cSrcweir 
395cdf0e10cSrcweir 			do
396cdf0e10cSrcweir 			{
397cdf0e10cSrcweir 				// On Windows XP it seems as the desktop calls WaitForInputIdle after "OpenWidth" so we have to do so
398cdf0e10cSrcweir 				// as if we where processing any messages
399cdf0e10cSrcweir 
400cdf0e10cSrcweir 				dwWaitResult = MsgWaitForMultipleObjects( 1, &aProcessInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS );
401cdf0e10cSrcweir 
402cdf0e10cSrcweir 				if (  WAIT_OBJECT_0 + 1 == dwWaitResult )
403cdf0e10cSrcweir 				{
404cdf0e10cSrcweir 					MSG	msg;
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 					PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
407cdf0e10cSrcweir 				}
408cdf0e10cSrcweir 			} while ( WAIT_OBJECT_0 + 1 == dwWaitResult );
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 			dwExitCode = 0;
411cdf0e10cSrcweir 			GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode );
412cdf0e10cSrcweir 
413cdf0e10cSrcweir 			CloseHandle( aProcessInfo.hProcess );
414cdf0e10cSrcweir 			CloseHandle( aProcessInfo.hThread );
415cdf0e10cSrcweir 		}
416cdf0e10cSrcweir 	} while ( fSuccess
417cdf0e10cSrcweir               && ( ::desktop::ExitHelper::E_CRASH_WITH_RESTART == dwExitCode || ::desktop::ExitHelper::E_NORMAL_RESTART == dwExitCode ));
418cdf0e10cSrcweir     delete[] lpCommandLine;
419cdf0e10cSrcweir 
420cdf0e10cSrcweir 	return fSuccess ? dwExitCode : -1;
421cdf0e10cSrcweir }
422