diff options
Diffstat (limited to 'desktop/win32')
-rw-r--r-- | desktop/win32/source/guiloader/genericloader.cxx | 2 | ||||
-rw-r--r-- | desktop/win32/source/loader.cxx | 53 | ||||
-rw-r--r-- | desktop/win32/source/loader.hxx | 4 | ||||
-rw-r--r-- | desktop/win32/source/officeloader/officeloader.cxx | 2 |
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); |