Alexandre Julliard : widl: Generate keys for coclasses in the registration resources.

Alexandre Julliard julliard at winehq.org
Thu Dec 2 12:23:57 CST 2010


Module: wine
Branch: master
Commit: 335282f5648b6bba215f969870e11a6b466b3738
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=335282f5648b6bba215f969870e11a6b466b3738

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Nov 30 12:49:01 2010 +0100

widl: Generate keys for coclasses in the registration resources.

---

 tools/widl/register.c |  109 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/tools/widl/register.c b/tools/widl/register.c
index 61870ea..20554b1 100644
--- a/tools/widl/register.c
+++ b/tools/widl/register.c
@@ -47,6 +47,20 @@ static const char *format_uuid( const UUID *uuid )
     return buffer;
 }
 
+static const char *get_coclass_threading( const type_t *class )
+{
+    static const char * const models[] =
+    {
+        NULL,
+        "Apartment", /* THREADING_APARTMENT */
+        "Neutral",   /* THREADING_NEUTRAL */
+        "Single",    /* THREADING_SINGLE */
+        "Free",      /* THREADING_FREE */
+        "Both",      /* THREADING_BOTH */
+    };
+    return models[get_attrv( class->attrs, ATTR_THREADING )];
+}
+
 static int write_interface( const type_t *iface )
 {
     const UUID *uuid = get_attrp( iface->attrs, ATTR_UUID );
@@ -79,6 +93,93 @@ static int write_interfaces( const statement_list_t *stmts )
     return count;
 }
 
+static int write_coclass( const type_t *class )
+{
+    const UUID *uuid = get_attrp( class->attrs, ATTR_UUID );
+    const char *descr = get_attrp( class->attrs, ATTR_HELPSTRING );
+    const char *progid = get_attrp( class->attrs, ATTR_PROGID );
+    const char *vi_progid = get_attrp( class->attrs, ATTR_VIPROGID );
+    const char *threading = get_coclass_threading( class );
+
+    if (!uuid) return 0;
+    if (!descr) descr = class->name;
+
+    put_str( indent, "ForceRemove '%s' = s '%s'\n", format_uuid( uuid ), descr );
+    put_str( indent++, "{\n" );
+    if (threading) put_str( indent, "InprocServer32 = s '%%MODULE%%' { val ThreadingModel = s '%s' }\n",
+                            threading );
+    if (progid || vi_progid) put_str( indent, "CLSID = s '%s'\n", descr );
+    if (progid) put_str( indent, "ProgId = s '%s'\n", progid );
+    if (vi_progid) put_str( indent, "VersionIndependentProgId = s '%s'\n", vi_progid );
+    put_str( --indent, "}\n" );
+    return 1;
+}
+
+static void write_coclasses( const statement_list_t *stmts, const UUID *typelib_uuid )
+{
+    const statement_t *stmt;
+
+    if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+    {
+        if (stmt->type == STMT_TYPE)
+        {
+            const type_t *type = stmt->u.type;
+            if (type_get_type(type) == TYPE_COCLASS) write_coclass( type );
+        }
+        else if (stmt->type == STMT_LIBRARY)
+        {
+            const UUID *uuid = get_attrp( stmt->u.lib->attrs, ATTR_UUID );
+            write_coclasses( stmt->u.lib->stmts, uuid );
+        }
+    }
+}
+
+static int write_progid( const type_t *class )
+{
+    const UUID *uuid = get_attrp( class->attrs, ATTR_UUID );
+    const char *descr = get_attrp( class->attrs, ATTR_HELPSTRING );
+    const char *progid = get_attrp( class->attrs, ATTR_PROGID );
+    const char *vi_progid = get_attrp( class->attrs, ATTR_VIPROGID );
+
+    if (!uuid) return 0;
+    if (!descr) descr = vi_progid ? vi_progid : progid;
+
+    if (progid)
+    {
+        put_str( indent, "ForceRemove '%s' = s '%s'\n", progid, descr );
+        put_str( indent++, "{\n" );
+        put_str( indent, "CLSID = s '%s'\n", format_uuid( uuid ) );
+        put_str( --indent, "}\n" );
+    }
+    if (vi_progid)
+    {
+        put_str( indent, "ForceRemove '%s' = s '%s'\n", vi_progid, descr );
+        put_str( indent++, "{\n" );
+        put_str( indent, "CLSID = s '%s'\n", format_uuid( uuid ) );
+        if (progid) put_str( indent, "CurVer = s '%s'\n", progid );
+        put_str( --indent, "}\n" );
+    }
+    return 1;
+}
+
+static void write_progids( const statement_list_t *stmts )
+{
+    const statement_t *stmt;
+
+    if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+    {
+        if (stmt->type == STMT_TYPE)
+        {
+            const type_t *type = stmt->u.type;
+            if (type_get_type(type) == TYPE_COCLASS) write_progid( type );
+        }
+        else if (stmt->type == STMT_LIBRARY)
+        {
+            write_progids( stmt->u.lib->stmts );
+        }
+    }
+}
+
 /* put a string into the resource file */
 static inline void put_string( const char *str )
 {
@@ -107,17 +208,19 @@ void write_regscript( const statement_list_t *stmts )
     count = write_interfaces( stmts );
     put_str( --indent, "}\n" );
 
+    put_str( indent, "NoRemove CLSID\n" );
+    put_str( indent++, "{\n" );
     if (count)
     {
-        put_str( indent, "NoRemove CLSID\n" );
-        put_str( indent++, "{\n" );
         put_str( indent, "ForceRemove '%%CLSID_PSFactoryBuffer%%' = s 'PSFactoryBuffer'\n" );
         put_str( indent++, "{\n" );
         put_str( indent, "InprocServer32 = s '%%MODULE%%' { val ThreadingModel = s 'Both' }\n" );
         put_str( --indent, "}\n" );
-        put_str( --indent, "}\n" );
     }
+    write_coclasses( stmts, NULL );
+    put_str( --indent, "}\n" );
 
+    write_progids( stmts );
     put_str( --indent, "}\n" );
 
     if (strendswith( regscript_name, ".res" ))  /* create a binary resource file */




More information about the wine-cvs mailing list