--- dlls/kernel32/tests/actctx.c | 1 - dlls/ntdll/loader.c | 202 +++++++++++++++++++---------------- 2 files changed, 109 insertions(+), 94 deletions(-)
diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index 19a51db742..76368e273e 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -3481,7 +3481,6 @@ static void test_builtin_sxs(void) GetModuleFileNameA(module_msvcp, path_msvcp, sizeof(path_msvcp)); GetModuleFileNameA(module_msvcr, path_msvcr, sizeof(path_msvcr)); ok(strncasecmp(expected_path, path_msvcp, strlen(expected_path)) == 0, "Expected path to start with %s, got %s\n", expected_path, path_msvcp); - todo_wine ok(strncasecmp(expected_path, path_msvcr, strlen(expected_path)) == 0, "Expected path to start with %s, got %s\n", expected_path, path_msvcr);
DeactivateActCtx(0, cookie); diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 3d747edaba..c6d37ab14e 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1710,6 +1710,99 @@ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE module, const ANSI_STRING *name, }
+/*********************************************************************** + * find_actctx_dll + * + * Find the full path (if any) of the dll from the activation context. + */ +static NTSTATUS find_actctx_dll( LPCWSTR libname, LPWSTR *fullname ) +{ + static const WCHAR winsxsW[] = {'\','w','i','n','s','x','s','\'}; + static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0}; + + ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *info; + ACTCTX_SECTION_KEYED_DATA data; + UNICODE_STRING nameW; + NTSTATUS status; + SIZE_T needed, size = 1024; + WCHAR *p; + + RtlInitUnicodeString( &nameW, libname ); + data.cbSize = sizeof(data); + status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL, + ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, + &nameW, &data ); + if (status != STATUS_SUCCESS) return status; + + for (;;) + { + if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, size ))) + { + status = STATUS_NO_MEMORY; + goto done; + } + status = RtlQueryInformationActivationContext( 0, data.hActCtx, &data.ulAssemblyRosterIndex, + AssemblyDetailedInformationInActivationContext, + info, size, &needed ); + if (status == STATUS_SUCCESS) break; + if (status != STATUS_BUFFER_TOO_SMALL) goto done; + RtlFreeHeap( GetProcessHeap(), 0, info ); + size = needed; + /* restart with larger buffer */ + } + + if (!info->lpAssemblyManifestPath || !info->lpAssemblyDirectoryName) + { + status = STATUS_SXS_KEY_NOT_FOUND; + goto done; + } + + if ((p = strrchrW( info->lpAssemblyManifestPath, '\' ))) + { + DWORD dirlen = info->ulAssemblyDirectoryNameLength / sizeof(WCHAR); + + p++; + if (strncmpiW( p, info->lpAssemblyDirectoryName, dirlen ) || strcmpiW( p + dirlen, dotManifestW )) + { + /* manifest name does not match directory name, so it's not a global + * windows/winsxs manifest; use the manifest directory name instead */ + dirlen = p - info->lpAssemblyManifestPath; + needed = (dirlen + 1) * sizeof(WCHAR) + nameW.Length; + if (!(*fullname = p = RtlAllocateHeap( GetProcessHeap(), 0, needed ))) + { + status = STATUS_NO_MEMORY; + goto done; + } + memcpy( p, info->lpAssemblyManifestPath, dirlen * sizeof(WCHAR) ); + p += dirlen; + strcpyW( p, libname ); + goto done; + } + } + + needed = (strlenW(user_shared_data->NtSystemRoot) * sizeof(WCHAR) + + sizeof(winsxsW) + info->ulAssemblyDirectoryNameLength + nameW.Length + 2*sizeof(WCHAR)); + + if (!(*fullname = p = RtlAllocateHeap( GetProcessHeap(), 0, needed ))) + { + status = STATUS_NO_MEMORY; + goto done; + } + strcpyW( p, user_shared_data->NtSystemRoot ); + p += strlenW(p); + memcpy( p, winsxsW, sizeof(winsxsW) ); + p += ARRAY_SIZE( winsxsW ); + memcpy( p, info->lpAssemblyDirectoryName, info->ulAssemblyDirectoryNameLength ); + p += info->ulAssemblyDirectoryNameLength / sizeof(WCHAR); + *p++ = '\'; + strcpyW( p, libname ); +done: + RtlFreeHeap( GetProcessHeap(), 0, info ); + RtlReleaseActivationContext( data.hActCtx ); + return status; +} + + /*********************************************************************** * get_builtin_fullname * @@ -1722,6 +1815,8 @@ static BOOL get_builtin_fullname( UNICODE_STRING *nt_name, const UNICODE_STRING static const WCHAR soW[] = {'.','s','o',0}; WCHAR *p, *fullname; size_t i, len = strlen(filename); + WCHAR buffer[MAX_PATH]; + NTSTATUS status;
/* check if path can correspond to the dll we have */ if (path && (p = strrchrW( path->Buffer, '\' ))) @@ -1741,6 +1836,20 @@ static BOOL get_builtin_fullname( UNICODE_STRING *nt_name, const UNICODE_STRING } }
+ ascii_to_unicode(buffer, filename, strlen(filename) + 1); + status = find_actctx_dll(buffer, &fullname); + if (status == STATUS_SUCCESS) + { + strcpyW(buffer, fullname); + RtlFreeHeap(GetProcessHeap(), 0, fullname); + if (!(fullname = RtlAllocateHeap(GetProcessHeap(), 0, + (strlenW(nt_prefixW) + strlenW(buffer) + 1) * sizeof(WCHAR)))) + return FALSE; + strcpyW(fullname, nt_prefixW); + strcatW(fullname, buffer); + goto done; + } + if (!(fullname = RtlAllocateHeap( GetProcessHeap(), 0, (strlenW(system_dir) + len + 5) * sizeof(WCHAR) ))) return FALSE; @@ -2529,99 +2638,6 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, const UNICODE_STRING *nt_na }
-/*********************************************************************** - * find_actctx_dll - * - * Find the full path (if any) of the dll from the activation context. - */ -static NTSTATUS find_actctx_dll( LPCWSTR libname, LPWSTR *fullname ) -{ - static const WCHAR winsxsW[] = {'\','w','i','n','s','x','s','\'}; - static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0}; - - ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *info; - ACTCTX_SECTION_KEYED_DATA data; - UNICODE_STRING nameW; - NTSTATUS status; - SIZE_T needed, size = 1024; - WCHAR *p; - - RtlInitUnicodeString( &nameW, libname ); - data.cbSize = sizeof(data); - status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL, - ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, - &nameW, &data ); - if (status != STATUS_SUCCESS) return status; - - for (;;) - { - if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, size ))) - { - status = STATUS_NO_MEMORY; - goto done; - } - status = RtlQueryInformationActivationContext( 0, data.hActCtx, &data.ulAssemblyRosterIndex, - AssemblyDetailedInformationInActivationContext, - info, size, &needed ); - if (status == STATUS_SUCCESS) break; - if (status != STATUS_BUFFER_TOO_SMALL) goto done; - RtlFreeHeap( GetProcessHeap(), 0, info ); - size = needed; - /* restart with larger buffer */ - } - - if (!info->lpAssemblyManifestPath || !info->lpAssemblyDirectoryName) - { - status = STATUS_SXS_KEY_NOT_FOUND; - goto done; - } - - if ((p = strrchrW( info->lpAssemblyManifestPath, '\' ))) - { - DWORD dirlen = info->ulAssemblyDirectoryNameLength / sizeof(WCHAR); - - p++; - if (strncmpiW( p, info->lpAssemblyDirectoryName, dirlen ) || strcmpiW( p + dirlen, dotManifestW )) - { - /* manifest name does not match directory name, so it's not a global - * windows/winsxs manifest; use the manifest directory name instead */ - dirlen = p - info->lpAssemblyManifestPath; - needed = (dirlen + 1) * sizeof(WCHAR) + nameW.Length; - if (!(*fullname = p = RtlAllocateHeap( GetProcessHeap(), 0, needed ))) - { - status = STATUS_NO_MEMORY; - goto done; - } - memcpy( p, info->lpAssemblyManifestPath, dirlen * sizeof(WCHAR) ); - p += dirlen; - strcpyW( p, libname ); - goto done; - } - } - - needed = (strlenW(user_shared_data->NtSystemRoot) * sizeof(WCHAR) + - sizeof(winsxsW) + info->ulAssemblyDirectoryNameLength + nameW.Length + 2*sizeof(WCHAR)); - - if (!(*fullname = p = RtlAllocateHeap( GetProcessHeap(), 0, needed ))) - { - status = STATUS_NO_MEMORY; - goto done; - } - strcpyW( p, user_shared_data->NtSystemRoot ); - p += strlenW(p); - memcpy( p, winsxsW, sizeof(winsxsW) ); - p += ARRAY_SIZE( winsxsW ); - memcpy( p, info->lpAssemblyDirectoryName, info->ulAssemblyDirectoryNameLength ); - p += info->ulAssemblyDirectoryNameLength / sizeof(WCHAR); - *p++ = '\'; - strcpyW( p, libname ); -done: - RtlFreeHeap( GetProcessHeap(), 0, info ); - RtlReleaseActivationContext( data.hActCtx ); - return status; -} - - /*********************************************************************** * search_dll_file * -- 2.22.0