1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
32 #define WIN32_LEAN_AND_MEAN
34 #pragma warning(push, 1)
41 #include "tools/pathutils.hxx"
43 #include "pyversion.hxx"
45 #define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
46 #define MY_STRING(s) (s), MY_LENGTH(s)
48 wchar_t * encode(wchar_t * buffer
, wchar_t const * text
) {
55 } else if (c
== L
'"') {
56 // Double any preceding backslashes as required by Windows:
57 for (std::size_t i
= 0; i
< n
; ++i
) {
63 } else if (c
== L
'\\') {
71 // The command line will continue with a double quote, so double any
72 // preceding backslashes as required by Windows:
73 for (std::size_t i
= 0; i
< n
; ++i
) {
81 int main(int argc
, char ** argv
, char **) {
83 int wmain(int argc
, wchar_t ** argv
, wchar_t **) {
85 wchar_t path
[MAX_PATH
];
86 DWORD n
= GetModuleFileNameW(NULL
, path
, MAX_PATH
);
87 if (n
== 0 || n
>= MAX_PATH
) {
90 wchar_t * pathEnd
= tools::filename(path
);
92 n
= GetEnvironmentVariableW(L
"UNO_PATH", NULL
, 0);
94 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND
||
95 !SetEnvironmentVariableW(L
"UNO_PATH", path
))
100 wchar_t bootstrap
[MY_LENGTH(L
"vnd.sun.star.pathname:") + MAX_PATH
] =
101 L
"vnd.sun.star.pathname:"; //TODO: overflow
102 wchar_t * bootstrapEnd
= tools::buildPath(
103 bootstrap
+ MY_LENGTH(L
"vnd.sun.star.pathname:"), path
, pathEnd
,
104 MY_STRING(L
"fundamental.ini"));
105 if (bootstrapEnd
== NULL
||
106 (tools::buildPath(path
, path
, pathEnd
, MY_STRING(L
"..\\basis-link"))
111 pathEnd
= tools::resolveLink(path
);
112 wchar_t path1
[MAX_PATH
];
113 wchar_t * path1End
= tools::buildPath(
114 path1
, path
, pathEnd
, MY_STRING(L
"\\program"));
115 if (path1End
== NULL
) {
118 wchar_t pythonpath2
[MAX_PATH
];
119 wchar_t * pythonpath2End
= tools::buildPath(
120 pythonpath2
, path
, pathEnd
,
121 MY_STRING(L
"\\program\\python-core-" MY_PYVERSION L
"\\lib"));
122 if (pythonpath2End
== NULL
) {
125 wchar_t pythonpath3
[MAX_PATH
];
126 wchar_t * pythonpath3End
= tools::buildPath(
127 pythonpath3
, path
, pathEnd
,
129 L
"\\program\\python-core-" MY_PYVERSION L
"\\lib\\site-packages"));
130 if (pythonpath3End
== NULL
) {
134 wchar_t pythonpath4
[MAX_PATH
];
135 wchar_t * pythonpath4End
= tools::buildPath(
136 pythonpath4
, path
, pathEnd
,
137 MY_STRING(L
"\\program\\python-core-" MY_PYVERSION L
"\\lib\\lib-dynload"));
138 if (pythonpath4End
== NULL
) {
141 wchar_t pythonpath5
[MAX_PATH
];
142 wchar_t * pythonpath5End
= tools::buildPath(
143 pythonpath5
, path
, pathEnd
,
144 MY_STRING(L
"\\program\\python-core-" MY_PYVERSION L
"\\lib\\lib-dynload"));
145 if (pythonpath5End
== NULL
) {
149 wchar_t pythonhome
[MAX_PATH
];
150 wchar_t * pythonhomeEnd
= tools::buildPath(
151 pythonhome
, path
, pathEnd
,
152 MY_STRING(L
"\\program\\python-core-" MY_PYVERSION
));
153 if (pythonhomeEnd
== NULL
) {
156 wchar_t pythonexe
[MAX_PATH
];
157 wchar_t * pythonexeEnd
= tools::buildPath(
158 pythonexe
, path
, pathEnd
,
161 L
"\\program\\python-core-" MY_PYVERSION L
"\\bin\\python.bin"));
164 L
"\\program\\python-core-" MY_PYVERSION L
"\\bin\\python.exe"));
166 if (pythonexeEnd
== NULL
) {
169 if (tools::buildPath(path
, path
, pathEnd
, MY_STRING(L
"\\ure-link")) == NULL
)
173 pathEnd
= tools::resolveLink(path
);
174 if (pathEnd
== NULL
) {
177 pathEnd
= tools::buildPath(path
, path
, pathEnd
, MY_STRING(L
"\\bin"));
178 if (pathEnd
== NULL
) {
181 std::size_t clSize
= MY_LENGTH(L
"\"") + 4 * (pythonexeEnd
- pythonexe
) +
182 MY_LENGTH(L
"\"\0"); //TODO: overflow
183 // 4 * len: each char preceded by backslash, each trailing backslash
185 for (int i
= 1; i
< argc
; ++i
) {
187 clSize
+= MY_LENGTH(L
" \"") + 4 * strlen(argv
[i
]) +
189 clSize
+= MY_LENGTH(L
" \"") + 4 * wcslen(argv
[i
]) +
191 MY_LENGTH(L
"\""); //TODO: overflow
193 wchar_t * cl
= new wchar_t[clSize
];
197 wchar_t * cp
= encode(cl
, pythonhome
);
198 for (int i
= 1; i
< argc
; ++i
) {
201 int nNeededWStrBuffSize
= MultiByteToWideChar(CP_ACP
, 0, argv
[i
], -1, NULL
, 0);
202 WCHAR
*buff
= new WCHAR
[nNeededWStrBuffSize
+1];
203 MultiByteToWideChar(CP_ACP
, 0, argv
[i
], -1, buff
, nNeededWStrBuffSize
);
204 buff
[nNeededWStrBuffSize
] = 0;
205 cp
= encode(cp
, buff
);
208 cp
= encode(cp
, argv
[i
]);
212 n
= GetEnvironmentVariableW(L
"PATH", NULL
, 0);
215 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND
) {
220 orig
= new wchar_t[n
];
222 GetEnvironmentVariableW(L
"PATH", orig
, n
) != n
- 1)
227 wchar_t * value
= new wchar_t[
228 (pathEnd
- path
) + MY_LENGTH(L
";") + (path1End
- path1
) +
229 (n
== 0 ? 0 : MY_LENGTH(L
";") + (n
- 1)) + 1]; //TODO: overflow
230 wsprintfW(value
, L
"%s;%s%s%s", path
, path1
, n
== 0 ? L
"" : L
";", orig
);
231 if (!SetEnvironmentVariableW(L
"PATH", value
)) {
238 n
= GetEnvironmentVariableW(L
"PYTHONPATH", NULL
, 0);
240 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND
) {
245 orig
= new wchar_t[n
];
247 GetEnvironmentVariableW(L
"PYTHONPATH", orig
, n
) != n
- 1)
254 (path1End
- path1
) + MY_LENGTH(L
";") + (pythonpath2End
- pythonpath2
) +
255 MY_LENGTH(L
";") + (pythonpath4End
- pythonpath4
) +
256 MY_LENGTH(L
";") + (pythonpath5End
- pythonpath5
) +
257 MY_LENGTH(L
";") + (pythonpath3End
- pythonpath3
) +
258 (n
== 0 ? 0 : MY_LENGTH(L
";") + (n
- 1)) + 1]; //TODO: overflow
260 value
, L
"%s;%s;%s;%s;%s%s%s", path1
, pythonpath2
, pythonpath4
,
261 pythonpath5
, pythonpath3
,
262 n
== 0 ? L
"" : L
";", orig
);
265 (path1End
- path1
) + MY_LENGTH(L
";") + (pythonpath2End
- pythonpath2
) +
266 MY_LENGTH(L
";") + (pythonpath3End
- pythonpath3
) +
267 (n
== 0 ? 0 : MY_LENGTH(L
";") + (n
- 1)) + 1]; //TODO: overflow
269 value
, L
"%s;%s;%s%s%s", path1
, pythonpath2
, pythonpath3
,
270 n
== 0 ? L
"" : L
";", orig
);
272 if (!SetEnvironmentVariableW(L
"PYTHONPATH", value
)) {
279 if (!SetEnvironmentVariableW(L
"PYTHONHOME", pythonhome
)) {
282 n
= GetEnvironmentVariableW(L
"URE_BOOTSTRAP", NULL
, 0);
284 if (GetLastError() != ERROR_ENVVAR_NOT_FOUND
||
285 !SetEnvironmentVariableW(L
"URE_BOOTSTRAP", bootstrap
))
290 STARTUPINFOW startinfo
;
291 ZeroMemory(&startinfo
, sizeof (STARTUPINFOW
));
292 startinfo
.cb
= sizeof (STARTUPINFOW
);
293 PROCESS_INFORMATION procinfo
;
295 pythonexe
, cl
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, NULL
,
296 NULL
, &startinfo
, &procinfo
)) {
299 WaitForSingleObject(procinfo
.hProcess
,INFINITE
);
301 GetExitCodeProcess(procinfo
.hProcess
,&exitStatus
);