From 7a612654dc12d82429405ecf71c525fb4460b597 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 31 Dec 2014 20:55:55 +0300 Subject: [PATCH] ntdll: Skip context dependencies that have allowDelayedBinding attribute set. --- dlls/kernel32/tests/actctx.c | 35 +++++++++++++++++++++++++++++++++++ dlls/ntdll/actctx.c | 21 +++++++++++++++++---- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index e30d985697..60763b1b49 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -222,6 +222,17 @@ static const char manifest4[] = "" ""; +static const char manifest5[] = +"" +"" +"" +"" +" " +" " +" " +"" +""; + static const char testdep_manifest1[] = "" "" @@ -1728,6 +1739,29 @@ static void test_typelib_section(void) pReleaseActCtx(handle); } +static void test_allowDelayedBinding(void) +{ + HANDLE handle; + + if (!create_manifest_file("test5.manifest", manifest5, -1, NULL, NULL)) { + skip("Could not create manifest file\n"); + return; + } + + handle = test_create("test5.manifest"); + if (handle == INVALID_HANDLE_VALUE) { + win_skip("allowDelayedBinding attribute is not supported.\n"); + return; + } + + DeleteFileA("test5.manifest"); + DeleteFileA("testdep.manifest"); + if (handle != INVALID_HANDLE_VALUE) { + test_basic_info(handle, __LINE__); + pReleaseActCtx(handle); + } +} + static void test_actctx(void) { ULONG_PTR cookie; @@ -1993,6 +2027,7 @@ static void test_actctx(void) test_wndclass_section(); test_dllredirect_section(); test_typelib_section(); + test_allowDelayedBinding(); } static void test_app_manifest(void) diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index ba6378e4be..20a98ec76b 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -129,6 +129,7 @@ struct assembly_identity WCHAR *type; struct assembly_version version; BOOL optional; + BOOL delayed; }; struct strsection_header @@ -2027,13 +2028,25 @@ static BOOL parse_clr_surrogate_elem(xmlbuf_t* xmlbuf, struct assembly* assembly static BOOL parse_dependent_assembly_elem(xmlbuf_t* xmlbuf, struct actctx_loader* acl, BOOL optional) { struct assembly_identity ai; - xmlstr_t elem; - BOOL end = FALSE, ret = TRUE; + xmlstr_t elem, attr_name, attr_value; + BOOL end = FALSE, error = FALSE, ret = TRUE, delayed = FALSE; - if (!parse_expect_no_attr(xmlbuf, &end) || end) return end; + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + static const WCHAR allowDelayedBindingW[] = {'a','l','l','o','w','D','e','l','a','y','e','d','B','i','n','d','i','n','g',0}; + static const WCHAR trueW[] = {'t','r','u','e',0}; + + if (xmlstr_cmp(&attr_name, allowDelayedBindingW)) + delayed = xmlstr_cmp(&attr_value, trueW); + else + WARN("unknown attr %s=%s\n", debugstr_xmlstr(&attr_name), debugstr_xmlstr(&attr_value)); + } + + if (error || end) return end; memset(&ai, 0, sizeof(ai)); ai.optional = optional; + ai.delayed = delayed; if (!parse_expect_elem(xmlbuf, assemblyIdentityW, asmv1W) || !parse_assembly_identity_elem(xmlbuf, acl->actctx, &ai)) @@ -2914,7 +2927,7 @@ static NTSTATUS parse_depend_manifests(struct actctx_loader* acl) { if (lookup_assembly(acl, &acl->dependencies[i]) != STATUS_SUCCESS) { - if (!acl->dependencies[i].optional) + if (!acl->dependencies[i].optional && !acl->dependencies[i].delayed) { FIXME( "Could not find dependent assembly %s (%s)\n", debugstr_w(acl->dependencies[i].name),