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 ************************************************************************/
28 #include "precompiled_desktop.hxx"
29 #include "sal/config.h"
33 #define WIN32_LEAN_AND_MEAN
35 #pragma warning(push, 1)
43 #include "tools/pathutils.hxx"
45 #include "extendloaderenvironment.hxx"
52 FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
, NULL
,
53 GetLastError(), 0, reinterpret_cast< LPWSTR
>(&buf
), 0, NULL
);
54 MessageBoxW(NULL
, buf
, NULL
, MB_OK
| MB_ICONERROR
);
56 TerminateProcess(GetCurrentProcess(), 255);
59 bool contains(WCHAR
const * paths
, WCHAR
const * path
, WCHAR
const * pathEnd
) {
60 WCHAR
const * q
= path
;
61 for (WCHAR
const * p
= paths
;; ++p
) {
74 if (q
!= pathEnd
&& *q
== c
) {
87 namespace desktop_win32
{
89 void extendLoaderEnvironment(WCHAR
* binPath
, WCHAR
* iniDirectory
) {
90 if (!GetModuleFileNameW(NULL
, iniDirectory
, MAX_PATH
)) {
93 WCHAR
* iniDirEnd
= tools::filename(iniDirectory
);
94 WCHAR name
[MAX_PATH
+ MY_LENGTH(L
".bin")];
95 // hopefully std::size_t is large enough to not overflow
96 WCHAR
* nameEnd
= name
;
97 for (WCHAR
* p
= iniDirEnd
; *p
!= L
'\0'; ++p
) {
100 if (!(nameEnd
- name
>= 4 && nameEnd
[-4] == L
'.' &&
101 (nameEnd
[-3] == L
'E' || nameEnd
[-3] == L
'e') &&
102 (nameEnd
[-2] == L
'X' || nameEnd
[-2] == L
'x') &&
103 (nameEnd
[-1] == L
'E' || nameEnd
[-1] == L
'e')))
111 tools::buildPath(binPath
, iniDirectory
, iniDirEnd
, name
, nameEnd
- name
);
113 WCHAR path
[MAX_PATH
];
114 WCHAR
* pathEnd
= tools::buildPath(
115 path
, iniDirectory
, iniDirEnd
, MY_STRING(L
"..\\basis-link"));
116 if (pathEnd
== NULL
) {
119 std::size_t const maxEnv
= 32767;
120 WCHAR pad
[2 * MAX_PATH
+ maxEnv
];
121 // hopefully std::size_t is large enough to not overflow
122 WCHAR
* padEnd
= NULL
;
124 DWORD n
= GetEnvironmentVariableW(L
"PATH", env
, maxEnv
);
125 if (n
>= maxEnv
|| n
== 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND
) {
130 pathEnd
= tools::resolveLink(path
);
131 if (pathEnd
== NULL
) {
132 if (GetLastError() != ERROR_FILE_NOT_FOUND
) {
135 // This path is only taken by testtool.exe in basis program directory;
136 // its PATH needs to include the brand program directory:
137 pathEnd
= tools::buildPath(
138 path
, iniDirectory
, iniDirEnd
, MY_STRING(L
".."));
139 if (pathEnd
== NULL
) {
142 padEnd
= tools::buildPath(
143 pad
, path
, pathEnd
, MY_STRING(L
"\\..\\program"));
144 if (padEnd
== NULL
) {
147 exclude1
= contains(env
, pad
, padEnd
);
151 WCHAR
* pad2
= exclude1
? pad
: padEnd
+ 1;
152 pathEnd
= tools::buildPath(path
, path
, pathEnd
, MY_STRING(L
"\\ure-link"));
153 if (pathEnd
== NULL
) {
156 pathEnd
= tools::resolveLink(path
);
157 if (pathEnd
== NULL
) {
160 padEnd
= tools::buildPath(pad2
, path
, pathEnd
, MY_STRING(L
"\\bin"));
161 if (padEnd
== NULL
) {
164 bool exclude2
= contains(env
, pad2
, padEnd
);
165 if (!(exclude1
&& exclude2
)) {
166 if (!(exclude1
|| exclude2
)) {
169 WCHAR
* p
= exclude2
? pad2
- 1 : padEnd
;
173 for (DWORD i
= 0; i
<= n
; ++i
) {
176 if (!SetEnvironmentVariableW(L
"PATH", pad
)) {