ntdll: Parse manifest compatibility section.
Signed-off-by: Mark Jansen <mark.jansen@reactos.org> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
74862f2e96
commit
0f1cb96b69
|
@ -2555,10 +2555,8 @@ static void test_no_compat(HANDLE handle, int line)
|
|||
CompatibilityInformationInActivationContext, &compat_info,
|
||||
sizeof(compat_info), &size);
|
||||
|
||||
todo_wine {
|
||||
ok_(__FILE__, line)(b, "CompatibilityInformationInActivationContext failed\n");
|
||||
ok_(__FILE__, line)(size == sizeof(DWORD), "size mismatch (got %lu, expected 4)\n", size);
|
||||
}
|
||||
ok_(__FILE__, line)(compat_info.ElementCount == 0, "unexpected ElementCount %u\n", compat_info.ElementCount);
|
||||
}
|
||||
|
||||
|
@ -2575,7 +2573,6 @@ static void test_with_compat(HANDLE handle, DWORD num_compat, const GUID* expect
|
|||
CompatibilityInformationInActivationContext, &compat_info,
|
||||
sizeof(compat_info), &size);
|
||||
|
||||
todo_wine {
|
||||
ok_(__FILE__, line)(b, "CompatibilityInformationInActivationContext failed\n");
|
||||
ok_(__FILE__, line)(size == expected, "size mismatch (got %lu, expected %lu)\n", size, expected);
|
||||
ok_(__FILE__, line)(compat_info.ElementCount == num_compat, "unexpected ElementCount %u\n", compat_info.ElementCount);
|
||||
|
@ -2591,7 +2588,6 @@ todo_wine {
|
|||
"Wrong type, got %u for %u\n", (DWORD)compat_info.Elements[n].Type, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_compatibility(void)
|
||||
{
|
||||
|
|
|
@ -499,6 +499,8 @@ struct assembly
|
|||
unsigned int num_dlls;
|
||||
unsigned int allocated_dlls;
|
||||
struct entity_array entities;
|
||||
COMPATIBILITY_CONTEXT_ELEMENT* compat_contexts;
|
||||
ULONG num_compat_contexts;
|
||||
};
|
||||
|
||||
enum context_sections
|
||||
|
@ -622,6 +624,12 @@ static const WCHAR staticW[] = {'s','t','a','t','i','c',0};
|
|||
static const WCHAR supportsmultilevelundoW[] = {'s','u','p','p','o','r','t','s','m','u','l','t','i','l','e','v','e','l','u','n','d','o',0};
|
||||
static const WCHAR wantstomenumergeW[] = {'w','a','n','t','s','t','o','m','e','n','u','m','e','r','g','e',0};
|
||||
|
||||
static const WCHAR compatibilityW[] = {'c','o','m','p','a','t','i','b','i','l','i','t','y',0};
|
||||
static const WCHAR compatibilityNSW[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','c','o','m','p','a','t','i','b','i','l','i','t','y','.','v','1',0};
|
||||
static const WCHAR applicationW[] = {'a','p','p','l','i','c','a','t','i','o','n',0};
|
||||
static const WCHAR supportedOSW[] = {'s','u','p','p','o','r','t','e','d','O','S',0};
|
||||
static const WCHAR IdW[] = {'I','d',0};
|
||||
|
||||
struct olemisc_entry
|
||||
{
|
||||
const WCHAR *name;
|
||||
|
@ -792,6 +800,25 @@ static struct dll_redirect* add_dll_redirect(struct assembly* assembly)
|
|||
return &assembly->dlls[assembly->num_dlls++];
|
||||
}
|
||||
|
||||
static PCOMPATIBILITY_CONTEXT_ELEMENT add_compat_context(struct assembly* assembly)
|
||||
{
|
||||
void *ptr;
|
||||
if (assembly->num_compat_contexts)
|
||||
{
|
||||
unsigned int new_count = assembly->num_compat_contexts + 1;
|
||||
ptr = RtlReAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
assembly->compat_contexts,
|
||||
new_count * sizeof(COMPATIBILITY_CONTEXT_ELEMENT) );
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(COMPATIBILITY_CONTEXT_ELEMENT) );
|
||||
}
|
||||
if (!ptr) return NULL;
|
||||
assembly->compat_contexts = ptr;
|
||||
return &assembly->compat_contexts[assembly->num_compat_contexts++];
|
||||
}
|
||||
|
||||
static void free_assembly_identity(struct assembly_identity *ai)
|
||||
{
|
||||
RtlFreeHeap( GetProcessHeap(), 0, ai->name );
|
||||
|
@ -1075,6 +1102,7 @@ static void actctx_release( ACTIVATION_CONTEXT *actctx )
|
|||
RtlFreeHeap( GetProcessHeap(), 0, assembly->dlls );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, assembly->manifest.info );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, assembly->directory );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, assembly->compat_contexts );
|
||||
free_entity_array( &assembly->entities );
|
||||
free_assembly_identity(&assembly->id);
|
||||
}
|
||||
|
@ -2211,6 +2239,84 @@ static BOOL parse_file_elem(xmlbuf_t* xmlbuf, struct assembly* assembly, struct
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL parse_compatibility_application_elem(xmlbuf_t* xmlbuf, struct assembly* assembly,
|
||||
struct actctx_loader* acl)
|
||||
{
|
||||
xmlstr_t attr_name, attr_value, elem;
|
||||
BOOL end = FALSE, ret = TRUE, error;
|
||||
|
||||
while (ret && (ret = next_xml_elem(xmlbuf, &elem)))
|
||||
{
|
||||
if (xmlstr_cmp_end(&elem, applicationW))
|
||||
{
|
||||
ret = parse_end_element(xmlbuf);
|
||||
break;
|
||||
}
|
||||
else if (xmlstr_cmp(&elem, supportedOSW))
|
||||
{
|
||||
while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end))
|
||||
{
|
||||
if (xmlstr_cmp(&attr_name, IdW))
|
||||
{
|
||||
UNICODE_STRING str;
|
||||
COMPATIBILITY_CONTEXT_ELEMENT* compat;
|
||||
GUID compat_id;
|
||||
str.Buffer = (PWSTR)attr_value.ptr;
|
||||
str.Length = str.MaximumLength = (USHORT)attr_value.len * sizeof(WCHAR);
|
||||
if (RtlGUIDFromString(&str, &compat_id) == STATUS_SUCCESS)
|
||||
{
|
||||
if (!(compat = add_compat_context(assembly))) return FALSE;
|
||||
compat->Type = ACTCX_COMPATIBILITY_ELEMENT_TYPE_OS;
|
||||
compat->Id = compat_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("Invalid guid %s\n", debugstr_xmlstr(&attr_value));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("unknown attr %s=%s\n", debugstr_xmlstr(&attr_name),
|
||||
debugstr_xmlstr(&attr_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("unknown elem %s\n", debugstr_xmlstr(&elem));
|
||||
ret = parse_unknown_elem(xmlbuf, &elem);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL parse_compatibility_elem(xmlbuf_t* xmlbuf, struct assembly* assembly,
|
||||
struct actctx_loader* acl)
|
||||
{
|
||||
xmlstr_t elem;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
while (ret && (ret = next_xml_elem(xmlbuf, &elem)))
|
||||
{
|
||||
if (xmlstr_cmp_end(&elem, compatibilityW))
|
||||
{
|
||||
ret = parse_end_element(xmlbuf);
|
||||
break;
|
||||
}
|
||||
else if (xmlstr_cmp(&elem, applicationW))
|
||||
{
|
||||
ret = parse_compatibility_application_elem(xmlbuf, assembly, acl);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("unknown elem %s\n", debugstr_xmlstr(&elem));
|
||||
ret = parse_unknown_elem(xmlbuf, &elem);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL parse_assembly_elem(xmlbuf_t* xmlbuf, struct actctx_loader* acl,
|
||||
struct assembly* assembly,
|
||||
struct assembly_identity* expected_ai)
|
||||
|
@ -2328,6 +2434,10 @@ static BOOL parse_assembly_elem(xmlbuf_t* xmlbuf, struct actctx_loader* acl,
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (xml_elem_cmp(&elem, compatibilityW, compatibilityNSW))
|
||||
{
|
||||
ret = parse_compatibility_elem(xmlbuf, assembly, acl);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("unknown element %s\n", debugstr_xmlstr(&elem));
|
||||
|
@ -4987,6 +5097,34 @@ NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, HANDLE handle
|
|||
}
|
||||
break;
|
||||
|
||||
case CompatibilityInformationInActivationContext:
|
||||
{
|
||||
/*ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION*/DWORD *acci = buffer;
|
||||
COMPATIBILITY_CONTEXT_ELEMENT *elements;
|
||||
struct assembly *assembly = NULL;
|
||||
ULONG num_compat_contexts = 0, n;
|
||||
SIZE_T len;
|
||||
|
||||
if (!(actctx = check_actctx(handle))) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (actctx->num_assemblies) assembly = actctx->assemblies;
|
||||
|
||||
if (assembly)
|
||||
num_compat_contexts = assembly->num_compat_contexts;
|
||||
len = sizeof(*acci) + num_compat_contexts * sizeof(COMPATIBILITY_CONTEXT_ELEMENT);
|
||||
|
||||
if (retlen) *retlen = len;
|
||||
if (!buffer || bufsize < len) return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
*acci = num_compat_contexts;
|
||||
elements = (COMPATIBILITY_CONTEXT_ELEMENT*)(acci + 1);
|
||||
for (n = 0; n < num_compat_contexts; ++n)
|
||||
{
|
||||
elements[n] = assembly->compat_contexts[n];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME( "class %u not implemented\n", class );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
|
Loading…
Reference in New Issue