[PATCH 11/27] [Kernel32]: ActCtx: added support for the assembly
leaves
Eric Pouech
eric.pouech at wanadoo.fr
Mon May 7 14:50:51 CDT 2007
---
dlls/kernel32/actctx.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 240 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/actctx.c b/dlls/kernel32/actctx.c
index 8100962..f90ca0b 100644
--- a/dlls/kernel32/actctx.c
+++ b/dlls/kernel32/actctx.c
@@ -98,9 +98,37 @@ struct assembly_identity
enum assembly_id_arch arch;
};
+struct entity
+{
+ DWORD kind;
+ union
+ {
+ struct
+ {
+ LPCWSTR tlbid;
+ LPCWSTR version;
+ LPCWSTR helpdir;
+ } typelib;
+ struct
+ {
+ LPCWSTR clsid;
+ } comclass;
+ struct {
+ LPCWSTR iid;
+ LPCWSTR name;
+ } proxy;
+ struct
+ {
+ LPCWSTR name;
+ } class;
+ } u;
+};
+
struct dll_redirect
{
LPCWSTR name;
+ unsigned num_entities;
+ struct entity* entities;
};
enum assembly_type
@@ -209,6 +237,8 @@ static struct dll_redirect* add_dll_redirect(struct assembly* assembly)
if (!assembly->dlls) return NULL;
dll = &assembly->dlls[assembly->num_dlls++];
dll->name = NULL;
+ dll->num_entities = 0;
+ dll->entities = NULL;
return dll;
}
@@ -234,6 +264,23 @@ static void free_assembly_identity(struct assembly_identity *ai)
HeapFree(GetProcessHeap(), 0, (void*)ai->name);
}
+static struct entity* add_entity(struct dll_redirect* dll, DWORD kind)
+{
+ struct entity* entity;
+
+ if (dll->num_entities)
+ dll->entities = HeapReAlloc(GetProcessHeap(), 0, dll->entities,
+ (dll->num_entities + 1) * sizeof(dll->entities[0]));
+ else
+ dll->entities = HeapAlloc(GetProcessHeap(), 0, sizeof(dll->entities[0]));
+ if (!dll->entities) return NULL;
+ entity = &dll->entities[dll->num_entities++];
+ memset(entity, 0, sizeof(*entity));
+ entity->kind = kind;
+
+ return entity;
+}
+
/***********************************************************************
* CreateActCtxA (KERNEL32.@)
*
@@ -314,15 +361,23 @@ done:
#define ASSEMBLY_ELEM "assembly"
#define ASSEMBLYIDENTITY_ELEM "assemblyIdentity"
+#define COMCLASS_ELEM "comClass"
+#define COMINTERFACEPROXYSTUB_ELEM "comInterfaceProxyStub"
#define DEPENDENCY_ELEM "dependency"
#define DEPENDENTASSEMBLY_ELEM "dependentAssembly"
#define FILE_ELEM "file"
+#define TYPELIB_ELEM "typelib"
+#define WINDOWCLASS_ELEM "windowClass"
#define ELEM_END(elem) "/" elem
+#define CLSID_ATTR "clsid"
+#define HELPDIR_ATTR "helpdir"
+#define IID_ATTR "iid"
#define MANIFESTVERSION_ATTR "manifestVersion"
#define NAME_ATTR "name"
#define PROCESSORARCHITECTURE_ATTR "processorArchitecture"
+#define TLBID_ATTR "tlbid"
#define TYPE_ATTR "type"
#define VERSION_ATTR "version"
#define XMLNS_ATTR "xmlns"
@@ -416,6 +471,19 @@ static BOOL next_xml_elem(xmlbuf_t* xmlbuf, xmlstr_t* elem)
return xmlbuf->ptr != xmlbuf->end;
}
+static BOOL parse_text_content(xmlbuf_t* xmlbuf, xmlstr_t* content)
+{
+ const char *ptr = memchr(xmlbuf->ptr, '<', xmlbuf->end - xmlbuf->ptr);
+
+ if (!ptr) return FALSE;
+
+ content->ptr = xmlbuf->ptr;
+ content->len = ptr - xmlbuf->ptr;
+ xmlbuf->ptr = ptr;
+
+ return TRUE;
+}
+
/* major.minor.build.revision */
static BOOL parse_version(xmlstr_t* str, struct version* version)
{
@@ -524,6 +592,128 @@ static BOOL parse_assembly_identity_elem(xmlbuf_t* xmlbuf, struct actctx* actctx
return parse_expect_elem(xmlbuf, ELEM_END(ASSEMBLYIDENTITY_ELEM)) && parse_end_element(xmlbuf);
}
+static BOOL parse_com_class_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll)
+{
+ xmlstr_t attr_name, attr_value;
+ BOOL end = FALSE, error;
+ struct entity* entity;
+
+ entity = add_entity(dll, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION);
+
+ while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end))
+ {
+ if (xmlstr_cmp(&attr_name, CLSID_ATTR))
+ {
+ entity->u.comclass.clsid = xstrdupXW(&attr_value);
+ }
+ else
+ {
+ WARN("wrong attr %s=%s\n", debugstr_xmlstr(&attr_name),
+ debugstr_xmlstr(&attr_value));
+ return FALSE;
+ }
+ }
+
+ if (error || end) return end;
+ return parse_expect_elem(xmlbuf, ELEM_END(COMCLASS_ELEM)) && parse_end_element(xmlbuf);
+}
+
+static BOOL parse_cominterface_proxy_stub_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll)
+{
+ xmlstr_t attr_name, attr_value;
+ BOOL end = FALSE, error;
+ struct entity* entity;
+
+ entity = add_entity(dll, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION);
+
+ while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end))
+ {
+ if (xmlstr_cmp(&attr_name, IID_ATTR))
+ {
+ entity->u.proxy.iid = xstrdupXW(&attr_value);
+ }
+ if (xmlstr_cmp(&attr_name, NAME_ATTR))
+ {
+ entity->u.proxy.name = xstrdupXW(&attr_value);
+ }
+ else
+ {
+ WARN("wrong attr %s=%s\n", debugstr_xmlstr(&attr_name),
+ debugstr_xmlstr(&attr_value));
+ return FALSE;
+ }
+ }
+
+ if (error || end) return end;
+ return parse_expect_elem(xmlbuf, ELEM_END(COMINTERFACEPROXYSTUB_ELEM)) && parse_end_element(xmlbuf);
+}
+
+static BOOL parse_typelib_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll)
+{
+ xmlstr_t attr_name, attr_value;
+ BOOL end = FALSE, error;
+ struct entity* entity;
+
+ entity = add_entity(dll, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION);
+
+ while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end))
+ {
+ if (xmlstr_cmp(&attr_name, TLBID_ATTR))
+ {
+ entity->u.typelib.tlbid = xstrdupXW(&attr_value);
+ }
+ if (xmlstr_cmp(&attr_name, VERSION_ATTR))
+ {
+ entity->u.typelib.version = xstrdupXW(&attr_value);
+ }
+ if (xmlstr_cmp(&attr_name, HELPDIR_ATTR))
+ {
+ entity->u.typelib.helpdir = xstrdupXW(&attr_value);
+ }
+ else
+ {
+ WARN("wrong attr %s=%s\n", debugstr_xmlstr(&attr_name),
+ debugstr_xmlstr(&attr_value));
+ return FALSE;
+ }
+ }
+
+ if (error || end) return end;
+ return parse_expect_elem(xmlbuf, ELEM_END(TYPELIB_ELEM)) && parse_end_element(xmlbuf);
+}
+
+static BOOL parse_window_class_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll)
+{
+ xmlstr_t elem, content;
+ BOOL end = FALSE, ret = TRUE;
+ struct entity* entity;
+
+ entity = add_entity(dll, ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION);
+
+ if (!parse_expect_no_attr(xmlbuf, &end)) return FALSE;
+ if (end) return FALSE;
+
+ if (!parse_text_content(xmlbuf, &content)) return FALSE;
+
+ entity->u.class.name = xstrdupXW(&content);
+
+ while (ret && (ret = next_xml_elem(xmlbuf, &elem)))
+ {
+ if (xmlstr_cmp(&elem, ELEM_END(WINDOWCLASS_ELEM)))
+ {
+ ret = parse_end_element(xmlbuf);
+ break;
+ }
+ else
+ {
+ WARN("wrong elem %s\n", debugstr_xmlstr(&elem));
+ ret = FALSE;
+ }
+ }
+
+ return ret;
+}
+
static BOOL parse_file_elem(xmlbuf_t* xmlbuf, struct assembly* assembly)
{
xmlstr_t attr_name, attr_value, elem;
@@ -557,6 +747,22 @@ static BOOL parse_file_elem(xmlbuf_t* xmlbuf, struct assembly* assembly)
ret = parse_end_element(xmlbuf);
break;
}
+ else if (xmlstr_cmp(&elem, COMCLASS_ELEM))
+ {
+ ret = parse_com_class_elem(xmlbuf, dll);
+ }
+ else if (xmlstr_cmp(&elem, COMINTERFACEPROXYSTUB_ELEM))
+ {
+ ret = parse_cominterface_proxy_stub_elem(xmlbuf, dll);;
+ }
+ else if (xmlstr_cmp(&elem, TYPELIB_ELEM))
+ {
+ ret = parse_typelib_elem(xmlbuf, dll);
+ }
+ else if (xmlstr_cmp(&elem, WINDOWCLASS_ELEM))
+ {
+ ret = parse_window_class_elem(xmlbuf, dll);
+ }
else
{
WARN("wrong elem %s\n", debugstr_xmlstr(&elem));
@@ -1119,6 +1325,30 @@ void WINAPI AddRefActCtx(HANDLE hActCtx)
actctx->ref_count++;
}
+static void free_entity(struct entity* entity)
+{
+ switch (entity->kind)
+ {
+ case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION:
+ HeapFree(GetProcessHeap(), 0, (void*)entity->u.comclass.clsid);
+ break;
+ case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION:
+ HeapFree(GetProcessHeap(), 0, (void*)entity->u.proxy.iid);
+ HeapFree(GetProcessHeap(), 0, (void*)entity->u.proxy.name);
+ break;
+ case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION:
+ HeapFree(GetProcessHeap(), 0, (void*)entity->u.typelib.tlbid);
+ HeapFree(GetProcessHeap(), 0, (void*)entity->u.typelib.version);
+ HeapFree(GetProcessHeap(), 0, (void*)entity->u.typelib.helpdir);
+ break;
+ case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION:
+ HeapFree(GetProcessHeap(), 0, (void*)entity->u.class.name);
+ break;
+ default:
+ FIXME("Unknown entity kind %d\n", entity->kind);
+ }
+}
+
/***********************************************************************
* ReleaseActCtx (KERNEL32.@)
*
@@ -1134,16 +1364,24 @@ void WINAPI ReleaseActCtx(HANDLE hActCtx)
{
if (--actctx->ref_count == 0)
{
- unsigned i, j;
+ unsigned i, j, k;
struct assembly* assembly;
+ struct dll_redirect*dll;
for (i = 0; i < actctx->num_assemblies; i++)
{
assembly = &actctx->assemblies[i];
for (j = 0; j < assembly->num_dlls; j++)
{
- HeapFree(GetProcessHeap(), 0, (void*)assembly->dlls[j].name);
+ dll = &assembly->dlls[j];
+ for (k = 0; k < dll->num_entities; k++)
+ {
+ free_entity(&dll->entities[k]);
+ }
+ HeapFree(GetProcessHeap(), 0, dll->entities);
+ HeapFree(GetProcessHeap(), 0, (void*)dll->name);
}
+ HeapFree(GetProcessHeap(), 0, assembly->dlls);
HeapFree(GetProcessHeap(), 0, (void*)assembly->manifest.info);
free_assembly_identity(&assembly->id);
}
More information about the wine-patches
mailing list