ntdll: Shared manifests should have a less-strict version check performed when loading them as dependencies.

This commit is contained in:
Rob Shearman 2007-11-20 13:46:43 +00:00 committed by Alexandre Julliard
parent f2efcf5f59
commit 542e10e44e
1 changed files with 35 additions and 21 deletions

View File

@ -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);