Alexandre Julliard : ntdll: Add infrastructure for loading manifest dependencies ( based on a patch by Eric Pouech).

Alexandre Julliard julliard at wine.codeweavers.com
Fri Jul 20 06:02:06 CDT 2007


Module: wine
Branch: master
Commit: c5bf0947f605cefd9ddfc205e3418d083ce8e8d7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c5bf0947f605cefd9ddfc205e3418d083ce8e8d7

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jul 19 17:50:11 2007 +0200

ntdll: Add infrastructure for loading manifest dependencies (based on a patch by Eric Pouech).

---

 dlls/ntdll/actctx.c |  119 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c
index 1d06356..d46f77c 100644
--- a/dlls/ntdll/actctx.c
+++ b/dlls/ntdll/actctx.c
@@ -217,6 +217,42 @@ static void free_assembly_identity(struct assembly_identity *ai)
     RtlFreeHeap( GetProcessHeap(), 0, ai->arch );
 }
 
+static BOOL add_dependent_assembly_id(struct actctx_loader* acl,
+                                      struct assembly_identity* ai)
+{
+    /* FIXME: should check that the passed ai isn't already in the list */
+    if (acl->num_dependencies == acl->allocated_dependencies)
+    {
+        void *ptr;
+        unsigned int new_count;
+        if (acl->dependencies)
+        {
+            new_count = acl->allocated_dependencies * 2;
+            ptr = RtlReAllocateHeap(GetProcessHeap(), 0, acl->dependencies,
+                                    new_count * sizeof(acl->dependencies[0]));
+        }
+        else
+        {
+            new_count = 4;
+            ptr = RtlAllocateHeap(GetProcessHeap(), 0, new_count * sizeof(acl->dependencies[0]));
+        }
+        if (!ptr) return FALSE;
+        acl->dependencies = ptr;
+        acl->allocated_dependencies = new_count;
+    }
+    acl->dependencies[acl->num_dependencies++] = *ai;
+
+    return TRUE;
+}
+
+static void free_depend_manifests(struct actctx_loader* acl)
+{
+    unsigned int i;
+    for (i = 0; i < acl->num_dependencies; i++)
+        free_assembly_identity(&acl->dependencies[i]);
+    RtlFreeHeap(GetProcessHeap(), 0, acl->dependencies);
+}
+
 static ACTIVATION_CONTEXT *check_actctx( HANDLE h )
 {
     ACTIVATION_CONTEXT *actctx = h;
@@ -802,6 +838,85 @@ static NTSTATUS get_manifest_in_associated_manifest( struct actctx_loader* acl,
     return status;
 }
 
+static NTSTATUS lookup_assembly(struct actctx_loader* acl,
+                                struct assembly_identity* ai)
+{
+    static const WCHAR dotDllW[] = {'.','d','l','l',0};
+    unsigned int i;
+    WCHAR *buffer, *p;
+    NTSTATUS status;
+    UNICODE_STRING nameW;
+    HANDLE file;
+
+    /* FIXME: add support for language specific lookup */
+
+    nameW.Buffer = NULL;
+    if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0,
+                                    (strlenW(acl->actctx->appdir.info) + 2 * strlenW(ai->name) + 2) * sizeof(WCHAR) + sizeof(dotManifestW) )))
+        return STATUS_NO_MEMORY;
+
+    /* lookup in appdir\name.dll
+     *           appdir\name.manifest
+     *           appdir\name\name.dll
+     *           appdir\name\name.manifest
+     */
+    strcpyW( buffer, acl->actctx->appdir.info );
+    p = buffer + strlenW(buffer);
+    for (i = 0; i < 2; i++)
+    {
+        *p++ = '\\';
+        strcpyW( p, ai->name );
+        p += strlenW(p);
+
+        strcpyW( p, dotDllW );
+        if (RtlDosPathNameToNtPathName_U( buffer, &nameW, NULL, NULL ))
+        {
+            status = open_nt_file( &file, &nameW );
+            if (!status)
+            {
+                status = get_manifest_in_pe_file( acl, ai, nameW.Buffer, file,
+                                                  (LPCWSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID, 0 );
+                NtClose( file );
+                break;
+            }
+            RtlFreeUnicodeString( &nameW );
+        }
+
+        strcpyW( p, dotManifestW );
+        if (RtlDosPathNameToNtPathName_U( buffer, &nameW, NULL, NULL ))
+        {
+            status = open_nt_file( &file, &nameW );
+            if (!status)
+            {
+                status = get_manifest_in_manifest_file( acl, ai, nameW.Buffer, file );
+                NtClose( file );
+                break;
+            }
+            RtlFreeUnicodeString( &nameW );
+        }
+    }
+    RtlFreeUnicodeString( &nameW );
+    return STATUS_SXS_ASSEMBLY_NOT_FOUND;
+}
+
+static NTSTATUS parse_depend_manifests(struct actctx_loader* acl)
+{
+    NTSTATUS status = STATUS_SUCCESS;
+    unsigned int i;
+
+    for (i = 0; i < acl->num_dependencies; i++)
+    {
+        if (lookup_assembly(acl, &acl->dependencies[i]) != STATUS_SUCCESS)
+        {
+            FIXME( "Could not find assembly %s\n", debugstr_w(acl->dependencies[i].name) );
+            status = STATUS_SXS_CANT_GEN_ACTCTX;
+            break;
+        }
+    }
+    /* FIXME should now iterate through all refs */
+    return status;
+}
+
 
 /***********************************************************************
  * RtlCreateActivationContext (NTDLL.@)
@@ -913,6 +1028,10 @@ NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, const void *ptr )
 
     if (file) NtClose( file );
     RtlFreeUnicodeString( &nameW );
+
+    if (status == STATUS_SUCCESS) status = parse_depend_manifests(&acl);
+    free_depend_manifests( &acl );
+
     if (status == STATUS_SUCCESS) *handle = actctx;
     else actctx_release( actctx );
     return status;




More information about the wine-cvs mailing list