ntdll: Shared manifests should have a less-strict version check performed when loading them as dependencies.
This commit is contained in:
parent
f2efcf5f59
commit
542e10e44e
|
@ -144,7 +144,8 @@ struct dll_redirect
|
|||
enum assembly_type
|
||||
{
|
||||
APPLICATION_MANIFEST,
|
||||
ASSEMBLY_MANIFEST
|
||||
ASSEMBLY_MANIFEST,
|
||||
ASSEMBLY_SHARED_MANIFEST,
|
||||
};
|
||||
|
||||
struct assembly
|
||||
|
@ -1379,7 +1380,8 @@ static BOOL parse_assembly_elem(xmlbuf_t* xmlbuf, struct actctx_loader* acl,
|
|||
if (!parse_noinheritable_elem(xmlbuf) || !next_xml_elem(xmlbuf, &elem))
|
||||
return FALSE;
|
||||
}
|
||||
else if (assembly->type == ASSEMBLY_MANIFEST && assembly->no_inherit)
|
||||
else if ((assembly->type == ASSEMBLY_MANIFEST || assembly->type == ASSEMBLY_SHARED_MANIFEST) &&
|
||||
assembly->no_inherit)
|
||||
return FALSE;
|
||||
|
||||
if (xmlstr_cmp(&elem, assemblyIdentityW))
|
||||
|
@ -1393,7 +1395,17 @@ static BOOL parse_assembly_elem(xmlbuf_t* xmlbuf, struct actctx_loader* acl,
|
|||
if (assembly->type == ASSEMBLY_MANIFEST &&
|
||||
memcmp(&assembly->id.version, &expected_ai->version, sizeof(assembly->id.version)))
|
||||
{
|
||||
FIXME("wrong version\n");
|
||||
FIXME("wrong version for assembly manifest\n");
|
||||
return FALSE;
|
||||
}
|
||||
else if (assembly->type == ASSEMBLY_SHARED_MANIFEST &&
|
||||
(assembly->id.version.major != expected_ai->version.major ||
|
||||
assembly->id.version.minor != expected_ai->version.minor ||
|
||||
assembly->id.version.build < expected_ai->version.build ||
|
||||
(assembly->id.version.build == expected_ai->version.build &&
|
||||
assembly->id.version.revision < expected_ai->version.revision)))
|
||||
{
|
||||
FIXME("wrong version for shared assembly manifest\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1479,7 +1491,8 @@ static NTSTATUS parse_manifest_buffer( struct actctx_loader* acl, struct assembl
|
|||
}
|
||||
|
||||
static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_identity* ai,
|
||||
LPCWSTR filename, LPCWSTR directory, const void *buffer, SIZE_T size )
|
||||
LPCWSTR filename, LPCWSTR directory, BOOL shared,
|
||||
const void *buffer, SIZE_T size )
|
||||
{
|
||||
xmlbuf_t xmlbuf;
|
||||
NTSTATUS status;
|
||||
|
@ -1488,7 +1501,7 @@ static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_ident
|
|||
|
||||
TRACE( "parsing manifest loaded from %s base dir %s\n", debugstr_w(filename), debugstr_w(directory) );
|
||||
|
||||
if (!(assembly = add_assembly(acl->actctx, ASSEMBLY_MANIFEST)))
|
||||
if (!(assembly = add_assembly(acl->actctx, shared ? ASSEMBLY_SHARED_MANIFEST : ASSEMBLY_MANIFEST)))
|
||||
return STATUS_SXS_CANT_GEN_ACTCTX;
|
||||
|
||||
if (directory && !(assembly->directory = strdupW(directory)))
|
||||
|
@ -1580,8 +1593,8 @@ static NTSTATUS get_module_filename( HMODULE module, UNICODE_STRING *str, unsign
|
|||
}
|
||||
|
||||
static NTSTATUS get_manifest_in_module( struct actctx_loader* acl, struct assembly_identity* ai,
|
||||
LPCWSTR filename, LPCWSTR directory, HANDLE hModule,
|
||||
LPCWSTR resname, ULONG lang )
|
||||
LPCWSTR filename, LPCWSTR directory, BOOL shared,
|
||||
HANDLE hModule, LPCWSTR resname, ULONG lang )
|
||||
{
|
||||
NTSTATUS status;
|
||||
UNICODE_STRING nameW;
|
||||
|
@ -1630,14 +1643,14 @@ static NTSTATUS get_manifest_in_module( struct actctx_loader* acl, struct assemb
|
|||
if (status == STATUS_SUCCESS) status = LdrAccessResource(hModule, entry, &ptr, NULL);
|
||||
|
||||
if (status == STATUS_SUCCESS)
|
||||
status = parse_manifest(acl, ai, filename, directory, ptr, entry->Size);
|
||||
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, HANDLE file,
|
||||
LPCWSTR resname, ULONG lang )
|
||||
LPCWSTR filename, LPCWSTR directory, BOOL shared,
|
||||
HANDLE file, LPCWSTR resname, ULONG lang )
|
||||
{
|
||||
HANDLE mapping;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
|
@ -1672,7 +1685,7 @@ 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, module, resname, lang );
|
||||
status = get_manifest_in_module( acl, ai, filename, directory, shared, module, resname, lang );
|
||||
}
|
||||
else status = STATUS_INVALID_IMAGE_FORMAT;
|
||||
|
||||
|
@ -1681,7 +1694,7 @@ static NTSTATUS get_manifest_in_pe_file( struct actctx_loader* acl, struct assem
|
|||
}
|
||||
|
||||
static NTSTATUS get_manifest_in_manifest_file( struct actctx_loader* acl, struct assembly_identity* ai,
|
||||
LPCWSTR filename, LPCWSTR directory, HANDLE file )
|
||||
LPCWSTR filename, LPCWSTR directory, BOOL shared, HANDLE file )
|
||||
{
|
||||
FILE_END_OF_FILE_INFORMATION info;
|
||||
IO_STATUS_BLOCK io;
|
||||
|
@ -1717,7 +1730,7 @@ static NTSTATUS get_manifest_in_manifest_file( struct actctx_loader* acl, struct
|
|||
|
||||
status = NtQueryInformationFile( file, &io, &info, sizeof(info), FileEndOfFileInformation );
|
||||
if (status == STATUS_SUCCESS)
|
||||
status = parse_manifest(acl, ai, filename, directory, base, info.EndOfFile.QuadPart);
|
||||
status = parse_manifest(acl, ai, filename, directory, shared, base, info.EndOfFile.QuadPart);
|
||||
|
||||
NtUnmapViewOfSection( GetCurrentProcess(), base );
|
||||
return status;
|
||||
|
@ -1765,7 +1778,7 @@ static NTSTATUS get_manifest_in_associated_manifest( struct actctx_loader* acl,
|
|||
|
||||
if (!open_nt_file( &file, &nameW ))
|
||||
{
|
||||
status = get_manifest_in_manifest_file( acl, ai, nameW.Buffer, directory, file );
|
||||
status = get_manifest_in_manifest_file( acl, ai, nameW.Buffer, directory, FALSE, file );
|
||||
NtClose( file );
|
||||
}
|
||||
else status = STATUS_RESOURCE_DATA_NOT_FOUND;
|
||||
|
@ -1905,7 +1918,7 @@ static NTSTATUS lookup_winsxs(struct actctx_loader* acl, struct assembly_identit
|
|||
|
||||
if (!open_nt_file( &handle, &path_us ))
|
||||
{
|
||||
io.u.Status = get_manifest_in_manifest_file(acl, &sxs_ai, path_us.Buffer, file, handle);
|
||||
io.u.Status = get_manifest_in_manifest_file(acl, &sxs_ai, path_us.Buffer, file, TRUE, handle);
|
||||
NtClose( handle );
|
||||
}
|
||||
else io.u.Status = STATUS_NO_SUCH_FILE;
|
||||
|
@ -1962,7 +1975,7 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl,
|
|||
status = open_nt_file( &file, &nameW );
|
||||
if (!status)
|
||||
{
|
||||
status = get_manifest_in_pe_file( acl, ai, nameW.Buffer, directory, file,
|
||||
status = get_manifest_in_pe_file( acl, ai, nameW.Buffer, directory, FALSE, file,
|
||||
(LPCWSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID, 0 );
|
||||
NtClose( file );
|
||||
break;
|
||||
|
@ -1976,7 +1989,7 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl,
|
|||
status = open_nt_file( &file, &nameW );
|
||||
if (!status)
|
||||
{
|
||||
status = get_manifest_in_manifest_file( acl, ai, nameW.Buffer, directory, file );
|
||||
status = get_manifest_in_manifest_file( acl, ai, nameW.Buffer, directory, FALSE, file );
|
||||
NtClose( file );
|
||||
break;
|
||||
}
|
||||
|
@ -2230,7 +2243,7 @@ NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, const void *ptr )
|
|||
/* if we have a resource it's a PE file */
|
||||
if (pActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID)
|
||||
{
|
||||
status = get_manifest_in_module( &acl, NULL, NULL, directory, pActCtx->hModule,
|
||||
status = get_manifest_in_module( &acl, NULL, NULL, directory, FALSE, pActCtx->hModule,
|
||||
pActCtx->lpResourceName, lang );
|
||||
if (status && status != STATUS_SXS_CANT_GEN_ACTCTX)
|
||||
/* FIXME: what to do if pActCtx->lpSource is set */
|
||||
|
@ -2239,7 +2252,7 @@ NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, const void *ptr )
|
|||
}
|
||||
else if (pActCtx->lpSource)
|
||||
{
|
||||
status = get_manifest_in_pe_file( &acl, NULL, nameW.Buffer, directory,
|
||||
status = get_manifest_in_pe_file( &acl, NULL, nameW.Buffer, directory, FALSE,
|
||||
file, pActCtx->lpResourceName, lang );
|
||||
if (status && status != STATUS_SXS_CANT_GEN_ACTCTX)
|
||||
status = get_manifest_in_associated_manifest( &acl, NULL, nameW.Buffer, directory,
|
||||
|
@ -2249,7 +2262,7 @@ NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, const void *ptr )
|
|||
}
|
||||
else
|
||||
{
|
||||
status = get_manifest_in_manifest_file( &acl, NULL, nameW.Buffer, directory, file );
|
||||
status = get_manifest_in_manifest_file( &acl, NULL, nameW.Buffer, directory, FALSE, file );
|
||||
}
|
||||
|
||||
if (file) NtClose( file );
|
||||
|
@ -2502,7 +2515,8 @@ NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, HANDLE handle
|
|||
id_len = strlenW(assembly_id) + 1;
|
||||
if (assembly->directory) ad_len = strlenW(assembly->directory) + 1;
|
||||
|
||||
if (assembly->manifest.info && assembly->type == ASSEMBLY_MANIFEST)
|
||||
if (assembly->manifest.info &&
|
||||
(assembly->type == ASSEMBLY_MANIFEST || assembly->type == ASSEMBLY_SHARED_MANIFEST))
|
||||
path_len = strlenW(assembly->manifest.info) + 1;
|
||||
|
||||
len = sizeof(*afdi) + (id_len + ad_len + path_len) * sizeof(WCHAR);
|
||||
|
|
Loading…
Reference in New Issue