summaryrefslogtreecommitdiff
path: root/desktop/win32
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/win32')
-rw-r--r--desktop/win32/source/guiloader/genericloader.cxx2
-rw-r--r--desktop/win32/source/loader.cxx53
-rw-r--r--desktop/win32/source/loader.hxx4
-rw-r--r--desktop/win32/source/officeloader/officeloader.cxx2
4 files changed, 50 insertions, 11 deletions
diff --git a/desktop/win32/source/guiloader/genericloader.cxx b/desktop/win32/source/guiloader/genericloader.cxx
index cdad10687b0e..db66ee39445b 100644
--- a/desktop/win32/source/guiloader/genericloader.cxx
+++ b/desktop/win32/source/guiloader/genericloader.cxx
@@ -47,7 +47,7 @@ static int GenericMain()
TCHAR szIniDirectory[MAX_PATH];
STARTUPINFO aStartupInfo;
- desktop_win32::getPaths(szTargetFileName, szIniDirectory);
+ desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory);
ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
aStartupInfo.cb = sizeof(aStartupInfo);
diff --git a/desktop/win32/source/loader.cxx b/desktop/win32/source/loader.cxx
index 948d370987b5..9cb133d1d573 100644
--- a/desktop/win32/source/loader.cxx
+++ b/desktop/win32/source/loader.cxx
@@ -33,17 +33,28 @@
#include "loader.hxx"
+#include <cassert>
+
+namespace {
+
+void fail()
+{
+ LPWSTR buf = nullptr;
+ FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr,
+ GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, nullptr);
+ MessageBoxW(nullptr, buf, nullptr, MB_OK | MB_ICONERROR);
+ LocalFree(buf);
+ TerminateProcess(GetCurrentProcess(), 255);
+}
+
+}
+
namespace desktop_win32 {
-void getPaths(WCHAR * binPath, WCHAR * iniDirectory) {
+void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory) {
if (!GetModuleFileNameW(nullptr, iniDirectory, MAX_PATH)) {
- LPWSTR buf = nullptr;
- FormatMessageW(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr,
- GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, nullptr);
- MessageBoxW(nullptr, buf, nullptr, MB_OK | MB_ICONERROR);
- LocalFree(buf);
- TerminateProcess(GetCurrentProcess(), 255);
+ fail();
}
WCHAR * iniDirEnd = tools::filename(iniDirectory);
WCHAR name[MAX_PATH + MY_LENGTH(L".bin")];
@@ -65,6 +76,32 @@ void getPaths(WCHAR * binPath, WCHAR * iniDirectory) {
nameEnd[-1] = 'n';
tools::buildPath(binPath, iniDirectory, iniDirEnd, name, nameEnd - name);
*iniDirEnd = L'\0';
+ std::size_t const maxEnv = 32767;
+ WCHAR env[maxEnv];
+ DWORD n = GetEnvironmentVariableW(L"PATH", env, maxEnv);
+ if ((n >= maxEnv || n == 0) && GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
+ fail();
+ }
+ // must be first in PATH to override other entries
+ assert(*(iniDirEnd - 1) == L'\\'); // hence -1 below
+ if (wcsncmp(env, iniDirectory, iniDirEnd - iniDirectory - 1) != 0
+ || env[iniDirEnd - iniDirectory - 1] != L';')
+ {
+ WCHAR pad[MAX_PATH + maxEnv];
+ // hopefully std::size_t is large enough to not overflow
+ WCHAR * p = commandLineAppend(pad, iniDirectory, iniDirEnd - iniDirectory - 1);
+ if (n != 0) {
+ *p++ = L';';
+ for (DWORD i = 0; i <= n; ++i) {
+ *p++ = env[i];
+ }
+ } else {
+ *p++ = L'\0';
+ }
+ if (!SetEnvironmentVariableW(L"PATH", pad)) {
+ fail();
+ }
+ }
}
}
diff --git a/desktop/win32/source/loader.hxx b/desktop/win32/source/loader.hxx
index e8a987650036..365afa637ffe 100644
--- a/desktop/win32/source/loader.hxx
+++ b/desktop/win32/source/loader.hxx
@@ -68,6 +68,8 @@ inline WCHAR * commandLineAppendEncoded(WCHAR * buffer, WCHAR const * text) {
return buffer;
}
+// Set the PATH environment variable in the current (loader) process, so that a
+// following CreateProcess has the necessary environment:
// @param binPath
// Must point to an array of size at least MAX_PATH. Is filled with the null
// terminated full path to the "bin" file corresponding to the current
@@ -76,7 +78,7 @@ inline WCHAR * commandLineAppendEncoded(WCHAR * buffer, WCHAR const * text) {
// Must point to an array of size at least MAX_PATH. Is filled with the null
// terminated full directory path (ending in "\") to the "ini" file
// corresponding to the current executable.
-void getPaths(WCHAR * binPath, WCHAR * iniDirectory);
+void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory);
}
diff --git a/desktop/win32/source/officeloader/officeloader.cxx b/desktop/win32/source/officeloader/officeloader.cxx
index 935cc7e42bb8..78c4bc1bfcec 100644
--- a/desktop/win32/source/officeloader/officeloader.cxx
+++ b/desktop/win32/source/officeloader/officeloader.cxx
@@ -62,7 +62,7 @@ int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
TCHAR szIniDirectory[MAX_PATH];
STARTUPINFO aStartupInfo;
- desktop_win32::getPaths(szTargetFileName, szIniDirectory);
+ desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory);
ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
aStartupInfo.cb = sizeof(aStartupInfo);