From a5ec351f6eb76093c1f8fd894d5aa9a371a4d2b9 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Sat, 3 Jan 2015 21:12:27 -0700 Subject: [PATCH] Added patch for CreateProcess to prioritize the working directory over the system search path. --- README.md | 3 +- debian/changelog | 1 + patches/Makefile | 20 +++++ ...rchPath-test-demonstrating-the-prior.patch | 79 +++++++++++++++++++ ...rentDirectoryForExePath-does-not-use.patch | 26 ++++++ ...r-the-working-directory-first-when-l.patch | 36 +++++++++ .../definition | 1 + 7 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 patches/kernel32-NeedCurrentDirectoryForExePath/0001-kernel32-Add-SearchPath-test-demonstrating-the-prior.patch create mode 100644 patches/kernel32-NeedCurrentDirectoryForExePath/0002-kernel32-NeedCurrentDirectoryForExePath-does-not-use.patch create mode 100644 patches/kernel32-NeedCurrentDirectoryForExePath/0003-kernel32-Consider-the-working-directory-first-when-l.patch create mode 100644 patches/kernel32-NeedCurrentDirectoryForExePath/definition diff --git a/README.md b/README.md index 06f9d41a..4c860890 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,13 @@ Wine. All those differences are also documented on the Included bug fixes and improvements =================================== -**Bugfixes and features included in the next upcoming release [20]:** +**Bugfixes and features included in the next upcoming release [21]:** * Add stub for D3DXComputeNormalMap * Add stub for D3DXComputeTangentFrameEx ([Wine Bug #31984](https://bugs.winehq.org/show_bug.cgi?id=31984)) * Add stub for D3DXIntersect * Basic support for CUDA +* CreateProcess does not prioritize the working directory over the system search path ([Wine Bug #23934](https://bugs.winehq.org/show_bug.cgi?id=23934)) * Ensure X11 input events are handled even without explicit message loop ([Wine Bug #8854](https://bugs.winehq.org/show_bug.cgi?id=8854)) * Expose PKEY_AudioEndpoint_PhysicalSpeakers device property in PulseAudio driver * Fix access violation when calling GetStringTypeW with NULL src. ([Wine Bug #37759](https://bugs.winehq.org/show_bug.cgi?id=37759)) diff --git a/debian/changelog b/debian/changelog index 2e19a874..efe5ab74 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,7 @@ wine-staging (1.7.34) UNRELEASED; urgency=low * Fix issue in DOS Attributes patch which broke ./configure on systems with alternative shells. * Fix issue in user32-WndProc patch which caused crashes for some 16-bit apps. * Fix issue in ws2_32-WriteWatches patch which can cause exceptions on the signal stack. + * Added patch for CreateProcess to prioritize the working directory over the system search path. * Added patch with stubs for WinSqm[Start|End]Session. * Added patch to fix handling of subdirectory in FtpFindFirstFile. * Added patch to return proper charcount for GetLocaleInfo with LOCALE_IFIRSTDAYOFWEEK. diff --git a/patches/Makefile b/patches/Makefile index 337713db..b64ec976 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -57,6 +57,7 @@ PATCHLIST := \ kernel32-GetSystemTimes.ok \ kernel32-GetVolumePathName.ok \ kernel32-Named_Pipe.ok \ + kernel32-NeedCurrentDirectoryForExePath.ok \ kernel32-Profile.ok \ kernel32-UTF7_Support.ok \ kernel32-VerifyVersionInfo.ok \ @@ -846,6 +847,25 @@ kernel32-Named_Pipe.ok: echo '+ { "Sebastian Lackner", "kernel32/tests: Add additional tests for PIPE_NOWAIT in overlapped mode.", 1 },'; \ ) > kernel32-Named_Pipe.ok +# Patchset kernel32-NeedCurrentDirectoryForExePath +# | +# | This patchset fixes the following Wine bugs: +# | * [#23934] CreateProcess does not prioritize the working directory over the system search path +# | +# | Modified files: +# | * dlls/kernel32/path.c, dlls/kernel32/process.c, dlls/kernel32/tests/path.c +# | +.INTERMEDIATE: kernel32-NeedCurrentDirectoryForExePath.ok +kernel32-NeedCurrentDirectoryForExePath.ok: + $(call APPLY_FILE,kernel32-NeedCurrentDirectoryForExePath/0001-kernel32-Add-SearchPath-test-demonstrating-the-prior.patch) + $(call APPLY_FILE,kernel32-NeedCurrentDirectoryForExePath/0002-kernel32-NeedCurrentDirectoryForExePath-does-not-use.patch) + $(call APPLY_FILE,kernel32-NeedCurrentDirectoryForExePath/0003-kernel32-Consider-the-working-directory-first-when-l.patch) + @( \ + echo '+ { "Erich E. Hoover", "kernel32: Add SearchPath test demonstrating the priority of the working directory.", 1 },'; \ + echo '+ { "Erich E. Hoover", "kernel32: NeedCurrentDirectoryForExePath does not use the registry.", 1 },'; \ + echo '+ { "Erich E. Hoover", "kernel32: Consider the working directory first when launching executables with CreateProcess.", 1 },'; \ + ) > kernel32-NeedCurrentDirectoryForExePath.ok + # Patchset kernel32-Profile # | # | This patchset fixes the following Wine bugs: diff --git a/patches/kernel32-NeedCurrentDirectoryForExePath/0001-kernel32-Add-SearchPath-test-demonstrating-the-prior.patch b/patches/kernel32-NeedCurrentDirectoryForExePath/0001-kernel32-Add-SearchPath-test-demonstrating-the-prior.patch new file mode 100644 index 00000000..698bf092 --- /dev/null +++ b/patches/kernel32-NeedCurrentDirectoryForExePath/0001-kernel32-Add-SearchPath-test-demonstrating-the-prior.patch @@ -0,0 +1,79 @@ +From 06fa831ed7d8dbd55f6fb272e888d4d1ec096b4d Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +Date: Sat, 3 Jan 2015 20:24:07 -0700 +Subject: kernel32: Add SearchPath test demonstrating the priority of the + working directory. + +--- + dlls/kernel32/tests/path.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c +index 44f14d0..3600abe 100644 +--- a/dlls/kernel32/tests/path.c ++++ b/dlls/kernel32/tests/path.c +@@ -1002,8 +1002,10 @@ static void test_GetTempPath(void) + { + char save_TMP[MAX_PATH]; + char windir[MAX_PATH]; ++ char origdir[MAX_PATH]; + char buf[MAX_PATH]; + ++ GetCurrentDirectoryA(sizeof(origdir), origdir); + if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) save_TMP[0] = 0; + + /* test default configuration */ +@@ -1048,6 +1050,7 @@ static void test_GetTempPath(void) + test_GetTempPathW(windir); + + SetEnvironmentVariableA("TMP", save_TMP); ++ SetCurrentDirectoryA(origdir); + } + + static void test_GetLongPathNameA(void) +@@ -1644,10 +1647,11 @@ static void test_SearchPathA(void) + static const CHAR testdeprelA[] = "./testdep.dll"; + static const CHAR kernel32A[] = "kernel32.dll"; + static const CHAR fileA[] = ""; +- CHAR pathA[MAX_PATH], buffA[MAX_PATH], path2A[MAX_PATH]; +- CHAR *ptrA = NULL; ++ CHAR pathA[MAX_PATH], buffA[MAX_PATH], path2A[MAX_PATH], path3A[MAX_PATH], curdirA[MAX_PATH]; ++ CHAR tmpdirA[MAX_PATH], *ptrA = NULL; + ULONG_PTR cookie; + HANDLE handle; ++ BOOL bret; + DWORD ret; + + if (!pSearchPathA) +@@ -1721,6 +1725,28 @@ static void test_SearchPathA(void) + ret = pDeactivateActCtx(0, cookie); + ok(ret, "failed to deactivate context, %u\n", GetLastError()); + pReleaseActCtx(handle); ++ ++ /* test the search path priority of the working directory */ ++ GetTempPathA(sizeof(tmpdirA), tmpdirA); ++ ret = GetCurrentDirectoryA(MAX_PATH, curdirA); ++ ok(ret, "failed to obtain working directory.\n"); ++ sprintf(pathA, "%s\\%s", tmpdirA, kernel32A); ++ ret = pSearchPathA(NULL, kernel32A, NULL, sizeof(path2A)/sizeof(CHAR), path2A, NULL); ++ ok(ret && ret == strlen(path2A), "got %d\n", ret); ++ bret = CopyFileA(path2A, pathA, FALSE); ++ ok(bret != 0, "failed to copy test executable to temp directory, %u\n", GetLastError()); ++ sprintf(path3A, "%s%s%s", curdirA, curdirA[strlen(curdirA)-1] != '\\' ? "\\" : "", kernel32A); ++ bret = CopyFileA(path2A, path3A, FALSE); ++ ok(bret != 0, "failed to copy test executable to launch directory, %u\n", GetLastError()); ++ bret = SetCurrentDirectoryA(tmpdirA); ++ ok(bret, "failed to change working directory\n"); ++ ret = pSearchPathA(NULL, kernel32A, ".exe", sizeof(buffA), buffA, NULL); ++ ok(ret && ret == strlen(buffA), "got %d\n", ret); ++ ok(strcmp(buffA, path3A) == 0, "expected %s, got %s\n", path3A, buffA); ++ bret = SetCurrentDirectoryA(curdirA); ++ ok(bret, "failed to reset working directory\n"); ++ DeleteFileA(path3A); ++ DeleteFileA(pathA); + } + + static void test_SearchPathW(void) +-- +1.9.1 + diff --git a/patches/kernel32-NeedCurrentDirectoryForExePath/0002-kernel32-NeedCurrentDirectoryForExePath-does-not-use.patch b/patches/kernel32-NeedCurrentDirectoryForExePath/0002-kernel32-NeedCurrentDirectoryForExePath-does-not-use.patch new file mode 100644 index 00000000..076b61cf --- /dev/null +++ b/patches/kernel32-NeedCurrentDirectoryForExePath/0002-kernel32-NeedCurrentDirectoryForExePath-does-not-use.patch @@ -0,0 +1,26 @@ +From c500701514fb08730e881285b75fb000c97d1c15 Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +Date: Sat, 3 Jan 2015 20:57:27 -0700 +Subject: kernel32: NeedCurrentDirectoryForExePath does not use the registry. + +--- + dlls/kernel32/path.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c +index bb167a0..dc90e58 100644 +--- a/dlls/kernel32/path.c ++++ b/dlls/kernel32/path.c +@@ -1872,8 +1872,7 @@ BOOL WINAPI NeedCurrentDirectoryForExePathW( LPCWSTR name ) + 'I','n','E','x','e','P','a','t','h',0}; + WCHAR env_val; + +- /* MSDN mentions some 'registry location'. We do not use registry. */ +- FIXME("(%s): partial stub\n", debugstr_w(name)); ++ TRACE("(%s)\n"); + + if (strchrW(name, '\\')) + return TRUE; +-- +1.9.1 + diff --git a/patches/kernel32-NeedCurrentDirectoryForExePath/0003-kernel32-Consider-the-working-directory-first-when-l.patch b/patches/kernel32-NeedCurrentDirectoryForExePath/0003-kernel32-Consider-the-working-directory-first-when-l.patch new file mode 100644 index 00000000..8bf67632 --- /dev/null +++ b/patches/kernel32-NeedCurrentDirectoryForExePath/0003-kernel32-Consider-the-working-directory-first-when-l.patch @@ -0,0 +1,36 @@ +From b0949848b3ba61c901fd705c5769b2014a96dabf Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +Date: Sat, 3 Jan 2015 20:55:43 -0700 +Subject: kernel32: Consider the working directory first when launching + executables with CreateProcess. + +--- + dlls/kernel32/process.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c +index 0a087ab..ec9d991 100644 +--- a/dlls/kernel32/process.c ++++ b/dlls/kernel32/process.c +@@ -259,9 +259,17 @@ static HANDLE open_exe_file( const WCHAR *name, struct binary_info *binary_info + static BOOL find_exe_file( const WCHAR *name, WCHAR *buffer, int buflen, + HANDLE *handle, struct binary_info *binary_info ) + { ++ WCHAR cur_dir[MAX_PATH]; ++ + TRACE("looking for %s\n", debugstr_w(name) ); + +- if (!SearchPathW( NULL, name, exeW, buflen, buffer, NULL ) && ++ /* The working directory takes precedence over other locations for CreateProcess unless the ++ * 'NoDefaultCurrentDirectoryInExePath' environment variable is set (and the executable name ++ * does not contain a backslash). */ ++ if ((NeedCurrentDirectoryForExePathW( name ) && GetCurrentDirectoryW( MAX_PATH, cur_dir) && ++ !SearchPathW( cur_dir, name, exeW, buflen, buffer, NULL )) && ++ /* not found in the working directory, try the system search path */ ++ !SearchPathW( NULL, name, exeW, buflen, buffer, NULL ) && + /* no builtin found, try native without extension in case it is a Unix app */ + !SearchPathW( NULL, name, NULL, buflen, buffer, NULL )) return FALSE; + +-- +1.9.1 + diff --git a/patches/kernel32-NeedCurrentDirectoryForExePath/definition b/patches/kernel32-NeedCurrentDirectoryForExePath/definition new file mode 100644 index 00000000..eb7205da --- /dev/null +++ b/patches/kernel32-NeedCurrentDirectoryForExePath/definition @@ -0,0 +1 @@ +Fixes: [23934] CreateProcess does not prioritize the working directory over the system search path