From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 94 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 71ad7abfd8e..145d534a26a 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -177,13 +177,87 @@ static void write_headers( UINT image_size ) } }
+enum table +{ + TABLE_MODULE = 0x00, + TABLE_TYPEREF = 0x01, + TABLE_TYPEDEF = 0x02, + TABLE_FIELD = 0x04, + TABLE_METHODDEF = 0x06, + TABLE_PARAM = 0x08, + TABLE_INTERFACEIMPL = 0x09, + TABLE_MEMBERREF = 0x0a, + TABLE_CONSTANT = 0x0b, + TABLE_CUSTOMATTRIBUTE = 0x0c, + TABLE_FIELDMARSHAL = 0x0d, + TABLE_DECLSECURITY = 0x0e, + TABLE_CLASSLAYOUT = 0x0f, + TABLE_FIELDLAYOUT = 0x10, + TABLE_STANDALONESIG = 0x11, + TABLE_EVENTMAP = 0x12, + TABLE_EVENT = 0x14, + TABLE_PROPERTYMAP = 0x15, + TABLE_PROPERTY = 0x17, + TABLE_METHODSEMANTICS = 0x18, + TABLE_METHODIMPL = 0x19, + TABLE_MODULEREF = 0x1a, + TABLE_TYPESPEC = 0x1b, + TABLE_IMPLMAP = 0x1c, + TABLE_FIELDRVA = 0x1d, + TABLE_ASSEMBLY = 0x20, + TABLE_ASSEMBLYPROCESSOR = 0x21, + TABLE_ASSEMBLYOS = 0x22, + TABLE_ASSEMBLYREF = 0x23, + TABLE_ASSEMBLYREFPROCESSOR = 0x24, + TABLE_ASSEMBLYREFOS = 0x25, + TABLE_FILE = 0x26, + TABLE_EXPORTEDTYPE = 0x27, + TABLE_MANIFESTRESOURCE = 0x28, + TABLE_NESTEDCLASS = 0x29, + TABLE_GENERICPARAM = 0x2a, + TABLE_METHODSPEC = 0x2b, + TABLE_GENERICPARAMCONSTRAINT = 0x2c, + TABLE_MAX = 0x2d +}; + +#define SORTED_TABLES \ + 1ul << TABLE_INTERFACEIMPL |\ + 1ul << TABLE_CONSTANT |\ + 1ul << TABLE_CUSTOMATTRIBUTE |\ + 1ul << TABLE_FIELDMARSHAL |\ + 1ul << TABLE_DECLSECURITY |\ + 1ul << TABLE_CLASSLAYOUT |\ + 1ul << TABLE_FIELDLAYOUT |\ + 1ul << TABLE_EVENTMAP |\ + 1ul << TABLE_PROPERTYMAP |\ + 1ul << TABLE_METHODSEMANTICS |\ + 1ul << TABLE_METHODIMPL |\ + 1ul << TABLE_IMPLMAP |\ + 1ul << TABLE_FIELDRVA |\ + 1ul << TABLE_NESTEDCLASS |\ + 1ul << TABLE_GENERICPARAM |\ + 1ul << TABLE_GENERICPARAMCONSTRAINT + +static struct +{ + UINT reserved; + BYTE majorversion; + BYTE minor_version; + BYTE heap_sizes; + BYTE reserved2; + UINT64 valid; + UINT64 sorted; +} +tables_header = { 0, 2, 0, 0, 1, 0, SORTED_TABLES }; + static struct buffer { UINT offset; /* write position */ UINT allocated; /* allocated size in bytes */ UINT count; /* number of entries written */ BYTE *ptr; -} strings, strings_idx, userstrings, userstrings_idx, blobs, blobs_idx, guids; +} strings, strings_idx, userstrings, userstrings_idx, blobs, blobs_idx, guids, tables[TABLE_MAX], + tables_disk;
static void *grow_buffer( struct buffer *buf, UINT size ) { @@ -389,12 +463,24 @@ static void build_table_stream( const statement_list_t *stmts ) { static const GUID guid = { 0x9ddc04c6, 0x04ca, 0x04cc, { 0x52, 0x85, 0x4b, 0x50, 0xb2, 0x60, 0x1d, 0xa8 } }; static const USHORT space = 0x20; + UINT i;
add_string( "" ); add_userstring( NULL, 0 ); add_userstring( &space, sizeof(space) ); add_blob( NULL, 0 ); add_guid( &guid ); + + for (i = 0; i < TABLE_MAX; i++) if (tables[i].count) tables_header.valid |= (1ul << i); + + if (strings.offset >> 16) tables_header.heap_sizes |= 0x1; + if (guids.offset / sizeof(GUID) >> 16) tables_header.heap_sizes |= 0x2; + if (blobs.offset >> 16) tables_header.heap_sizes |= 0x4; + + add_bytes( &tables_disk, (const BYTE *)&tables_header, sizeof(tables_header) ); + + for (i = 0; i < TABLE_MAX; i++) + if (tables[i].count) add_bytes( &tables_disk, (const BYTE *)&tables[i].count, sizeof(tables[i].count) ); }
static void build_streams( const statement_list_t *stmts ) @@ -404,6 +490,12 @@ static void build_streams( const statement_list_t *stmts )
build_table_stream( stmts );
+ len = (tables_disk.offset + 3) & ~3; + add_bytes( &tables_disk, pad, len - tables_disk.offset ); + + streams[STREAM_TABLE].data_size = tables_disk.offset; + streams[STREAM_TABLE].data = tables_disk.ptr; + len = (strings.offset + 3) & ~3; add_bytes( &strings, pad, len - strings.offset );
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 69 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 145d534a26a..5719e3f966e 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -257,7 +257,7 @@ static struct buffer UINT count; /* number of entries written */ BYTE *ptr; } strings, strings_idx, userstrings, userstrings_idx, blobs, blobs_idx, guids, tables[TABLE_MAX], - tables_disk; + tables_idx[TABLE_MAX], tables_disk;
static void *grow_buffer( struct buffer *buf, UINT size ) { @@ -452,6 +452,25 @@ static UINT add_guid( const GUID *guid ) return ++guids.count; }
+/* returns row number */ +static UINT add_row( enum table table, const BYTE *row, UINT row_size ) +{ + const struct index *idx; + UINT insert_idx, offset = tables[table].offset; + BOOL sort = (table != TABLE_PARAM && table != TABLE_FIELD); + + if (sort && (idx = find_index( &tables_idx[table], &tables[table], row, row_size, FALSE, &insert_idx ))) + return idx->offset / row_size + 1; + + grow_buffer( &tables[table], row_size ); + memcpy( tables[table].ptr + offset, row, row_size ); + tables[table].offset += row_size; + tables[table].count++; + + if (sort) insert_index( &tables_idx[table], insert_idx, offset, row_size ); + return tables[table].count; +} + static void add_bytes( struct buffer *buf, const BYTE *data, UINT size ) { grow_buffer( buf, size ); @@ -459,6 +478,49 @@ static void add_bytes( struct buffer *buf, const BYTE *data, UINT size ) buf->offset += size; }
+static void serialize_ushort( USHORT value ) +{ + add_bytes( &tables_disk, (const BYTE *)&value, sizeof(value) ); +} + +static void serialize_string_idx( UINT idx ) +{ + UINT size = strings.offset >> 16 ? sizeof(UINT) : sizeof(USHORT); + add_bytes( &tables_disk, (const BYTE *)&idx, size ); +} + +static void serialize_guid_idx( UINT idx ) +{ + UINT size = guids.offset / sizeof(GUID) >> 16 ? sizeof(UINT) : sizeof(USHORT); + add_bytes( &tables_disk, (const BYTE *)&idx, size ); +} + +struct module_row +{ + USHORT generation; + UINT name; + UINT mvid; + UINT encid; + UINT encbaseid; +}; + +static UINT add_module_row( UINT name, UINT mvid ) +{ + struct module_row row = { 0, name, mvid }; + return add_row( TABLE_MODULE, (const BYTE *)&row, sizeof(row) ); +} + +static void serialize_module_table( void ) +{ + const struct module_row *row = (const struct module_row *)tables[TABLE_MODULE].ptr; + + serialize_ushort( row->generation ); + serialize_string_idx( row->name ); + serialize_guid_idx( row->mvid ); + serialize_guid_idx( row->encid ); + serialize_guid_idx( row->encbaseid ); +} + static void build_table_stream( const statement_list_t *stmts ) { static const GUID guid = { 0x9ddc04c6, 0x04ca, 0x04cc, { 0x52, 0x85, 0x4b, 0x50, 0xb2, 0x60, 0x1d, 0xa8 } }; @@ -469,7 +531,8 @@ static void build_table_stream( const statement_list_t *stmts ) add_userstring( NULL, 0 ); add_userstring( &space, sizeof(space) ); add_blob( NULL, 0 ); - add_guid( &guid ); + + add_module_row( add_string(metadata_name), add_guid(&guid) );
for (i = 0; i < TABLE_MAX; i++) if (tables[i].count) tables_header.valid |= (1ul << i);
@@ -481,6 +544,8 @@ static void build_table_stream( const statement_list_t *stmts )
for (i = 0; i < TABLE_MAX; i++) if (tables[i].count) add_bytes( &tables_disk, (const BYTE *)&tables[i].count, sizeof(tables[i].count) ); + + serialize_module_table(); }
static void build_streams( const statement_list_t *stmts )
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 61 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 5719e3f966e..4168e13b96b 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -483,6 +483,11 @@ static void serialize_ushort( USHORT value ) add_bytes( &tables_disk, (const BYTE *)&value, sizeof(value) ); }
+static void serialize_uint( UINT value ) +{ + add_bytes( &tables_disk, (const BYTE *)&value, sizeof(value) ); +} + static void serialize_string_idx( UINT idx ) { UINT size = strings.offset >> 16 ? sizeof(UINT) : sizeof(USHORT); @@ -495,6 +500,23 @@ static void serialize_guid_idx( UINT idx ) add_bytes( &tables_disk, (const BYTE *)&idx, size ); }
+static void serialize_table_idx( UINT idx, enum table target ) +{ + UINT size = tables[target].count >> 16 ? sizeof(UINT) : sizeof(USHORT); + add_bytes( &tables_disk, (const BYTE *)&idx, size ); +} + +static enum table typedef_or_ref_to_table( UINT token ) +{ + switch (token & 0x3) + { + case 0: return TABLE_TYPEDEF; + case 1: return TABLE_TYPEREF; + case 2: return TABLE_TYPESPEC; + default: exit( 1 ); + } +} + struct module_row { USHORT generation; @@ -521,6 +543,43 @@ static void serialize_module_table( void ) serialize_guid_idx( row->encbaseid ); }
+struct typedef_row +{ + UINT flags; + UINT typename; + UINT typenamespace; + UINT extends; + UINT fieldlist; + UINT methodlist; +}; + +static UINT add_typedef_row( UINT flags, UINT name, UINT namespace, UINT extends, UINT fieldlist, UINT methodlist ) +{ + struct typedef_row row = { flags, name, namespace, extends, fieldlist, methodlist }; + + if (!row.fieldlist) row.fieldlist = tables[TABLE_FIELD].count + 1; + if (!row.methodlist) row.methodlist = tables[TABLE_METHODDEF].count + 1; + return add_row( TABLE_TYPEDEF, (const BYTE *)&row, sizeof(row) ); +} + +/* FIXME: enclosing classes should come before enclosed classes */ +static void serialize_typedef_table( void ) +{ + const struct typedef_row *row = (const struct typedef_row *)tables[TABLE_TYPEDEF].ptr; + UINT i; + + for (i = 0; i < tables[TABLE_TYPEDEF].count; i++) + { + serialize_uint( row->flags ); + serialize_string_idx( row->typename ); + serialize_string_idx( row->typenamespace ); + serialize_table_idx( row->extends, typedef_or_ref_to_table(row->extends) ); + serialize_table_idx( row->fieldlist, TABLE_FIELD ); + serialize_table_idx( row->methodlist, TABLE_METHODDEF ); + row++; + } +} + static void build_table_stream( const statement_list_t *stmts ) { static const GUID guid = { 0x9ddc04c6, 0x04ca, 0x04cc, { 0x52, 0x85, 0x4b, 0x50, 0xb2, 0x60, 0x1d, 0xa8 } }; @@ -532,6 +591,7 @@ static void build_table_stream( const statement_list_t *stmts ) add_userstring( &space, sizeof(space) ); add_blob( NULL, 0 );
+ add_typedef_row( 0, add_string("<Module>"), 0, 0, 1, 1 ); add_module_row( add_string(metadata_name), add_guid(&guid) );
for (i = 0; i < TABLE_MAX; i++) if (tables[i].count) tables_header.valid |= (1ul << i); @@ -546,6 +606,7 @@ static void build_table_stream( const statement_list_t *stmts ) if (tables[i].count) add_bytes( &tables_disk, (const BYTE *)&tables[i].count, sizeof(tables[i].count) );
serialize_module_table(); + serialize_typedef_table(); }
static void build_streams( const statement_list_t *stmts )
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 4168e13b96b..049063ee531 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -500,6 +500,12 @@ static void serialize_guid_idx( UINT idx ) add_bytes( &tables_disk, (const BYTE *)&idx, size ); }
+static void serialize_blob_idx( UINT idx ) +{ + UINT size = blobs.offset >> 16 ? sizeof(UINT) : sizeof(USHORT); + add_bytes( &tables_disk, (const BYTE *)&idx, size ); +} + static void serialize_table_idx( UINT idx, enum table target ) { UINT size = tables[target].count >> 16 ? sizeof(UINT) : sizeof(USHORT); @@ -580,10 +586,47 @@ static void serialize_typedef_table( void ) } }
+struct assembly_row +{ + UINT hashalgid; + USHORT majorversion; + USHORT minorversion; + USHORT buildnumber; + USHORT revisionnumber; + UINT flags; + UINT publickey; + UINT name; + UINT culture; +}; + +static UINT add_assembly_row( UINT name ) +{ + struct assembly_row row = { 0x8004, 255, 255, 255, 255, 0x200, 0, name }; + return add_row( TABLE_ASSEMBLY, (const BYTE *)&row, sizeof(row) ); +} + +static void serialize_assembly_table( void ) +{ + const struct assembly_row *row = (const struct assembly_row *)tables[TABLE_ASSEMBLY].ptr; + + serialize_uint( row->hashalgid ); + serialize_ushort( row->majorversion ); + serialize_ushort( row->minorversion ); + serialize_ushort( row->buildnumber ); + serialize_ushort( row->revisionnumber ); + serialize_uint( row->flags ); + serialize_blob_idx( row->publickey ); + serialize_string_idx( row->name ); + serialize_string_idx( row->culture ); +} + +static char *assembly_name; + static void build_table_stream( const statement_list_t *stmts ) { static const GUID guid = { 0x9ddc04c6, 0x04ca, 0x04cc, { 0x52, 0x85, 0x4b, 0x50, 0xb2, 0x60, 0x1d, 0xa8 } }; static const USHORT space = 0x20; + char *ptr; UINT i;
add_string( "" ); @@ -591,7 +634,11 @@ static void build_table_stream( const statement_list_t *stmts ) add_userstring( &space, sizeof(space) ); add_blob( NULL, 0 );
+ assembly_name = xstrdup( metadata_name ); + if ((ptr = strrchr( assembly_name, '.' ))) *ptr = 0; + add_typedef_row( 0, add_string("<Module>"), 0, 0, 1, 1 ); + add_assembly_row( add_string(assembly_name) ); add_module_row( add_string(metadata_name), add_guid(&guid) );
for (i = 0; i < TABLE_MAX; i++) if (tables[i].count) tables_header.valid |= (1ul << i); @@ -607,6 +654,7 @@ static void build_table_stream( const statement_list_t *stmts )
serialize_module_table(); serialize_typedef_table(); + serialize_assembly_table(); }
static void build_streams( const statement_list_t *stmts )
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 049063ee531..6e1b5767378 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -620,11 +620,51 @@ static void serialize_assembly_table( void ) serialize_string_idx( row->culture ); }
+struct assemblyref_row +{ + USHORT majorversion; + USHORT minorversion; + USHORT buildnumber; + USHORT revisionnumber; + UINT flags; + UINT publickey; + UINT name; + UINT culture; + UINT hashvalue; +}; + +static UINT add_assemblyref_row( UINT flags, UINT publickey, UINT name ) +{ + struct assemblyref_row row = { 255, 255, 255, 255, flags, publickey, name }; + return add_row( TABLE_ASSEMBLYREF, (const BYTE *)&row, sizeof(row) ); +} + +static void serialize_assemblyref_table( void ) +{ + const struct assemblyref_row *row = (const struct assemblyref_row *)tables[TABLE_ASSEMBLYREF].ptr; + UINT i; + + for (i = 0; i < tables[TABLE_ASSEMBLYREF].count; i++) + { + serialize_ushort( row->majorversion ); + serialize_ushort( row->minorversion ); + serialize_ushort( row->buildnumber ); + serialize_ushort( row->revisionnumber ); + serialize_uint( row->flags ); + serialize_blob_idx( row->publickey ); + serialize_string_idx( row->name ); + serialize_string_idx( row->culture ); + serialize_blob_idx( row->hashvalue ); + row++; + } +} + static char *assembly_name;
static void build_table_stream( const statement_list_t *stmts ) { static const GUID guid = { 0x9ddc04c6, 0x04ca, 0x04cc, { 0x52, 0x85, 0x4b, 0x50, 0xb2, 0x60, 0x1d, 0xa8 } }; + static const BYTE token[] = { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 }; static const USHORT space = 0x20; char *ptr; UINT i; @@ -640,6 +680,7 @@ static void build_table_stream( const statement_list_t *stmts ) add_typedef_row( 0, add_string("<Module>"), 0, 0, 1, 1 ); add_assembly_row( add_string(assembly_name) ); add_module_row( add_string(metadata_name), add_guid(&guid) ); + add_assemblyref_row( 0, add_blob(token, sizeof(token)), add_string("mscorlib") );
for (i = 0; i < TABLE_MAX; i++) if (tables[i].count) tables_header.valid |= (1ul << i);
@@ -655,6 +696,7 @@ static void build_table_stream( const statement_list_t *stmts ) serialize_module_table(); serialize_typedef_table(); serialize_assembly_table(); + serialize_assemblyref_table(); }
static void build_streams( const statement_list_t *stmts )