From 4ff0faa67cbc150b1031af927f919c0e438968df Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 2 Aug 2011 15:15:55 +0200 Subject: [PATCH] widl: Generate a registration script along with the typelib when creating a resource file. --- dlls/stdole32.tlb/std_ole_v1.idl | 1 + tools/widl/register.c | 114 ++++++++++++++++++++++++------- tools/widl/widl.h | 1 + tools/widl/write_msft.c | 1 + tools/wine.inf.in | 15 ---- 5 files changed, 94 insertions(+), 38 deletions(-) diff --git a/dlls/stdole32.tlb/std_ole_v1.idl b/dlls/stdole32.tlb/std_ole_v1.idl index bf9cb7e2011..45fb3d50aed 100644 --- a/dlls/stdole32.tlb/std_ole_v1.idl +++ b/dlls/stdole32.tlb/std_ole_v1.idl @@ -20,6 +20,7 @@ [ uuid(00020430-0000-0000-C000-000000000046), + restricted, version(1.0), helpstring("OLE Automation") ] diff --git a/tools/widl/register.c b/tools/widl/register.c index ec573be0006..c75a6acd88e 100644 --- a/tools/widl/register.c +++ b/tools/widl/register.c @@ -77,40 +77,72 @@ static const type_t *find_ps_factory( const statement_list_t *stmts ) return NULL; } -static int write_interface( const type_t *iface, const type_t *ps_factory ) +static void write_interface( const type_t *iface, const type_t *ps_factory ) { const UUID *uuid = get_attrp( iface->attrs, ATTR_UUID ); const UUID *ps_uuid = get_attrp( ps_factory->attrs, ATTR_UUID ); - if (!uuid) return 0; - if (!is_object( iface )) return 0; + if (!uuid) return; + if (!is_object( iface )) return; if (!type_iface_get_inherit(iface)) /* special case for IUnknown */ { - put_str( indent, "ForceRemove '%s' = s '%s'\n", format_uuid( uuid ), iface->name ); - return 0; + put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name ); + return; } - if (is_local( iface->attrs )) return 0; - put_str( indent, "ForceRemove '%s' = s '%s'\n", format_uuid( uuid ), iface->name ); + if (is_local( iface->attrs )) return; + put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name ); put_str( indent, "{\n" ); indent++; put_str( indent, "NumMethods = s %u\n", count_methods( iface )); put_str( indent, "ProxyStubClsid32 = s '%s'\n", format_uuid( ps_uuid )); indent--; put_str( indent, "}\n" ); - return 1; } -static int write_interfaces( const statement_list_t *stmts, const type_t *ps_factory ) +static void write_interfaces( const statement_list_t *stmts, const type_t *ps_factory ) { const statement_t *stmt; - int count = 0; if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) { if (stmt->type == STMT_TYPE && type_get_type( stmt->u.type ) == TYPE_INTERFACE) - count += write_interface( stmt->u.type, ps_factory ); + write_interface( stmt->u.type, ps_factory ); + } +} + +static void write_typelib_interface( const type_t *iface, const typelib_t *typelib ) +{ + const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID ); + const UUID *uuid = get_attrp( iface->attrs, ATTR_UUID ); + unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION ); + + if (!uuid) return; + if (!is_object( iface )) return; + if (!is_attr( iface->attrs, ATTR_OLEAUTOMATION ) && !is_attr( iface->attrs, ATTR_DISPINTERFACE )) + return; + put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name ); + put_str( indent, "{\n" ); + indent++; + put_str( indent, "ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'\n" ); + put_str( indent, "ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'\n" ); + if (version) + put_str( indent, "TypeLib = s '%s' { val Version = s '%u.%u' }\n", + format_uuid( typelib_uuid ), MAJORVERSION(version), MINORVERSION(version) ); + else + put_str( indent, "TypeLib = s '%s'", format_uuid( typelib_uuid )); + indent--; + put_str( indent, "}\n" ); +} + +static void write_typelib_interfaces( const typelib_t *typelib ) +{ + const statement_t *stmt; + + if (typelib->stmts) LIST_FOR_EACH_ENTRY( stmt, typelib->stmts, const statement_t, entry ) + { + if (stmt->type == STMT_TYPE && type_get_type( stmt->u.type ) == TYPE_INTERFACE) + write_typelib_interface( stmt->u.type, typelib ); } - return count; } static int write_coclass( const type_t *class, const typelib_t *typelib ) @@ -123,10 +155,10 @@ static int write_coclass( const type_t *class, const typelib_t *typelib ) unsigned int version = get_attrv( class->attrs, ATTR_VERSION ); if (!uuid) return 0; - if (typelib && !threading) return 0; + if (typelib && !threading && !progid) return 0; if (!descr) descr = class->name; - put_str( indent, "ForceRemove '%s' = s '%s'\n", format_uuid( uuid ), descr ); + put_str( indent, "'%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 ); @@ -154,11 +186,6 @@ static void write_coclasses( const statement_list_t *stmts, const typelib_t *typ const type_t *type = stmt->u.type; if (type_get_type(type) == TYPE_COCLASS) write_coclass( type, typelib ); } - else if (stmt->type == STMT_LIBRARY) - { - const typelib_t *lib = stmt->u.lib; - write_coclasses( lib->stmts, lib ); - } } } @@ -201,10 +228,6 @@ static void write_progids( const statement_list_t *stmts ) 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 ); - } } } @@ -249,3 +272,48 @@ void write_regscript( const statement_list_t *stmts ) error( "Failed to write to %s\n", regscript_name ); } } + +void output_typelib_regscript( const typelib_t *typelib ) +{ + const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID ); + const char *descr = get_attrp( typelib->attrs, ATTR_HELPSTRING ); + const expr_t *lcid_expr = get_attrp( typelib->attrs, ATTR_LIBLCID ); + unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION ); + unsigned int flags = 0; + + if (is_attr( typelib->attrs, ATTR_RESTRICTED )) flags |= 1; /* LIBFLAG_FRESTRICTED */ + if (is_attr( typelib->attrs, ATTR_CONTROL )) flags |= 2; /* LIBFLAG_FCONTROL */ + if (is_attr( typelib->attrs, ATTR_HIDDEN )) flags |= 4; /* LIBFLAG_FHIDDEN */ + + put_str( indent, "HKCR\n" ); + put_str( indent++, "{\n" ); + + put_str( indent, "NoRemove Typelib\n" ); + put_str( indent++, "{\n" ); + put_str( indent, "NoRemove '%s'\n", format_uuid( typelib_uuid )); + put_str( indent++, "{\n" ); + put_str( indent, "'%u.%u' = s '%s'\n", + MAJORVERSION(version), MINORVERSION(version), descr ? descr : typelib->name ); + put_str( indent++, "{\n" ); + put_str( indent, "'%x' { %s = s '%%MODULE%%' }\n", + lcid_expr ? lcid_expr->cval : 0, typelib_kind == SYS_WIN64 ? "win64" : "win32" ); + put_str( indent, "FLAGS = s '%u'\n", flags ); + put_str( --indent, "}\n" ); + put_str( --indent, "}\n" ); + put_str( --indent, "}\n" ); + + put_str( indent, "NoRemove Interface\n" ); + put_str( indent++, "{\n" ); + write_typelib_interfaces( typelib ); + put_str( --indent, "}\n" ); + + put_str( indent, "NoRemove CLSID\n" ); + put_str( indent++, "{\n" ); + write_coclasses( typelib->stmts, typelib ); + put_str( --indent, "}\n" ); + + write_progids( typelib->stmts ); + put_str( --indent, "}\n" ); + + add_output_to_resources( "WINE_REGISTRY", typelib_name ); +} diff --git a/tools/widl/widl.h b/tools/widl/widl.h index 20be1f3cbd4..6551fa07fbe 100644 --- a/tools/widl/widl.h +++ b/tools/widl/widl.h @@ -86,6 +86,7 @@ extern void write_proxies(const statement_list_t *stmts); extern void write_client(const statement_list_t *stmts); extern void write_server(const statement_list_t *stmts); extern void write_regscript(const statement_list_t *stmts); +extern void output_typelib_regscript( const typelib_t *typelib ); extern void write_local_stubs(const statement_list_t *stmts); extern void write_dlldata(const statement_list_t *stmts); diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index 66da2866cf8..416f81d2f73 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -2546,6 +2546,7 @@ static void save_all_changes(msft_typelib_t *typelib) if (strendswith( typelib_name, ".res" )) /* create a binary resource file */ { add_output_to_resources( "TYPELIB", "#1" ); + output_typelib_regscript( typelib->typelib ); flush_output_resources( typelib_name ); } else flush_output_buffer( typelib_name ); diff --git a/tools/wine.inf.in b/tools/wine.inf.in index cfefbe48346..af68d8f054a 100644 --- a/tools/wine.inf.in +++ b/tools/wine.inf.in @@ -231,9 +231,6 @@ HKCR,https\shell\open\ddeexec,"NoActivateHandler",2,"" HKCR,https\shell\open\ddeexec\Application,,2,"IExplore" HKCR,https\shell\open\ddeexec\Topic,,2,"WWW_OpenURL" HKCR,mailto\shell\open\command,,2,"%11%\winebrowser %1" -; FIXME: the following should be done by the dll registration -HKCR,TypeLib\{00020430-0000-0000-C000-000000000046}\1.0\0\win16,,,"stdole.tlb" -HKCR,TypeLib\{00020430-0000-0000-C000-000000000046}\1.0\FLAGS,,,"1" HKCR,MIME\Database\Charset\_iso-2022-jp$ESC,"Codepage",0x10003,932 HKCR,MIME\Database\Charset\_iso-2022-jp$ESC,"InternetEncoding",0x10003,50221 @@ -2496,19 +2493,9 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 11,,cryptdlg.dll,1 11,,cryptnet.dll,1 11,,devenum.dll,1 -11,,gameux.dll,1 -11,,hhctrl.ocx,1 -11,,ieframe.dll,1 -11,,jscript.dll,1 11,,mshtml.dll,1 -11,,msi.dll,1 11,,msiexec.exe,1 11,,msisip.dll,1 -11,,msxml.dll,1 -11,,msxml2.dll,1 -11,,msxml3.dll,1 -11,,msxml4.dll,1 -11,,msxml6.dll,1 11,,qcap.dll,1 11,,qmgr.dll,1 11,,quartz.dll,1 @@ -2517,9 +2504,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 11,,windowscodecs.dll,1 11,,winegstreamer.dll,1 11,,wineqtdecoder.dll,1 -11,,winhttp.dll,1 11,,wintrust.dll,1 -11,,wuapi.dll,1 11,,iexplore.exe,1 ; 32bit-only fake dlls