Module: wine Branch: master Commit: a5d45e9ae5a6a88f859c1ca1f05b4c93a0817103 URL: https://source.winehq.org/git/wine.git/?a=commit;h=a5d45e9ae5a6a88f859c1ca1f...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Oct 3 19:26:01 2019 +0200
kernel32: Move exe path functions to ntdll.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/process.c | 19 ++++++++---- dlls/kernel32/tests/path.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/loader.c | 25 ++++++++++++++++ dlls/ntdll/ntdll.spec | 1 + include/winternl.h | 1 + 5 files changed, 116 insertions(+), 5 deletions(-)
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 3aae3d129e..d2682ac83e 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -438,11 +438,18 @@ static HANDLE open_exe_file( const WCHAR *name, BOOL *is_64bit ) */ static BOOL find_exe_file( const WCHAR *name, WCHAR *buffer, int buflen, HANDLE *handle ) { - TRACE("looking for %s\n", debugstr_w(name) ); + WCHAR *load_path; + BOOL ret; + + if (!set_ntstatus( RtlGetExePath( name, &load_path ))) return FALSE; + + TRACE("looking for %s in %s\n", debugstr_w(name), debugstr_w(load_path) );
- if (!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; + ret = (SearchPathW( load_path, name, exeW, buflen, buffer, NULL ) || + /* no builtin found, try native without extension in case it is a Unix app */ + SearchPathW( load_path, name, NULL, buflen, buffer, NULL )); + RtlReleasePath( load_path ); + if (!ret) return FALSE;
TRACE( "Trying native exe %s\n", debugstr_w(buffer) ); *handle = CreateFileW( buffer, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, @@ -1412,12 +1419,14 @@ void * CDECL __wine_kernel_init(void) { BOOL is_64bit;
- if (!SearchPathW( NULL, __wine_main_wargv[0], exeW, MAX_PATH, main_exe_name, NULL ) && + RtlGetExePath( __wine_main_wargv[0], &load_path ); + if (!SearchPathW( load_path, __wine_main_wargv[0], exeW, MAX_PATH, main_exe_name, NULL ) && !get_builtin_path( __wine_main_wargv[0], exeW, main_exe_name, MAX_PATH, &is_64bit )) { MESSAGE( "wine: cannot find '%s'\n", __wine_main_argv[0] ); ExitProcess( GetLastError() ); } + RtlReleasePath( load_path ); update_library_argv0( main_exe_name ); if (!build_command_line( __wine_main_wargv )) goto error; start_wineboot( boot_events ); diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c index 1610370064..71577793b0 100644 --- a/dlls/kernel32/tests/path.c +++ b/dlls/kernel32/tests/path.c @@ -78,6 +78,7 @@ static BOOL (WINAPI *pRemoveDllDirectory)(DLL_DIRECTORY_COOKIE); static BOOL (WINAPI *pSetSearchPathMode)(DWORD); static BOOL (WINAPI *pSetDllDirectoryW)(LPCWSTR); static BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD); +static NTSTATUS (WINAPI *pRtlGetExePath)(LPCWSTR,LPWSTR*); static NTSTATUS (WINAPI *pRtlGetSearchPath)(LPWSTR*); static void (WINAPI *pRtlReleasePath)(LPWSTR); static NTSTATUS (WINAPI *pLdrGetDllPath)(LPCWSTR,ULONG,LPWSTR*,LPWSTR*); @@ -2218,6 +2219,7 @@ static void init_pointers(void) MAKEFUNC(CheckNameLegalDOS8Dot3A); mod = GetModuleHandleA("ntdll.dll"); MAKEFUNC(LdrGetDllPath); + MAKEFUNC(RtlGetExePath); MAKEFUNC(RtlGetSearchPath); MAKEFUNC(RtlReleasePath); #undef MAKEFUNC @@ -2570,6 +2572,78 @@ static void test_RtlGetSearchPath(void) SetEnvironmentVariableW( pathW, old_path ); }
+static void test_RtlGetExePath(void) +{ + static const WCHAR fooW[] = {'\','f','o','o',0}; + static const WCHAR emptyW[1]; + NTSTATUS ret; + WCHAR *path; + WCHAR buffer[2048], old_path[2048], dlldir[4]; + + if (!pRtlGetExePath) + { + win_skip( "RtlGetExePath isn't available\n" ); + return; + } + + GetEnvironmentVariableW( pathW, old_path, ARRAY_SIZE(old_path) ); + GetWindowsDirectoryW( buffer, ARRAY_SIZE(buffer) ); + lstrcpynW( dlldir, buffer, ARRAY_SIZE(dlldir) ); + SetEnvironmentVariableA( "NoDefaultCurrentDirectoryInExePath", NULL ); + + build_search_path( buffer, ARRAY_SIZE(buffer), NULL, FALSE ); + path = (WCHAR *)0xdeadbeef; + ret = pRtlGetExePath( fooW, &path ); + ok( !ret, "RtlGetExePath failed %x\n", ret ); + ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer)); + pRtlReleasePath( path ); + + build_search_path( buffer, ARRAY_SIZE(buffer), NULL, FALSE ); + path = (WCHAR *)0xdeadbeef; + ret = pRtlGetExePath( fooW + 1, &path ); + ok( !ret, "RtlGetExePath failed %x\n", ret ); + ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer)); + pRtlReleasePath( path ); + + SetEnvironmentVariableA( "NoDefaultCurrentDirectoryInExePath", "yes" ); + + build_search_path( buffer, ARRAY_SIZE(buffer), NULL, FALSE ); + path = (WCHAR *)0xdeadbeef; + ret = pRtlGetExePath( fooW, &path ); + ok( !ret, "RtlGetExePath failed %x\n", ret ); + ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer)); + pRtlReleasePath( path ); + + build_search_path( buffer, ARRAY_SIZE(buffer), emptyW, TRUE ); + path = (WCHAR *)0xdeadbeef; + ret = pRtlGetExePath( fooW + 1, &path ); + ok( !ret, "RtlGetExePath failed %x\n", ret ); + ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer)); + pRtlReleasePath( path ); + + SetEnvironmentVariableA( "PATH", "foo" ); + build_search_path( buffer, ARRAY_SIZE(buffer), NULL, FALSE ); + path = (WCHAR *)0xdeadbeef; + ret = pRtlGetExePath( fooW, &path ); + ok( !ret, "RtlGetExePath failed %x\n", ret ); + ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer)); + pRtlReleasePath( path ); + + if (pSetDllDirectoryW) + { + ok( pSetDllDirectoryW( dlldir ), "SetDllDirectoryW failed\n" ); + build_search_path( buffer, ARRAY_SIZE(buffer), NULL, FALSE ); + path = (WCHAR *)0xdeadbeef; + ret = pRtlGetExePath( fooW, &path ); + ok( !ret, "RtlGetExePath failed %x\n", ret ); + ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer)); + pRtlReleasePath( path ); + pSetDllDirectoryW( NULL ); + } + + SetEnvironmentVariableW( pathW, old_path ); +} + static void test_LdrGetDllPath(void) { static const WCHAR fooW[] = {'f','o','o',0}; @@ -2705,5 +2779,6 @@ START_TEST(path) test_CheckNameLegalDOS8Dot3(); test_SetSearchPathMode(); test_RtlGetSearchPath(); + test_RtlGetExePath(); test_LdrGetDllPath(); } diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 4b528b5ea8..5eacc5a23c 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -4132,6 +4132,31 @@ NTSTATUS WINAPI RtlSetSearchPathMode( ULONG flags ) }
+/****************************************************************** + * RtlGetExePath (NTDLL.@) + */ +NTSTATUS WINAPI RtlGetExePath( PCWSTR name, PWSTR *path ) +{ + static const WCHAR emptyW[1]; + const WCHAR *dlldir = dotW; + const WCHAR *module = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer; + + /* same check as NeedCurrentDirectoryForExePathW */ + if (!strchrW( name, '\' )) + { + static const WCHAR env_name[] = {'N','o','D','e','f','a','u','l','t','C','u','r','r','e','n','t', + 'D','i','r','e','c','t','o','r','y','I','n', + 'E','x','e','P','a','t','h',0}; + UNICODE_STRING name, value = { 0 }; + + RtlInitUnicodeString( &name, env_name ); + if (RtlQueryEnvironmentVariable_U( NULL, &name, &value ) != STATUS_VARIABLE_NOT_FOUND) + dlldir = emptyW; + } + return get_dll_load_path( module, dlldir, FALSE, path ); +} + + /****************************************************************** * RtlGetSearchPath (NTDLL.@) */ diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index c33f12121b..3dd184d8c7 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -687,6 +687,7 @@ @ stdcall RtlGetDaclSecurityDescriptor(ptr ptr ptr ptr) @ stub RtlGetElementGenericTable # @ stub RtlGetElementGenericTableAvl +@ stdcall RtlGetExePath(wstr ptr) # @ stub RtlGetFirstRange @ stdcall RtlGetFrame() @ stdcall RtlGetFullPathName_U(wstr long ptr ptr) diff --git a/include/winternl.h b/include/winternl.h index 95105c67b4..16df963770 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2724,6 +2724,7 @@ NTSYSAPI NTSTATUS WINAPI RtlGetControlSecurityDescriptor(PSECURITY_DESCRIPTOR, NTSYSAPI ULONG WINAPI RtlGetCurrentDirectory_U(ULONG, LPWSTR); NTSYSAPI PEB * WINAPI RtlGetCurrentPeb(void); NTSYSAPI NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR,PBOOLEAN,PACL *,PBOOLEAN); +NTSYSAPI NTSTATUS WINAPI RtlGetExePath(PCWSTR,PWSTR*); NTSYSAPI TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void); NTSYSAPI ULONG WINAPI RtlGetFullPathName_U(PCWSTR,ULONG,PWSTR,PWSTR*); NTSYSAPI NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID *,PBOOLEAN);