From: Bolan Chen <bolanchen123@gmail.com> --- dlls/ntdll/actctx.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index 1bf503eba91..d285b79049d 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -3568,6 +3568,7 @@ static NTSTATUS probe_private_path( struct actctx_loader *acl, struct assembly_i DWORD len; HANDLE file; UNICODE_STRING nameW; + WCHAR *manifest_dir = NULL; WCHAR *private_path = NULL; WCHAR *directory = NULL; WCHAR *buffer = NULL; @@ -3601,8 +3602,9 @@ static NTSTATUS probe_private_path( struct actctx_loader *acl, struct assembly_i debugstr_w( acl->actctx->config.info ) ); if (!lang || !wcsicmp( lang, L"neutral" ) || !wcscmp( lang, L"*")) lang = L""; - - len = wcslen( acl->actctx->appdir.info ); + + len = max( RtlGetFullPathName_U( acl->actctx->assemblies->manifest.info, 0, NULL, NULL ) / sizeof(WCHAR), + wcslen( acl->actctx->appdir.info ) ); total = len + 2 * wcslen( private_path ) + 2 * wcslen( ai->name ) + wcslen( lang ) + 12; if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0, total * sizeof(WCHAR) ))) @@ -3610,11 +3612,18 @@ static NTSTATUS probe_private_path( struct actctx_loader *acl, struct assembly_i RtlFreeHeap( GetProcessHeap(), 0, private_path ); return STATUS_NO_MEMORY; } + if(!(manifest_dir = RtlAllocateHeap( GetProcessHeap(), 0, total * sizeof(WCHAR) ))) + { + RtlFreeHeap( GetProcessHeap(), 0, private_path ); + RtlFreeHeap( GetProcessHeap(), 0, buffer ); + return STATUS_NO_MEMORY; + } if (!(directory = build_assembly_dir( ai ))) { RtlFreeHeap( GetProcessHeap(), 0, buffer ); RtlFreeHeap( GetProcessHeap(), 0, private_path ); + RtlFreeHeap( GetProcessHeap(), 0, manifest_dir ); return STATUS_NO_MEMORY; } @@ -3628,6 +3637,8 @@ static NTSTATUS probe_private_path( struct actctx_loader *acl, struct assembly_i SIZE_T path_len = end ? end - path : wcslen( path ); if (path_len) { + /* follow the same lookup order in lookup_assembly */ + /* but insert privatePath in between */ p = buffer + swprintf( buffer, total, L"%s%.*s", acl->actctx->appdir.info, (int)path_len, path); if (p > buffer && p[-1] != '\\') *p++ = '\\'; @@ -3638,6 +3649,22 @@ static NTSTATUS probe_private_path( struct actctx_loader *acl, struct assembly_i (int)path_len, path, ai->name ); status = open_manifest_file( acl, ai, lang, directory, buffer, total ); if (status != STATUS_SXS_ASSEMBLY_NOT_FOUND) break; + + if (RtlGetFullPathName_U( acl->actctx->assemblies->manifest.info, len * sizeof(WCHAR), manifest_dir, &p )) + { + *p = 0; + p = buffer + swprintf( buffer, total, L"%s%.*s", manifest_dir, + (int)path_len, path); + if (p > buffer && p[-1] != '\\') *p++ = '\\'; + *p = 0; + status = open_manifest_file( acl, ai, lang, directory, buffer, total ); + if (status != STATUS_SXS_ASSEMBLY_NOT_FOUND) break; + swprintf( buffer, total, L"%s%.*s\\%s\\", manifest_dir, + (int)path_len, path, ai->name ); + + status = open_manifest_file( acl, ai, lang, directory, buffer, total ); + if (status != STATUS_SXS_ASSEMBLY_NOT_FOUND) break; + } } if (!end) break; path = end + 1; @@ -3646,6 +3673,7 @@ static NTSTATUS probe_private_path( struct actctx_loader *acl, struct assembly_i RtlFreeHeap( GetProcessHeap(), 0, buffer); RtlFreeHeap( GetProcessHeap(), 0, directory ); RtlFreeHeap( GetProcessHeap(), 0, private_path ); + RtlFreeHeap( GetProcessHeap(), 0, manifest_dir ); return status; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10753