Alexandre Julliard : ntdll:
Use activation contexts information to load dlls (
based on a patch by Jacek Caban).
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Jul 26 06:36:47 CDT 2007
Module: wine
Branch: master
Commit: 76bd190a72902d6efab2c85f8aa0d775d02c68da
URL: http://source.winehq.org/git/wine.git/?a=commit;h=76bd190a72902d6efab2c85f8aa0d775d02c68da
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jul 25 21:33:46 2007 +0200
ntdll: Use activation contexts information to load dlls (based on a patch by Jacek Caban).
---
dlls/ntdll/loader.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 79 insertions(+), 0 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 700b673..5ed7df9 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1578,6 +1578,70 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, HANDLE file,
/***********************************************************************
+ * 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','\\'};
+
+ 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 */
+ }
+
+ needed = (windows_dir.Length + sizeof(winsxsW) + info->ulAssemblyDirectoryNameLength +
+ nameW.Length + 2*sizeof(WCHAR));
+
+ if (!(*fullname = p = RtlAllocateHeap( GetProcessHeap(), 0, needed )))
+ {
+ status = STATUS_NO_MEMORY;
+ goto done;
+ }
+ memcpy( p, windows_dir.Buffer, windows_dir.Length );
+ p += windows_dir.Length / sizeof(WCHAR);
+ memcpy( p, winsxsW, sizeof(winsxsW) );
+ p += sizeof(winsxsW) / sizeof(WCHAR);
+ memcpy( p, info->lpAssemblyDirectoryName, info->ulAssemblyDirectoryNameLength );
+ p += info->ulAssemblyDirectoryNameLength / sizeof(WCHAR);
+ *p++ = '\\';
+ strcpyW( p, libname );
+ TRACE ("found %s for %s\n", debugstr_w(*fullname), debugstr_w(libname) );
+done:
+ RtlFreeHeap( GetProcessHeap(), 0, info );
+ RtlReleaseActivationContext( data.hActCtx );
+ return status;
+}
+
+
+/***********************************************************************
* find_dll_file
*
* Find the file (or already loaded module) for a given dll name.
@@ -1608,7 +1672,22 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
if (!contains_path( libname ))
{
+ NTSTATUS status;
+ WCHAR *fullname;
+
if ((*pwm = find_basename_module( libname )) != NULL) goto found;
+
+ status = find_actctx_dll( libname, &fullname );
+ if (status == STATUS_SUCCESS)
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, dllname );
+ libname = dllname = fullname;
+ }
+ else if (status != STATUS_SXS_KEY_NOT_FOUND)
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, dllname );
+ return status;
+ }
}
if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH)
More information about the wine-cvs
mailing list