[PATCH v4 2/3] ntdll: Load builtin sxs dlls with the correct path
Fabian Maurer
dark.shadow4 at web.de
Thu Jun 20 10:50:31 CDT 2019
---
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
More information about the wine-devel
mailing list