2 * Typelib (SLTG) generation
4 * Copyright 2015,2016 Dmitry Timoshkov
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
35 #include "typelib_struct.h"
40 static const GUID sltg_library_guid
= { 0x204ff,0,0,{ 0xc0,0,0,0,0,0,0,0x46 } };
71 struct sltg_data index
;
72 struct sltg_data name_table
;
73 struct sltg_library library
;
74 struct sltg_block
*blocks
;
79 struct sltg_block
*typeinfo
;
83 struct sltg_typeinfo_header
94 unsigned unknown1
: 3;
96 unsigned unknown2
: 8;
97 unsigned typekind
: 8;
102 struct sltg_member_header
112 char magic
; /* 0x0a */
116 short byte_offs
; /* pos in struct, or offset to const type or const data (if flags & 0x08) */
117 short type
; /* if flags & 0x02 this is the type, else offset to type */
121 short varflags
; /* only present if magic & 0x20 */
129 short res06
; /* always 0000 */
130 short funcs_off
; /* offset to functions (starting from the member header) */
131 short vars_off
; /* offset to vars (starting from the member header) */
132 short impls_off
; /* offset to implemented types (starting from the member header) */
133 short funcs_bytes
; /* bytes used by function data */
134 short vars_bytes
; /* bytes used by var data */
135 short impls_bytes
; /* bytes used by implemented type data */
136 short tdescalias_vt
; /* for TKIND_ALIAS */
137 short res16
; /* always ffff */
138 short res18
; /* always 0000 */
139 short res1a
; /* always 0000 */
140 short simple_alias
; /* tdescalias_vt is a vt rather than an offset? */
141 short res1e
; /* always 0000 */
142 short cbSizeInstance
;
144 short res24
; /* always ffff */
145 short res26
; /* always ffff */
147 short res2a
; /* always ffff */
148 short res2c
; /* always ffff */
149 short res2e
; /* always ffff */
150 short res30
; /* always ffff */
151 short res32
; /* unknown */
152 short type_bytes
; /* bytes used by type descriptions */
156 static void init_sltg_data(struct sltg_data
*data
)
163 static int add_index(struct sltg_data
*index
, const char *name
)
165 int name_offset
= index
->size
;
166 int new_size
= index
->size
+ strlen(name
) + 1;
168 chat("add_index: name_offset %d, \"%s\"\n", name_offset
, name
);
170 if (new_size
> index
->allocated
)
172 index
->allocated
= index
->allocated
? max(index
->allocated
* 2, new_size
) : new_size
;
173 index
->data
= xrealloc(index
->data
, index
->allocated
);
176 strcpy(index
->data
+ index
->size
, name
);
177 index
->size
= new_size
;
182 static void init_index(struct sltg_data
*index
)
184 static const char compobj
[] = { 1,'C','o','m','p','O','b','j',0 };
186 init_sltg_data(index
);
188 add_index(index
, compobj
);
191 static int add_name(struct sltg_data
*name_table
, const char *name
)
193 int name_offset
= name_table
->size
;
194 int new_size
= name_table
->size
+ strlen(name
) + 1 + 8;
196 chat("add_name: %s\n", name
);
198 new_size
= (new_size
+ 1) & ~1; /* align */
200 if (new_size
> name_table
->allocated
)
202 name_table
->allocated
= name_table
->allocated
? max(name_table
->allocated
* 2, new_size
) : new_size
;
203 name_table
->data
= xrealloc(name_table
->data
, name_table
->allocated
);
206 memset(name_table
->data
+ name_table
->size
, 0xff, 8);
207 strcpy(name_table
->data
+ name_table
->size
+ 8, name
);
208 name_table
->size
= new_size
;
209 name_table
->data
[name_table
->size
- 1] = 0; /* clear alignment */
214 static void init_name_table(struct sltg_data
*name_table
)
216 init_sltg_data(name_table
);
219 static void init_library(struct sltg_typelib
*sltg
)
223 sltg
->library
.name
= add_name(&sltg
->name_table
, sltg
->typelib
->name
);
224 sltg
->library
.helpstring
= NULL
;
225 sltg
->library
.helpcontext
= 0;
226 sltg
->library
.syskind
= SYS_WIN32
;
227 sltg
->library
.lcid
= 0x0409;
228 sltg
->library
.libflags
= 0;
229 sltg
->library
.version
= 0;
230 sltg
->library
.helpfile
= NULL
;
231 memset(&sltg
->library
.uuid
, 0, sizeof(sltg
->library
.uuid
));
233 if (!sltg
->typelib
->attrs
) return;
235 LIST_FOR_EACH_ENTRY(attr
, sltg
->typelib
->attrs
, const attr_t
, entry
)
242 sltg
->library
.version
= attr
->u
.ival
;
244 case ATTR_HELPSTRING
:
245 sltg
->library
.helpstring
= attr
->u
.pval
;
248 sltg
->library
.helpfile
= attr
->u
.pval
;
251 sltg
->library
.uuid
= *(GUID
*)attr
->u
.pval
;
253 case ATTR_HELPCONTEXT
:
255 sltg
->library
.helpcontext
= expr
->cval
;
259 sltg
->library
.lcid
= expr
->cval
;
262 sltg
->library
.libflags
|= 0x02; /* LIBFLAG_FCONTROL */
265 sltg
->library
.libflags
|= 0x04; /* LIBFLAG_FHIDDEN */
267 case ATTR_RESTRICTED
:
268 sltg
->library
.libflags
|= 0x01; /* LIBFLAG_FRESTRICTED */
276 static void add_block(struct sltg_typelib
*sltg
, void *data
, int length
, const char *name
)
278 chat("add_block: %p,%d,\"%s\"\n", data
, length
, name
);
280 sltg
->blocks
= xrealloc(sltg
->blocks
, sizeof(sltg
->blocks
[0]) * (sltg
->block_count
+ 1));
281 sltg
->blocks
[sltg
->block_count
].length
= length
;
282 sltg
->blocks
[sltg
->block_count
].data
= data
;
283 sltg
->blocks
[sltg
->block_count
].index_string
= add_index(&sltg
->index
, name
);
287 static void add_library_block(struct sltg_typelib
*typelib
)
293 size
= sizeof(short) * 9 + sizeof(int) * 3 + sizeof(GUID
);
294 if (typelib
->library
.helpstring
) size
+= strlen(typelib
->library
.helpstring
);
295 if (typelib
->library
.helpfile
) size
+= strlen(typelib
->library
.helpfile
);
297 block
= xmalloc(size
);
299 *p
++ = 0x51cc; /* magic */
300 *p
++ = 3; /* res02 */
301 *p
++ = typelib
->library
.name
;
302 *p
++ = 0xffff; /* res06 */
303 if (typelib
->library
.helpstring
)
305 *p
++ = strlen(typelib
->library
.helpstring
);
306 strcpy((char *)p
, typelib
->library
.helpstring
);
307 p
= (short *)((char *)p
+ strlen(typelib
->library
.helpstring
));
311 if (typelib
->library
.helpfile
)
313 *p
++ = strlen(typelib
->library
.helpfile
);
314 strcpy((char *)p
, typelib
->library
.helpfile
);
315 p
= (short *)((char *)p
+ strlen(typelib
->library
.helpfile
));
319 *(int *)p
= typelib
->library
.helpcontext
;
321 *p
++ = typelib
->library
.syskind
;
322 *p
++ = typelib
->library
.lcid
;
323 *(int *)p
= 0; /* res12 */
325 *p
++ = typelib
->library
.libflags
;
326 *(int *)p
= typelib
->library
.version
;
328 *(GUID
*)p
= typelib
->library
.uuid
;
330 add_block(typelib
, block
, size
, "dir");
333 static const char *new_index_name(void)
335 static char name
[11] = "AAAAAAAAAA";
339 if (name
[pos
] == 'Z')
343 error("too many index names\n");
348 new_name
= xmalloc(sizeof(name
));
349 strcpy(new_name
, name
);
353 static void sltg_add_typeinfo(struct sltg_typelib
*sltg
, void *data
, int length
, const char *name
)
355 chat("sltg_add_typeinfo: %p,%d,%s\n", data
, length
, name
);
357 sltg
->typeinfo
= xrealloc(sltg
->typeinfo
, sizeof(sltg
->typeinfo
[0]) * (sltg
->typeinfo_count
+ 1));
358 sltg
->typeinfo
[sltg
->typeinfo_count
].length
= length
;
359 sltg
->typeinfo
[sltg
->typeinfo_count
].data
= data
;
360 sltg
->typeinfo
[sltg
->typeinfo_count
].index_string
= 0;
361 sltg
->typeinfo_count
++;
362 sltg
->typeinfo_size
+= length
;
365 static void append_data(struct sltg_data
*block
, const void *data
, int size
)
367 int new_size
= block
->size
+ size
;
369 if (new_size
> block
->allocated
)
371 block
->allocated
= max(block
->allocated
* 2, new_size
);
372 block
->data
= xrealloc(block
->data
, block
->allocated
);
375 memcpy(block
->data
+ block
->size
, data
, size
);
376 block
->size
= new_size
;
379 static void add_typedef_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
381 error("add_typedef_typeinfo: %s not implemented\n", type
->name
);
384 static void add_module_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
386 error("add_module_typeinfo: %s not implemented\n", type
->name
);
389 static void add_interface_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
391 error("add_interface_typeinfo: %s not implemented\n", type
->name
);
394 static const char *add_typeinfo_block(struct sltg_typelib
*typelib
, const type_t
*type
, short kind
)
396 struct sltg_data block
;
397 const char *index_name
, *other_name
;
404 index_name
= new_index_name();
405 other_name
= new_index_name();
407 expr
= get_attrp(type
->attrs
, ATTR_HELPCONTEXT
);
408 if (expr
) helpcontext
= expr
->cval
;
410 p
= get_attrp(type
->attrs
, ATTR_UUID
);
411 if (p
) guid
= *(GUID
*)p
;
413 init_sltg_data(&block
);
415 val
= strlen(index_name
);
416 append_data(&block
, &val
, sizeof(val
));
417 append_data(&block
, index_name
, val
);
418 val
= strlen(other_name
);
419 append_data(&block
, &val
, sizeof(val
));
420 append_data(&block
, other_name
, val
);
421 val
= -1; /* res1a */
422 append_data(&block
, &val
, sizeof(val
));
423 val
= add_name(&typelib
->name_table
, type
->name
); /* name offset */
424 append_data(&block
, &val
, sizeof(val
));
425 val
= 0; /* FIXME: helpstring */
426 append_data(&block
, &val
, sizeof(val
));
427 val
= -1; /* res20 */
428 append_data(&block
, &val
, sizeof(val
));
429 append_data(&block
, &helpcontext
, sizeof(helpcontext
));
430 val
= -1; /* res26 */
431 append_data(&block
, &val
, sizeof(val
));
432 append_data(&block
, &guid
, sizeof(guid
));
433 append_data(&block
, &kind
, sizeof(kind
));
435 sltg_add_typeinfo(typelib
, block
.data
, block
.size
, index_name
);
440 static void init_typeinfo(struct sltg_typeinfo_header
*ti
, const type_t
*type
, int kind
)
443 ti
->href_offset
= -1;
445 ti
->member_offset
= sizeof(*ti
);
447 ti
->version
= get_attrv(type
->attrs
, ATTR_VERSION
);
448 ti
->res16
= 0xfffe0000;
449 ti
->misc
.unknown1
= 0x02;
450 ti
->misc
.flags
= 0; /* FIXME */
451 ti
->misc
.unknown2
= 0x02;
452 ti
->misc
.typekind
= kind
;
456 static void dump_var_desc(const char *data
, int size
)
458 const unsigned char *p
= (const unsigned char *)data
;
461 if (!(debuglevel
& (DEBUGLEVEL_TRACE
| DEBUGLEVEL_CHAT
))) return;
463 chat("dump_var_desc: size %d bytes\n", size
);
465 for (i
= 0; i
< size
; i
++)
466 fprintf(stderr
, " %02x", *p
++);
468 fprintf(stderr
, "\n");
471 static int get_element_size(type_t
*type
)
473 int vt
= get_type_vt(type
);
520 error("get_element_size: unrecognized vt %d\n", vt
);
527 static short write_var_desc(struct sltg_data
*data
, type_t
*type
, short flags
, short base_offset
, int *size_instance
)
529 short vt
, desc_offset
;
531 chat("write_var_desc: type %p, type->name %s\n",
532 type
, type
->name
? type
->name
: "NULL");
534 if (is_array(type
) && !type_array_is_decl_as_ptr(type
))
536 int num_dims
, elements
, array_start
, size
, array_size
;
555 while (is_array(atype
) && !type_array_is_decl_as_ptr(atype
))
558 elements
*= type_array_get_dim(atype
);
560 atype
= type_array_get_element_type(atype
);
563 chat("write_var_desc: VT_CARRAY: %d dimensions, %d elements\n", num_dims
, elements
);
565 array_start
= data
->size
;
567 size
= sizeof(*array
) + (num_dims
- 1) * 8 /* sizeof(SAFEARRAYBOUND) */;
568 array
= xmalloc(size
);
570 array
->cDims
= num_dims
;
571 array
->fFeatures
= 0x0004; /* FADF_EMBEDDED */
572 array
->cbElements
= get_element_size(atype
);
576 bound
= array
->bound
;
578 array_size
= array
->cbElements
;
581 while (is_array(atype
) && !type_array_is_decl_as_ptr(atype
))
583 bound
[0] = type_array_get_dim(atype
);
584 array_size
*= bound
[0];
588 atype
= type_array_get_element_type(atype
);
591 *size_instance
+= array_size
;
592 size_instance
= NULL
; /* don't account for element size */
594 append_data(data
, array
, size
);
596 desc_offset
= data
->size
;
598 vt_off
[0] = VT_CARRAY
;
599 vt_off
[1] = array_start
+ base_offset
;
600 append_data(data
, vt_off
, sizeof(vt_off
));
602 /* fall through to write array element description */
606 desc_offset
= data
->size
;
608 vt
= get_type_vt(type
);
612 type_t
*ref
= is_ptr(type
) ? type_pointer_get_ref_type(type
) : type_array_get_element_type(type
);
616 chat("write_var_desc: vt VT_PTR | 0x0400\n");
617 vt
= VT_PTR
| 0x0400;
618 append_data(data
, &vt
, sizeof(vt
));
619 write_var_desc(data
, ref
, 0, base_offset
, size_instance
);
622 write_var_desc(data
, ref
, 0x0e00, base_offset
, size_instance
);
626 chat("write_var_desc: vt %d, flags %04x\n", vt
, flags
);
629 *size_instance
+= get_element_size(type
);
632 append_data(data
, &vt
, sizeof(vt
));
637 static void init_sltg_tail(struct sltg_tail
*tail
)
641 tail
->cImplTypes
= 0;
643 tail
->funcs_off
= -1;
645 tail
->impls_off
= -1;
646 tail
->funcs_bytes
= -1;
647 tail
->vars_bytes
= 0;
648 tail
->impls_bytes
= -1;
649 tail
->tdescalias_vt
= -1;
653 tail
->simple_alias
= 0;
655 tail
->cbSizeInstance
= 0;
656 tail
->cbAlignment
= 4;
665 tail
->type_bytes
= 0;
668 static void add_structure_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
670 struct sltg_data data
, *var_data
= NULL
;
671 const char *index_name
;
672 struct sltg_typeinfo_header ti
;
673 struct sltg_member_header member
;
674 struct sltg_tail tail
;
675 int member_offset
, var_count
= 0, var_data_size
= 0, size_instance
= 0;
676 short *type_desc_offset
= NULL
;
678 chat("add_structure_typeinfo: %s\n", type
->name
);
680 init_sltg_data(&data
);
682 index_name
= add_typeinfo_block(typelib
, type
, TKIND_RECORD
);
684 init_typeinfo(&ti
, type
, TKIND_RECORD
);
685 append_data(&data
, &ti
, sizeof(ti
));
687 if (type_struct_get_fields(type
))
692 var_count
= list_count(type_struct_get_fields(type
));
694 var_data
= xmalloc(var_count
* sizeof(*var_data
));
695 type_desc_offset
= xmalloc(var_count
* sizeof(*type_desc_offset
));
697 LIST_FOR_EACH_ENTRY(var
, type_struct_get_fields(type
), var_t
, entry
)
701 chat("add_structure_typeinfo: var %p, name %s, type %p\n",
702 var
, var
->name
, var
->declspec
.type
);
704 init_sltg_data(&var_data
[i
]);
706 base_offset
= var_data_size
+ (i
+ 1) * sizeof(struct sltg_variable
);
707 type_desc_offset
[i
] = write_var_desc(&var_data
[i
], var
->declspec
.type
, 0, base_offset
, &size_instance
);
708 dump_var_desc(var_data
[i
].data
, var_data
[i
].size
);
710 if (var_data
[i
].size
> sizeof(short))
711 var_data_size
+= var_data
[i
].size
;
716 member_offset
= data
.size
;
718 member
.res00
= 0x0001;
719 member
.res02
= 0xffff;
721 member
.extra
= var_data_size
+ var_count
* sizeof(struct sltg_variable
);
722 append_data(&data
, &member
, sizeof(member
));
726 if (type_struct_get_fields(type
))
729 short next
= member_offset
;
732 LIST_FOR_EACH_ENTRY(var
, type_struct_get_fields(type
), var_t
, entry
)
734 struct sltg_variable variable
;
736 next
+= sizeof(variable
);
738 variable
.magic
= 0x2a; /* always write flags to simplify calculations */
739 variable
.name
= add_name(&typelib
->name_table
, var
->name
);
740 variable
.byte_offs
= 0;
741 if (var_data
[i
].size
> sizeof(short))
744 var_data_size
= next
- member_offset
+ type_desc_offset
[i
];
745 variable
.type
= var_data_size
;
746 next
+= var_data
[i
].size
;
750 variable
.flags
= 0x02;
751 variable
.type
= *(short *)var_data
[i
].data
;
753 variable
.next
= i
< var_count
- 1 ? next
- member_offset
: -1;
754 variable
.memid
= 0x40000000 + i
;
755 variable
.helpcontext
= -2; /* 0xfffe */
756 variable
.helpstring
= -1;
757 variable
.varflags
= 0;
759 append_data(&data
, &variable
, sizeof(variable
));
760 if (var_data
[i
].size
> sizeof(short))
761 append_data(&data
, var_data
[i
].data
, var_data
[i
].size
);
767 init_sltg_tail(&tail
);
768 tail
.cVars
= var_count
;
769 tail
.vars_bytes
= var_data_size
;
770 tail
.cbSizeInstance
= size_instance
;
771 tail
.type_bytes
= data
.size
- member_offset
- sizeof(member
);
772 append_data(&data
, &tail
, sizeof(tail
));
774 add_block(typelib
, data
.data
, data
.size
, index_name
);
777 static void add_enum_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
779 error("add_enum_typeinfo: %s not implemented\n", type
->name
);
782 static void add_union_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
784 error("add_union_typeinfo: %s not implemented\n", type
->name
);
787 static void add_coclass_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
789 error("add_coclass_typeinfo: %s not implemented\n", type
->name
);
792 static void add_type_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
794 chat("add_type_typeinfo: adding %s, type %d\n", type
->name
, type_get_type(type
));
796 switch (type_get_type(type
))
799 add_interface_typeinfo(typelib
, type
);
802 add_structure_typeinfo(typelib
, type
);
805 add_enum_typeinfo(typelib
, type
);
808 add_union_typeinfo(typelib
, type
);
811 add_coclass_typeinfo(typelib
, type
);
817 error("add_type_typeinfo: unhandled type %d for %s\n", type_get_type(type
), type
->name
);
822 static void add_statement(struct sltg_typelib
*typelib
, const statement_t
*stmt
)
830 case STMT_DECLARATION
:
831 /* not included in typelib */
834 /* not processed here */
841 if (!stmt
->u
.type_list
)
844 LIST_FOR_EACH_ENTRY(ref
, stmt
->u
.type_list
, typeref_t
, entry
)
846 /* if the type is public then add the typedef, otherwise attempt
847 * to add the aliased type */
848 if (is_attr(ref
->type
->attrs
, ATTR_PUBLIC
))
849 add_typedef_typeinfo(typelib
, ref
->type
);
851 add_type_typeinfo(typelib
, type_alias_get_aliasee_type(ref
->type
));
857 add_module_typeinfo(typelib
, stmt
->u
.type
);
863 type_t
*type
= stmt
->u
.type
;
864 add_type_typeinfo(typelib
, type
);
869 error("add_statement: unhandled statement type %d\n", stmt
->type
);
874 static void sltg_write_header(struct sltg_typelib
*sltg
, int *library_block_start
)
888 struct sltg_block_entry
896 header
.magic
= 0x47544c53;
897 header
.block_count
= sltg
->block_count
+ 1; /* 1-based */
899 header
.size_of_index
= sltg
->index
.size
;
900 header
.first_blk
= 1; /* 1-based */
901 header
.uuid
= sltg_library_guid
;
902 header
.res1c
= 0x00000044;
903 header
.res20
= 0xffff0000;
905 put_data(&header
, sizeof(header
));
907 /* library block is written separately */
908 for (i
= 0; i
< sltg
->block_count
- 1; i
++)
910 entry
.length
= sltg
->blocks
[i
].length
;
911 entry
.index_string
= sltg
->blocks
[i
].index_string
;
912 entry
.next
= header
.first_blk
+ i
+ 1; /* point to next block */
913 chat("sltg_write_header: writing block entry %d: length %#x, index_string %#x, next %#x\n",
914 i
, entry
.length
, entry
.index_string
, entry
.next
);
915 put_data(&entry
, sizeof(entry
));
918 /* library block length includes helpstrings and name table */
919 entry
.length
= sltg
->blocks
[sltg
->block_count
- 1].length
+ 0x40 /* pad after library block */ +
920 sizeof(sltg
->typeinfo_count
) + sltg
->typeinfo_size
+ 4 /* library block offset */ + 6 /* dummy help strings */ +
921 12 /* name table header */ + 0x200 /* name table hash */ + sltg
->name_table
.size
;
922 entry
.index_string
= sltg
->blocks
[sltg
->block_count
- 1].index_string
;
924 chat("sltg_write_header: writing library block entry %d: length %#x, index_string %#x, next %#x\n",
925 i
, entry
.length
, entry
.index_string
, entry
.next
);
926 put_data(&entry
, sizeof(entry
));
928 chat("sltg_write_header: writing index: %d bytes\n", sltg
->index
.size
);
929 put_data(sltg
->index
.data
, sltg
->index
.size
);
933 /* library block is written separately */
934 for (i
= 0; i
< sltg
->block_count
- 1; i
++)
936 chat("sltg_write_header: writing block %d: %d bytes\n", i
, sltg
->blocks
[i
].length
);
937 put_data(sltg
->blocks
[i
].data
, sltg
->blocks
[i
].length
);
941 chat("library_block_start = %#x\n", (int)output_buffer_pos
);
942 *library_block_start
= output_buffer_pos
;
943 chat("sltg_write_header: writing library block %d: %d bytes\n", i
, sltg
->blocks
[i
].length
);
944 put_data(sltg
->blocks
[sltg
->block_count
- 1].data
, sltg
->blocks
[sltg
->block_count
- 1].length
);
946 chat("sltg_write_header: writing pad 0x40 bytes\n");
947 memset(pad
, 0xff, 0x40);
951 static void sltg_write_typeinfo(struct sltg_typelib
*typelib
)
955 put_data(&typelib
->typeinfo_count
, sizeof(typelib
->typeinfo_count
));
957 for (i
= 0; i
< typelib
->typeinfo_count
; i
++)
959 chat("sltg_write_typeinfo: writing block %d: %d bytes\n", i
, typelib
->typeinfo
[i
].length
);
960 put_data(typelib
->typeinfo
[i
].data
, typelib
->typeinfo
[i
].length
);
964 static void sltg_write_helpstrings(struct sltg_typelib
*typelib
)
966 static const char dummy
[6];
968 chat("sltg_write_helpstrings: writing dummy 6 bytes\n");
970 put_data(dummy
, sizeof(dummy
));
973 static void sltg_write_nametable(struct sltg_typelib
*typelib
)
975 static const short dummy
[6] = { 0xffff,1,2,0xff00,0xffff,0xffff };
978 chat("sltg_write_nametable: writing 12+0x200+%d bytes\n", typelib
->name_table
.size
);
980 put_data(dummy
, sizeof(dummy
));
981 memset(pad
, 0xff, 0x200);
982 put_data(pad
, 0x200);
983 put_data(&typelib
->name_table
.size
, sizeof(typelib
->name_table
.size
));
984 put_data(typelib
->name_table
.data
, typelib
->name_table
.size
);
987 static void sltg_write_remainder(void)
989 static const short dummy1
[] = { 1,0xfffe,0x0a03,0,0xffff,0xffff };
990 static const short dummy2
[] = { 0xffff,0xffff,0x0200,0,0,0 };
991 static const char dummy3
[] = { 0xf4,0x39,0xb2,0x71,0,0,0,0,0,0,0,0,0,0,0,0 };
992 static const char TYPELIB
[] = { 8,0,0,0,'T','Y','P','E','L','I','B',0 };
996 put_data(&pad
, sizeof(pad
));
998 put_data(&pad
, sizeof(pad
));
1000 put_data(dummy1
, sizeof(dummy1
));
1002 put_data(&sltg_library_guid
, sizeof(sltg_library_guid
));
1004 put_data(TYPELIB
, sizeof(TYPELIB
));
1006 put_data(dummy2
, sizeof(dummy2
));
1007 put_data(dummy3
, sizeof(dummy3
));
1010 static void save_all_changes(struct sltg_typelib
*typelib
)
1012 int library_block_start
;
1013 int *name_table_offset
;
1015 sltg_write_header(typelib
, &library_block_start
);
1016 sltg_write_typeinfo(typelib
);
1018 name_table_offset
= (int *)(output_buffer
+ output_buffer_pos
);
1019 chat("name_table_offset = %#x\n", (int)output_buffer_pos
);
1020 put_data(&library_block_start
, sizeof(library_block_start
));
1022 sltg_write_helpstrings(typelib
);
1024 *name_table_offset
= output_buffer_pos
- library_block_start
;
1025 chat("*name_table_offset = %#x\n", *name_table_offset
);
1027 sltg_write_nametable(typelib
);
1028 sltg_write_remainder();
1030 if (strendswith(typelib_name
, ".res")) /* create a binary resource file */
1032 char typelib_id
[13] = "#1";
1034 expr_t
*expr
= get_attrp(typelib
->typelib
->attrs
, ATTR_ID
);
1036 sprintf(typelib_id
, "#%d", expr
->cval
);
1037 add_output_to_resources("TYPELIB", typelib_id
);
1038 if (strendswith(typelib_name
, "_t.res")) /* add typelib registration */
1039 output_typelib_regscript(typelib
->typelib
);
1041 else flush_output_buffer(typelib_name
);
1044 int create_sltg_typelib(typelib_t
*typelib
)
1046 struct sltg_typelib sltg
;
1047 const statement_t
*stmt
;
1049 if (pointer_size
!= 4)
1050 error("Only 32-bit platform is supported\n");
1052 sltg
.typelib
= typelib
;
1053 sltg
.typeinfo_count
= 0;
1054 sltg
.typeinfo_size
= 0;
1055 sltg
.typeinfo
= NULL
;
1057 sltg
.block_count
= 0;
1058 sltg
.first_block
= 1;
1060 init_index(&sltg
.index
);
1061 init_name_table(&sltg
.name_table
);
1062 init_library(&sltg
);
1064 add_library_block(&sltg
);
1067 LIST_FOR_EACH_ENTRY(stmt
, typelib
->stmts
, const statement_t
, entry
)
1068 add_statement(&sltg
, stmt
);
1070 save_all_changes(&sltg
);