-- v2: widl: Add rows for regular methods. widl: Add rows for eventremove methods. widl: Add rows for eventadd methods. widl: Add rows for propput methods. widl: Add rows for propget methods.
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 180 +++++++++++++++++++++++++++++++++++++++++ tools/widl/widltypes.h | 1 + 2 files changed, 181 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 0e3d7f18e75..af9a50008d7 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -601,6 +601,16 @@ static enum table customattribute_type_to_table( UINT token ) } }
+static enum table has_semantics_to_table( UINT token ) +{ + switch (token & 0x1) + { + case 0: return TABLE_EVENT; + case 1: return TABLE_PROPERTY; + default: assert( 0 ); + } +} + struct module_row { USHORT generation; @@ -998,6 +1008,97 @@ static void serialize_assemblyref_table( void ) } }
+struct propertymap_row +{ + UINT parent; + UINT proplist; +}; + +static UINT add_propertymap_row( UINT parent, UINT proplist ) +{ + struct propertymap_row row = { parent, proplist }; + return add_row( TABLE_PROPERTYMAP, (const BYTE *)&row, sizeof(row) ); +} + +static void serialize_propertymap_table( void ) +{ + const struct propertymap_row *row = (const struct propertymap_row *)tables[TABLE_PROPERTYMAP].ptr; + UINT i; + + for (i = 0; i < tables[TABLE_PROPERTYMAP].count; i++) + { + serialize_table_idx( row->parent, TABLE_TYPEDEF ); + serialize_table_idx( row->proplist, TABLE_PROPERTY ); + row++; + } +} + +struct property_row +{ + USHORT flags; + UINT name; + UINT type; +}; + +static UINT add_property_row( USHORT flags, UINT name, UINT type ) +{ + struct property_row row = { flags, name, type }; + return add_row( TABLE_PROPERTY, (const BYTE *)&row, sizeof(row) ); +} + +static void serialize_property_table( void ) +{ + const struct property_row *row = (const struct property_row *)tables[TABLE_PROPERTY].ptr; + UINT i; + + for (i = 0; i < tables[TABLE_PROPERTY].count; i++) + { + serialize_ushort( row->flags ); + serialize_string_idx( row->name ); + serialize_blob_idx( row->type ); + row++; + } +} + +struct methodsemantics_row +{ + USHORT semantics; + UINT method; + UINT association; +}; + +static UINT add_methodsemantics_row( USHORT flags, UINT name, UINT type ) +{ + struct methodsemantics_row row = { flags, name, type }; + return add_row( TABLE_METHODSEMANTICS, (const BYTE *)&row, sizeof(row) ); +} + +static int cmp_methodsemantics_row( const void *a, const void *b ) +{ + const struct methodsemantics_row *row = a, *row2 = b; + if (row->association > row2->association) return 1; + if (row->association < row2->association) return -1; + return 0; +} + +/* sorted by association */ +static void serialize_methodsemantics_table( void ) +{ + const struct methodsemantics_row *row = (const struct methodsemantics_row *)tables[TABLE_METHODSEMANTICS].ptr; + UINT i; + + qsort( tables[TABLE_METHODSEMANTICS].ptr, tables[TABLE_METHODSEMANTICS].count, sizeof(*row), + cmp_methodsemantics_row ); + + for (i = 0; i < tables[TABLE_METHODSEMANTICS].count; i++) + { + serialize_ushort( row->semantics ); + serialize_table_idx( row->method, TABLE_METHODDEF ); + serialize_table_idx( row->association, has_semantics_to_table(row->association) ); + row++; + } +} + static UINT typedef_or_ref( enum table table, UINT row ) { switch (table) @@ -1081,6 +1182,16 @@ static UINT customattribute_type( enum table table, UINT row ) } }
+static UINT has_semantics( enum table table, UINT row ) +{ + switch (table) + { + case TABLE_EVENT: return row << 1; + case TABLE_PROPERTY: return row << 1 | 1; + default: assert( 0 ); + } +} + enum element_type { ELEMENT_TYPE_END = 0x00, @@ -1196,6 +1307,15 @@ enum METHOD_IMPL_UNMANAGED = 0x0004 };
+enum +{ + METHOD_SEM_SETTER = 0x0001, + METHOD_SEM_GETTER = 0x0002, + METHOD_SEM_OTHER = 0x0004, + METHOD_SEM_ADDON = 0x0008, + METHOD_SEM_REMOVEON = 0x0010 +}; + enum { PARAM_ATTR_IN = 0x0001, @@ -1422,6 +1542,28 @@ static UINT make_method_sig( const var_t *method, BYTE *buf ) return len; }
+static UINT make_property_sig( const var_t *method, BYTE *buf ) +{ + const var_t *arg; + const var_list_t *arg_list = type_function_get_args( method->declspec.type ); + UINT len = 3; + + buf[0] = SIG_TYPE_HASTHIS | SIG_TYPE_PROPERTY; + buf[1] = 0; + buf[2] = ELEMENT_TYPE_VOID; + + LIST_FOR_EACH_ENTRY( arg, arg_list, var_t, entry ) + { + const type_t *type; + + if (!is_attr( arg->attrs, ATTR_RETVAL )) continue; + type = type_pointer_get_ref_type( arg->declspec.type ); /* retval must be a pointer */ + len = make_type_sig( type, buf + 2 ) + 2; + } + + return len; +} + static UINT make_contract_value( const type_t *type, BYTE *buf ) { const expr_t *contract = get_attrp( type->attrs, ATTR_CONTRACT ); @@ -1766,11 +1908,39 @@ static UINT add_method_params_step2( var_list_t *arg_list ) return first; }
+static void add_propget_method( const type_t *iface, const var_t *method ) +{ + UINT methoddef, property, sig_size, paramlist, attrs; + BYTE sig[256]; + char *name; + + /* method may already have been added by add_propput_method() */ + if (method->declspec.type->md.property) return; + + sig_size = make_property_sig( method, sig ); + property = add_property_row( 0, add_string(method->name), add_blob(sig, sig_size) ); + method->declspec.type->md.property = property; + add_propertymap_row( iface->md.def, property ); + + paramlist = add_method_params_step2( type_function_get_args(method->declspec.type) ); + sig_size = make_method_sig( method, sig ); + + attrs = METHOD_ATTR_PUBLIC | METHOD_ATTR_VIRTUAL | METHOD_ATTR_HIDEBYSIG | + METHOD_ATTR_NEWSLOT | METHOD_ATTR_ABSTRACT | METHOD_ATTR_SPECIALNAME; + + name = strmake( "get_%s", method->name ); + methoddef = add_methoddef_row( 0, attrs, add_string(name), add_blob(sig, sig_size), paramlist ); + free( name ); + + add_methodsemantics_row( METHOD_SEM_GETTER, methoddef, has_semantics(TABLE_PROPERTY, property) ); +} + static void add_interface_type_step2( type_t *type ) { UINT name, namespace, interface, flags = TYPE_ATTR_INTERFACE | TYPE_ATTR_ABSTRACT | TYPE_ATTR_UNKNOWN; const typeref_list_t *require_list = type_iface_get_requires( type ); const typeref_t *require; + const statement_t *stmt;
name = add_name( type, &namespace );
@@ -1783,6 +1953,13 @@ static void add_interface_type_step2( type_t *type ) add_interfaceimpl_row( type->md.def, interface ); }
+ STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(type) ) + { + const var_t *method = stmt->u.var; + + if (is_attr( method->attrs, ATTR_PROPGET )) add_propget_method( type, method ); + } + add_contract_attr_step2( type ); add_uuid_attr_step2( type ); add_exclusiveto_attr_step2( type ); @@ -2052,6 +2229,9 @@ static void build_table_stream( const statement_list_t *stmts ) serialize_memberref_table(); serialize_constant_table(); serialize_customattribute_table(); + serialize_propertymap_table(); + serialize_property_table(); + serialize_methodsemantics_table(); serialize_assembly_table(); serialize_assemblyref_table(); } diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index c76dea97a6c..bf2d6d4e8d8 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -518,6 +518,7 @@ struct metadata unsigned int def; unsigned int extends; unsigned int member[MD_ATTR_MAX]; + unsigned int property; /* get/put methods */ };
struct _type_t {
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index af9a50008d7..f5cda27062d 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -1935,6 +1935,42 @@ static void add_propget_method( const type_t *iface, const var_t *method ) add_methodsemantics_row( METHOD_SEM_GETTER, methoddef, has_semantics(TABLE_PROPERTY, property) ); }
+static const var_t *find_propget_method( const type_t *iface, const char *name ) +{ + const statement_t *stmt; + + STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) ) + { + const var_t *method = stmt->u.var; + if (is_attr( method->attrs, ATTR_PROPGET ) && !strcmp( method->name, name )) return method; + } + return NULL; +} + +static void add_propput_method( const type_t *iface, const var_t *method ) +{ + const var_t *propget = find_propget_method( iface, method->name ); + UINT methoddef, property, sig_size, paramlist, attrs; + BYTE sig[256]; + char *name; + + paramlist = add_method_params_step2( type_function_get_args(method->declspec.type) ); + sig_size = make_method_sig( method, sig ); + + attrs = METHOD_ATTR_PUBLIC | METHOD_ATTR_VIRTUAL | METHOD_ATTR_HIDEBYSIG | + METHOD_ATTR_NEWSLOT | METHOD_ATTR_ABSTRACT | METHOD_ATTR_SPECIALNAME; + + name = strmake( "put_%s", method->name ); + methoddef = add_methoddef_row( 0, attrs, add_string(name), add_blob(sig, sig_size), paramlist ); + free( name ); + + /* add propget method if not already added */ + if (!propget->declspec.type->md.property) add_propget_method( iface, propget ); + property = propget->declspec.type->md.property; + + add_methodsemantics_row( METHOD_SEM_SETTER, methoddef, has_semantics(TABLE_PROPERTY, property) ); +} + static void add_interface_type_step2( type_t *type ) { UINT name, namespace, interface, flags = TYPE_ATTR_INTERFACE | TYPE_ATTR_ABSTRACT | TYPE_ATTR_UNKNOWN; @@ -1958,6 +1994,7 @@ static void add_interface_type_step2( type_t *type ) const var_t *method = stmt->u.var;
if (is_attr( method->attrs, ATTR_PROPGET )) add_propget_method( type, method ); + else if (is_attr( method->attrs, ATTR_PROPPUT )) add_propput_method( type, method ); }
add_contract_attr_step2( type );
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 111 +++++++++++++++++++++++++++++++++++++++++ tools/widl/widltypes.h | 1 + 2 files changed, 112 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index f5cda27062d..224c019cd42 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -1060,6 +1060,58 @@ static void serialize_property_table( void ) } }
+struct eventmap_row +{ + UINT parent; + UINT eventlist; +}; + +static UINT add_eventmap_row( UINT parent, UINT eventlist ) +{ + struct eventmap_row row = { parent, eventlist }; + return add_row( TABLE_EVENTMAP, (const BYTE *)&row, sizeof(row) ); +} + +static void serialize_eventmap_table( void ) +{ + const struct eventmap_row *row = (const struct eventmap_row *)tables[TABLE_EVENTMAP].ptr; + UINT i; + + for (i = 0; i < tables[TABLE_EVENTMAP].count; i++) + { + serialize_table_idx( row->parent, TABLE_TYPEDEF ); + serialize_table_idx( row->eventlist, TABLE_EVENT ); + row++; + } +} + +struct event_row +{ + USHORT flags; + UINT name; + UINT type; +}; + +static UINT add_event_row( USHORT flags, UINT name, UINT type ) +{ + struct event_row row = { flags, name, type }; + return add_row( TABLE_EVENT, (const BYTE *)&row, sizeof(row) ); +} + +static void serialize_event_table( void ) +{ + const struct event_row *row = (const struct event_row *)tables[TABLE_EVENT].ptr; + UINT i; + + for (i = 0; i < tables[TABLE_EVENT].count; i++) + { + serialize_ushort( row->flags ); + serialize_string_idx( row->name ); + serialize_table_idx( row->type, typedef_or_ref_to_table(row->type) ); + row++; + } +} + struct methodsemantics_row { USHORT semantics; @@ -1858,8 +1910,31 @@ static void add_exclusiveto_attr_step2( type_t *type ) add_customattribute_row( parent, attr_type, add_blob(value, value_size) ); }
+static void add_method_params_step1( var_list_t *arg_list ) +{ + var_t *arg; + + if (!arg_list) return; + + LIST_FOR_EACH_ENTRY( arg, arg_list, var_t, entry ) + { + type_t *type = arg->declspec.type; + + if (type_get_type( type ) == TYPE_POINTER) type = type_pointer_get_ref_type( type ); + + if (type->name && !strcmp( type->name, "EventRegistrationToken" )) + { + UINT assemblyref, scope; + assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") ); + scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref ); + type->md.ref = add_typeref_row( scope, add_string("EventRegistrationToken"), add_string("Windows.Foundation") ); + } + } +} + static void add_interface_type_step1( type_t *type ) { + const statement_t *stmt; UINT name, namespace;
name = add_name( type, &namespace ); @@ -1869,6 +1944,13 @@ static void add_interface_type_step1( type_t *type ) add_contract_attr_step1( type ); add_uuid_attr_step1( type ); add_exclusiveto_attr_step1( type ); + + STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(type) ) + { + const var_t *method = stmt->u.var; + + add_method_params_step1( type_function_get_args(method->declspec.type) ); + } }
static UINT get_param_attrs( const var_t *arg ) @@ -1971,6 +2053,32 @@ static void add_propput_method( const type_t *iface, const var_t *method ) add_methodsemantics_row( METHOD_SEM_SETTER, methoddef, has_semantics(TABLE_PROPERTY, property) ); }
+static void add_eventadd_method( const type_t *iface, const var_t *method ) +{ + UINT methoddef, event, sig_size, paramlist, attrs; + BYTE sig[256]; + char *name; + + event = add_event_row( 0, add_string(method->name), typedef_or_ref(TABLE_TYPEREF, method->declspec.type->md.ref) ); + method->declspec.type->md.event = event; + add_eventmap_row( iface->md.def, event ); + + /* method may already have been added by add_eventremove_method() */ + if (method->declspec.type->md.event) return; + + paramlist = add_method_params_step2( type_function_get_args(method->declspec.type) ); + sig_size = make_method_sig( method, sig ); + + attrs = METHOD_ATTR_PUBLIC | METHOD_ATTR_VIRTUAL | METHOD_ATTR_HIDEBYSIG | + METHOD_ATTR_NEWSLOT | METHOD_ATTR_ABSTRACT | METHOD_ATTR_SPECIALNAME; + + name = strmake( "add_%s", method->name ); + methoddef = add_methoddef_row( 0, attrs, add_string(name), add_blob(sig, sig_size), paramlist ); + free( name ); + + add_methodsemantics_row( METHOD_SEM_ADDON, methoddef, has_semantics(TABLE_EVENT, event) ); +} + static void add_interface_type_step2( type_t *type ) { UINT name, namespace, interface, flags = TYPE_ATTR_INTERFACE | TYPE_ATTR_ABSTRACT | TYPE_ATTR_UNKNOWN; @@ -1995,6 +2103,7 @@ static void add_interface_type_step2( type_t *type )
if (is_attr( method->attrs, ATTR_PROPGET )) add_propget_method( type, method ); else if (is_attr( method->attrs, ATTR_PROPPUT )) add_propput_method( type, method ); + else if (is_attr( method->attrs, ATTR_EVENTADD )) add_eventadd_method( type, method ); }
add_contract_attr_step2( type ); @@ -2266,6 +2375,8 @@ static void build_table_stream( const statement_list_t *stmts ) serialize_memberref_table(); serialize_constant_table(); serialize_customattribute_table(); + serialize_eventmap_table(); + serialize_event_table(); serialize_propertymap_table(); serialize_property_table(); serialize_methodsemantics_table(); diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index bf2d6d4e8d8..73d593a6aee 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -519,6 +519,7 @@ struct metadata unsigned int extends; unsigned int member[MD_ATTR_MAX]; unsigned int property; /* get/put methods */ + unsigned int event; /* add/remove methods */ };
struct _type_t {
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 224c019cd42..98bb613acbb 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -2079,6 +2079,42 @@ static void add_eventadd_method( const type_t *iface, const var_t *method ) add_methodsemantics_row( METHOD_SEM_ADDON, methoddef, has_semantics(TABLE_EVENT, event) ); }
+static const var_t *find_eventadd_method( const type_t *iface, const char *name ) +{ + const statement_t *stmt; + + STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) ) + { + const var_t *method = stmt->u.var; + if (is_attr( method->attrs, ATTR_EVENTADD ) && !strcmp( method->name, name )) return method; + } + return NULL; +} + +static void add_eventremove_method( const type_t *iface, const var_t *method ) +{ + const var_t *eventadd = find_eventadd_method( iface, method->name ); + UINT methoddef, event, sig_size, paramlist, attrs; + BYTE sig[256]; + char *name; + + paramlist = add_method_params_step2( type_function_get_args(method->declspec.type) ); + sig_size = make_method_sig( method, sig ); + + attrs = METHOD_ATTR_PUBLIC | METHOD_ATTR_VIRTUAL | METHOD_ATTR_HIDEBYSIG | + METHOD_ATTR_NEWSLOT | METHOD_ATTR_ABSTRACT | METHOD_ATTR_SPECIALNAME; + + name = strmake( "remove_%s", method->name ); + methoddef = add_methoddef_row( 0, attrs, add_string(name), add_blob(sig, sig_size), paramlist ); + free( name ); + + /* add eventadd method if not already added */ + if (!eventadd->declspec.type->md.event) add_eventadd_method( iface, eventadd ); + event = eventadd->declspec.type->md.event; + + add_methodsemantics_row( METHOD_SEM_REMOVEON, methoddef, has_semantics(TABLE_EVENT, event) ); +} + static void add_interface_type_step2( type_t *type ) { UINT name, namespace, interface, flags = TYPE_ATTR_INTERFACE | TYPE_ATTR_ABSTRACT | TYPE_ATTR_UNKNOWN; @@ -2104,6 +2140,7 @@ static void add_interface_type_step2( type_t *type ) if (is_attr( method->attrs, ATTR_PROPGET )) add_propget_method( type, method ); else if (is_attr( method->attrs, ATTR_PROPPUT )) add_propput_method( type, method ); else if (is_attr( method->attrs, ATTR_EVENTADD )) add_eventadd_method( type, method ); + else if (is_attr( method->attrs, ATTR_EVENTREMOVE )) add_eventremove_method( type, method ); }
add_contract_attr_step2( type );
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 98bb613acbb..73b3b97a821 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -2115,6 +2115,20 @@ static void add_eventremove_method( const type_t *iface, const var_t *method ) add_methodsemantics_row( METHOD_SEM_REMOVEON, methoddef, has_semantics(TABLE_EVENT, event) ); }
+static void add_method( const type_t *iface, const var_t *method ) +{ + UINT paramlist, sig_size, attrs; + BYTE sig[256]; + + paramlist = add_method_params_step2( type_function_get_args(method->declspec.type) ); + sig_size = make_method_sig( method, sig ); + + attrs = METHOD_ATTR_PUBLIC | METHOD_ATTR_VIRTUAL | METHOD_ATTR_HIDEBYSIG | + METHOD_ATTR_NEWSLOT | METHOD_ATTR_ABSTRACT; + + add_methoddef_row( 0, attrs, add_string(method->name), add_blob(sig, sig_size), paramlist ); +} + static void add_interface_type_step2( type_t *type ) { UINT name, namespace, interface, flags = TYPE_ATTR_INTERFACE | TYPE_ATTR_ABSTRACT | TYPE_ATTR_UNKNOWN; @@ -2141,6 +2155,7 @@ static void add_interface_type_step2( type_t *type ) else if (is_attr( method->attrs, ATTR_PROPPUT )) add_propput_method( type, method ); else if (is_attr( method->attrs, ATTR_EVENTADD )) add_eventadd_method( type, method ); else if (is_attr( method->attrs, ATTR_EVENTREMOVE )) add_eventremove_method( type, method ); + else add_method( type, method ); }
add_contract_attr_step2( type );
On Wed Jun 18 11:07:37 2025 +0000, Hans Leidekker wrote:
This is what midlrt generates as soon as you define an addevent method. It encodes the type of the event in the event table.
But I don't understand why this is hardcoded like that for this specific parameter type name.
If typerefs are required for any imported types, which is probably what this is about, we need to generate them for every parameter and for every method.
On Wed Jun 18 11:17:47 2025 +0000, Rémi Bernon wrote:
For instance something like that doesn't work, monodis asserts and ILSpy fails to resolve the method parameter types:
``` [ contract(Windows.Foundation.UniversalApiContract, 1.0), uuid(11111111-2222-3333-4444-555555555555), ] interface IWineInterface : IInspectable { void WineMethod([in] IUnknown *param); }; ```
On Wed Jun 18 11:30:47 2025 +0000, Rémi Bernon wrote:
Sure this should probably be generalized. I didn't get to imported types yet.
On Wed Jun 18 11:31:12 2025 +0000, Hans Leidekker wrote:
Sure this should probably be generalized. I didn't get to imported types yet.
Seems to me that something like that instead would make it work, do you think it's more complicated?
``` static UINT add_name( type_t *type, UINT *namespace ) { UINT name = add_string( type->name ); if (!type->namespace) *namespace = add_string( "Windows.Foundation" ); else { char *str = format_namespace( type->namespace, "", ".", NULL, NULL ); *namespace = add_string( str ); free( str ); } return name; }
/* ... */
if (type->name) { UINT assemblyref, scope, name, namespace; name = add_name( type, &namespace ); assemblyref = add_assemblyref_row( 0x200, 0, namespace ); scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref ); type->md.ref = add_typeref_row( scope, name, namespace ); } ```
On Wed Jun 18 11:37:23 2025 +0000, Rémi Bernon wrote:
I don't know. Is it safe to assume that the type is imported from Windows.Foundation if it doesn't have a namespace? All winmd files I've seen have a Windows.Foundation assembly reference but they also reference mscorlib for example.
On Wed Jun 18 12:07:28 2025 +0000, Hans Leidekker wrote:
midlrt requires you to pass a 'platform metadata directory'. I suspect it uses that to resolve imported types.
On Wed Jun 18 12:17:55 2025 +0000, Hans Leidekker wrote:
midlrt requires you to pass a 'platform metadata directory'. I suspect it uses that to resolve imported types.
IUnknown is not accepted by midlrt but if I use an IInspectable parameter and pass an empty metadata dir I get an error: Could not load required metadata file. If I copy system windows.foundation.winmd to that directory the idl file compiles successfully. So it does appear to use that directory to resolve IInspectable at least.
On Wed Jun 18 12:45:24 2025 +0000, Hans Leidekker wrote:
It looks like WinRT interface are simply not allowed to use anything that isn't a WinRT type. Trying to pass types from the global namespace usually fails a the IDL parsing time.
Then it seems like that EventRegistrationToken is allowed, but it also doesn't show up from `Windows.Foundation` assembly or namespace in ILSpy. Its namespace is `System.Runtime.InteropServices.WindowsRuntime`, its resolution scope is 0 and and its assembly ref seems special:
 
On Wed Jun 18 12:58:50 2025 +0000, Rémi Bernon wrote:
... which is something ILSpy seems to be doing on its own. Well we can leave it like that for now, but I think it would be better to ultimately do it differently, it doesn't look right to have some type name specific logic there.
This merge request was approved by Rémi Bernon.
On Wed Jun 18 13:06:13 2025 +0000, Rémi Bernon wrote:
I agree that imported types should be handled in a generic way but note that EventRegistrationToken is still special in the sense that it's the only type allowed in WinRT eventadd methods.
This merge request was approved by Huw Davies.