https://git.reactos.org/?p=reactos.git;a=commitdiff;h=57ed670b5a0b51806b529…
commit 57ed670b5a0b51806b529ab18848022e55d82e8a
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Mon Sep 24 23:59:57 2018 +0200
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Mon Oct 1 20:16:10 2018 +0200
[RTL] actctx: When probing a dll for a manifest, use the first manifest id present,
instead of always searching for CREATEPROCESS_MANIFEST_RESOURCE_ID.
CORE-9519
---
sdk/lib/rtl/actctx.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 74 insertions(+), 4 deletions(-)
diff --git a/sdk/lib/rtl/actctx.c b/sdk/lib/rtl/actctx.c
index 2f82808dd5..8df2af46fc 100644
--- a/sdk/lib/rtl/actctx.c
+++ b/sdk/lib/rtl/actctx.c
@@ -2947,6 +2947,65 @@ static NTSTATUS get_manifest_in_module( struct actctx_loader* acl,
struct assemb
return status;
}
+IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( IMAGE_RESOURCE_DIRECTORY *dir,
+ LPCWSTR name, void *root,
+ int want_dir );
+
+IMAGE_RESOURCE_DIRECTORY *find_first_entry( IMAGE_RESOURCE_DIRECTORY *dir,
+ void *root, int want_dir );
+
+
+static IMAGE_RESOURCE_DIRECTORY *find_first_id_entry( IMAGE_RESOURCE_DIRECTORY *dir,
+ void *root, int want_dir )
+{
+ const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY
*)(dir + 1);
+ int pos;
+
+ for (pos = dir->NumberOfNamedEntries; pos < dir->NumberOfNamedEntries +
dir->NumberOfIdEntries; pos++)
+ {
+ if (!entry[pos].DataIsDirectory == !want_dir)
+ return (IMAGE_RESOURCE_DIRECTORY *)((char *)root +
entry[pos].OffsetToDirectory);
+ }
+ return NULL;
+}
+
+
+static NTSTATUS search_manifest_in_module( struct actctx_loader* acl, struct
assembly_identity* ai,
+ LPCWSTR filename, LPCWSTR directory, BOOL shared,
+ HANDLE hModule, ULONG lang )
+{
+ ULONG size;
+ PVOID root, ptr;
+ IMAGE_RESOURCE_DIRECTORY *resdirptr;
+ IMAGE_RESOURCE_DATA_ENTRY *entry;
+ NTSTATUS status;
+
+ root = RtlImageDirectoryEntryToData(hModule, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE,
&size);
+ if (!root) return STATUS_RESOURCE_DATA_NOT_FOUND;
+ if (size < sizeof(*resdirptr)) return STATUS_RESOURCE_DATA_NOT_FOUND;
+ resdirptr = root;
+
+ if (!(ptr = find_entry_by_name(resdirptr, (LPCWSTR)RT_MANIFEST, root, 1)))
+ return STATUS_RESOURCE_TYPE_NOT_FOUND;
+
+ resdirptr = ptr;
+ if (!(ptr = find_first_id_entry(resdirptr, root, 1)))
+ return STATUS_RESOURCE_TYPE_NOT_FOUND;
+
+ resdirptr = ptr;
+ if (!(ptr = find_first_entry(resdirptr, root, 0)))
+ return STATUS_RESOURCE_TYPE_NOT_FOUND;
+
+ entry = ptr;
+ status = LdrAccessResource(hModule, entry, &ptr, NULL);
+
+ if (status == STATUS_SUCCESS)
+ status = parse_manifest(acl, ai, filename, directory, shared, ptr,
entry->Size);
+
+ return status;
+}
+
+
static NTSTATUS get_manifest_in_pe_file( struct actctx_loader* acl, struct
assembly_identity* ai,
LPCWSTR filename, LPCWSTR directory, BOOL
shared,
HANDLE file, LPCWSTR resname, ULONG lang )
@@ -2958,8 +3017,16 @@ static NTSTATUS get_manifest_in_pe_file( struct actctx_loader* acl,
struct assem
NTSTATUS status;
SIZE_T count;
void *base;
+ WCHAR resnameBuf[20];
+ LPCWSTR resptr = resname;
- DPRINT( "looking for res %S in %S\n", resname, filename );
+ if ((!((ULONG_PTR)resname >> 16)))
+ {
+ sprintfW(resnameBuf, L"#%u", (ULONG_PTR)resname);
+ resptr = resnameBuf;
+ }
+
+ DPRINT( "looking for res %S in %S\n", resptr, filename ? filename :
L"<NULL>");
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
@@ -2984,7 +3051,10 @@ static NTSTATUS get_manifest_in_pe_file( struct actctx_loader* acl,
struct assem
if (RtlImageNtHeader(base)) /* we got a PE file */
{
HANDLE module = (HMODULE)((ULONG_PTR)base | 1); /* make it a
LOAD_LIBRARY_AS_DATAFILE handle */
- status = get_manifest_in_module( acl, ai, filename, directory, shared, module,
resname, lang );
+ if (resname)
+ status = get_manifest_in_module( acl, ai, filename, directory, shared,
module, resname, lang );
+ else
+ status = search_manifest_in_module(acl, ai, filename, directory, shared,
module, lang);
}
else status = STATUS_INVALID_IMAGE_FORMAT;
@@ -3308,7 +3378,7 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl,
if (!status)
{
status = get_manifest_in_pe_file( acl, ai, nameW.Buffer, directory,
FALSE, file,
-
(LPCWSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID, 0 );
+ (LPCWSTR)0, 0 );
NtClose( file );
break;
}
@@ -5098,7 +5168,7 @@ RtlCreateActivationContext(IN ULONG Flags,
status = get_manifest_in_associated_manifest( &acl, NULL, NULL,
directory,
pActCtx->hModule,
pActCtx->lpResourceName );
}
- else if (pActCtx->lpSource)
+ else if (pActCtx->lpSource && pActCtx->lpResourceName)
{
status = get_manifest_in_pe_file( &acl, NULL, nameW.Buffer, directory,
FALSE,
file, pActCtx->lpResourceName, lang );