From: Paul Gofman pgofman@codeweavers.com
--- dlls/kernel32/tests/module.c | 4 ++-- dlls/ntdll/loader.c | 38 +++++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/dlls/kernel32/tests/module.c b/dlls/kernel32/tests/module.c index 50ad86bd600..c05af6a235a 100644 --- a/dlls/kernel32/tests/module.c +++ b/dlls/kernel32/tests/module.c @@ -1655,10 +1655,10 @@ static void test_apiset_target_load(void) ok( !!hlocal, "Got NULL.\n" );
old_behaviour = (hsystem == hlocal); - todo_wine ok( hsystem != hlocal || broken( old_behaviour ), "Got same module.\n" ); + ok( hsystem != hlocal || broken( old_behaviour ), "Got same module.\n" );
hapiset = GetModuleHandleA( apiset_dll ); - todo_wine ok( hapiset == hsystem || broken( old_behaviour && !hapiset ), "Got %p, %p.\n", hapiset, hsystem ); + ok( hapiset == hsystem || broken( old_behaviour && !hapiset ), "Got %p, %p.\n", hapiset, hsystem );
h = GetModuleHandleA( "shcore.dll" ); ok( h == hsystem, "Got %p, %p.\n", h, hapiset ); diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 01a30742678..e68c6ac6c05 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -683,6 +683,27 @@ static NTSTATUS get_apiset_target( const API_SET_NAMESPACE *map, const API_SET_N }
+/****************************************************************************** + * is_apiset_target + */ +static BOOL is_apiset_target( const WCHAR *name ) +{ + const API_SET_NAMESPACE *map = NtCurrentTeb()->Peb->ApiSetMap; + const API_SET_NAMESPACE_ENTRY *entry; + UNICODE_STRING target; + ULONG i, len; + + for (i = 0; i < map->Count; ++i) + { + entry = (API_SET_NAMESPACE_ENTRY *)((char *)map + map->EntryOffset) + i; + if (get_apiset_target( map, entry, NULL, &target )) continue; + len = target.Length / sizeof(WCHAR); + if (!wcsnicmp( name, target.Buffer, len ) && !name[len]) return TRUE; + } + return FALSE; +} + + /********************************************************************** * build_import_name */ @@ -2997,17 +3018,18 @@ done: */ static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING *nt_name, WINE_MODREF **pwm, HANDLE *mapping, SECTION_IMAGE_INFORMATION *image_info, - struct file_id *id ) + struct file_id *id, BOOL system_dir_only ) { WCHAR *name; BOOL found_image = FALSE; NTSTATUS status = STATUS_DLL_NOT_FOUND; - ULONG len; + ULONG len, system_dir_len;
if (!paths) paths = default_load_path; len = wcslen( paths );
- if (len < wcslen( system_dir )) len = wcslen( system_dir ); + system_dir_len = wcslen( system_dir ); + if (len < system_dir_len) len = system_dir_len; len += wcslen( search ) + 2;
if (!(name = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) @@ -3022,6 +3044,11 @@ static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING * if (*ptr == ';') ptr++; memcpy( name, paths, len * sizeof(WCHAR) ); if (len && name[len - 1] != '\') name[len++] = '\'; + if (system_dir_only && (len != system_dir_len || wcsnicmp(name, system_dir, len))) + { + paths = ptr; + continue; + } wcscpy( name + len, search );
nt_name->Buffer = NULL; @@ -3086,7 +3113,8 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, UNI
if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH) { - status = search_dll_file( load_path, libname, nt_name, pwm, mapping, image_info, id ); + status = search_dll_file( load_path, libname, nt_name, pwm, mapping, image_info, id, + is_apiset_target( libname ) ); if (status == STATUS_DLL_NOT_FOUND) status = find_builtin_without_file( libname, nt_name, pwm, mapping, image_info, id ); } @@ -3120,7 +3148,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, DWORD fl TRACE( "looking for %s in %s\n", debugstr_w(libname), debugstr_w(load_path) );
if (system && system_dll_path.Buffer) - nts = search_dll_file( system_dll_path.Buffer, libname, &nt_name, pwm, &mapping, &image_info, &id ); + nts = search_dll_file( system_dll_path.Buffer, libname, &nt_name, pwm, &mapping, &image_info, &id, FALSE );
if (nts) {