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