widl: Generate a registration script along with the typelib when creating a resource file.

This commit is contained in:
Alexandre Julliard 2011-08-02 15:15:55 +02:00
parent 5ec4e8f192
commit 4ff0faa67c
5 changed files with 94 additions and 38 deletions

View File

@ -20,6 +20,7 @@
[
uuid(00020430-0000-0000-C000-000000000046),
restricted,
version(1.0),
helpstring("OLE Automation")
]

View File

@ -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 );
}

View File

@ -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);

View File

@ -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 );

View File

@ -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