[PATCH 09/11] [Kernel32]: ActCtx: added support for the assembly leaves

Eric Pouech eric.pouech at wanadoo.fr
Wed May 9 15:08:26 CDT 2007


---

 dlls/kernel32/actctx.c |  253 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 251 insertions(+), 2 deletions(-)

diff --git a/dlls/kernel32/actctx.c b/dlls/kernel32/actctx.c
index 97cac9f..9c6cfe6 100644
--- a/dlls/kernel32/actctx.c
+++ b/dlls/kernel32/actctx.c
@@ -98,9 +98,38 @@ struct assembly_identity
     enum assembly_id_arch arch;
 };
 
+struct entity
+{
+    DWORD               kind;
+    union
+    {
+        struct
+        {
+            LPWSTR              tlbid;
+            LPWSTR              version;
+            LPWSTR              helpdir;
+	} typelib;
+        struct
+        {
+            LPWSTR              clsid;
+	} comclass;
+	struct {
+            LPWSTR              iid;
+            LPWSTR              name;
+	} proxy;
+        struct
+        {
+            LPWSTR              name;
+        } class;
+    } u;
+};
+
 struct dll_redirect
 {
     LPWSTR              name;
+    struct entity*      entities;
+    unsigned            num_entities;
+    unsigned            allocated_entities;
 };
 
 enum assembly_type
@@ -231,6 +260,9 @@ 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->allocated_entities = 0;
+    dll->entities = NULL;
 
     return dll;
 }
@@ -265,6 +297,32 @@ static void free_assembly_identity(struct assembly_identity *ai)
     HeapFree(GetProcessHeap(), 0, ai->name);
 }
 
+static struct entity* add_entity(struct dll_redirect* dll, DWORD kind)
+{
+    struct entity*      entity;
+
+    if (dll->num_entities == dll->allocated_entities)
+    {
+        if (dll->allocated_entities)
+        {
+            dll->allocated_entities *= 2;
+            dll->entities = HeapReAlloc(GetProcessHeap(), 0, dll->entities,
+                                        dll->allocated_entities * sizeof(dll->entities[0]));
+        }
+        else
+        {
+            dll->allocated_entities = 1;
+            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.@)
  *
@@ -344,15 +402,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"
@@ -446,6 +512,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(const xmlstr_t* str, struct version* version)
 {
@@ -554,6 +633,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 = strdupXW(&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 = strdupXW(&attr_value);
+        }
+        if (xmlstr_cmp(&attr_name, NAME_ATTR))
+        {
+            entity->u.proxy.name = strdupXW(&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 = strdupXW(&attr_value);
+        }
+        if (xmlstr_cmp(&attr_name, VERSION_ATTR))
+        {
+            entity->u.typelib.version = strdupXW(&attr_value);
+        }
+        if (xmlstr_cmp(&attr_name, HELPDIR_ATTR))
+        {
+            entity->u.typelib.helpdir = strdupXW(&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 = strdupXW(&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;
@@ -587,6 +788,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));
@@ -1151,6 +1368,30 @@ void WINAPI AddRefActCtx(HANDLE hActCtx)
         InterlockedIncrement( &actctx->ref_count );
 }
 
+static void free_entity(struct entity* entity)
+{
+    switch (entity->kind)
+    {
+    case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION:
+        HeapFree(GetProcessHeap(), 0, entity->u.comclass.clsid);
+        break;
+    case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION:
+        HeapFree(GetProcessHeap(), 0, entity->u.proxy.iid);
+        HeapFree(GetProcessHeap(), 0, entity->u.proxy.name);
+        break;
+    case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION:
+        HeapFree(GetProcessHeap(), 0, entity->u.typelib.tlbid);
+        HeapFree(GetProcessHeap(), 0, entity->u.typelib.version);
+        HeapFree(GetProcessHeap(), 0, entity->u.typelib.helpdir);
+        break;
+    case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION:
+        HeapFree(GetProcessHeap(), 0, entity->u.class.name);
+        break;
+    default:
+        FIXME("Unknown entity kind %d\n", entity->kind);
+    }
+}
+
 /***********************************************************************
  * ReleaseActCtx (KERNEL32.@)
  *
@@ -1166,16 +1407,24 @@ void WINAPI ReleaseActCtx(HANDLE hActCtx)
     {
         if (!InterlockedDecrement( &actctx->ref_count ))
         {
-            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, 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, dll->name);
                 }
+                HeapFree(GetProcessHeap(), 0, assembly->dlls);
                 HeapFree(GetProcessHeap(), 0, assembly->manifest.info);
                 free_assembly_identity(&assembly->id);
             }





More information about the wine-patches mailing list