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
GenericMain()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 were 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__
WinMain(HINSTANCE,HINSTANCE,LPSTR,int)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__
main()165 int __cdecl main()
166 #else
167 int __cdecl _tmain()
168 #endif
169 {
170 return GenericMain();
171 }
172
173