+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;
+}
+
+