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
22 #include "wine/port.h"
31 #define NONAMELESSUNION
43 #include "typelib_struct.h"
48 static const GUID sltg_library_guid
= { 0x204ff,0,0,{ 0xc0,0,0,0,0,0,0,0x46 } };
74 struct sltg_block
*next
;
80 struct sltg_data index
;
81 struct sltg_data name_table
;
82 struct sltg_library library
;
83 struct sltg_block
*blocks
;
88 struct sltg_block
*typeinfo
;
98 struct sltg_typeinfo_header
109 unsigned unknown1
: 3;
111 unsigned unknown2
: 8;
112 unsigned typekind
: 8;
117 struct sltg_member_header
127 char magic
; /* 0x0a */
131 short byte_offs
; /* pos in struct, or offset to const type or const data (if flags & 0x08) */
132 short type
; /* if flags & 0x02 this is the type, else offset to type */
136 short varflags
; /* only present if magic & 0x02 */
144 short res06
; /* always 0000 */
145 short funcs_off
; /* offset to functions (starting from the member header) */
146 short vars_off
; /* offset to vars (starting from the member header) */
147 short impls_off
; /* offset to implemented types (starting from the member header) */
148 short funcs_bytes
; /* bytes used by function data */
149 short vars_bytes
; /* bytes used by var data */
150 short impls_bytes
; /* bytes used by implemented type data */
151 short tdescalias_vt
; /* for TKIND_ALIAS */
152 short res16
; /* always ffff */
153 short res18
; /* always 0000 */
154 short res1a
; /* always 0000 */
155 short simple_alias
; /* tdescalias_vt is a vt rather than an offset? */
156 short res1e
; /* always 0000 */
157 short cbSizeInstance
;
162 short res2a
; /* always ffff */
163 short res2c
; /* always ffff */
164 short res2e
; /* always ffff */
165 short res30
; /* always ffff */
166 short res32
; /* unknown */
167 short type_bytes
; /* bytes used by type descriptions */
172 char magic
; /* 0xdf */
173 char res01
; /* 0x00 */
174 int res02
; /* 0xffffffff */
175 int res06
; /* 0xffffffff */
176 int res0a
; /* 0xffffffff */
177 int res0e
; /* 0xffffffff */
178 int res12
; /* 0xffffffff */
179 int res16
; /* 0xffffffff */
180 int res1a
; /* 0xffffffff */
181 int res1e
; /* 0xffffffff */
182 int res22
; /* 0xffffffff */
183 int res26
; /* 0xffffffff */
184 int res2a
; /* 0xffffffff */
185 int res2e
; /* 0xffffffff */
186 int res32
; /* 0xffffffff */
187 int res36
; /* 0xffffffff */
188 int res3a
; /* 0xffffffff */
189 int res3e
; /* 0xffffffff */
190 short res42
;/* 0xffff */
191 int number
; /* this is 8 times the number of refs */
192 /* Now we have number bytes (8 for each ref) of SLTG_UnknownRefInfo */
194 short res50
;/* 0xffff */
195 char res52
; /* 0x01 */
196 int res53
; /* 0x00000000 */
197 /* Now we have number/8 SLTG_Names (first WORD is no of bytes in the ascii
198 * string). Strings look like "*\Rxxxx*#n". If xxxx == ffff then the
199 * ref refers to the nth type listed in this library (0 based). Else
200 * the xxxx (which maybe fewer than 4 digits) is the offset into the name
201 * table to a string "*\G{<guid>}#1.0#0#C:\WINNT\System32\stdole32.tlb#"
202 * The guid is the typelib guid; the ref again refers to the nth type of
203 * the imported typelib.
206 char resxx
; /* 0xdf */
211 char magic
; /* 0x4c, 0xcb or 0x8b with optional SLTG_FUNCTION_FLAGS_PRESENT flag */
212 char flags
; /* high nibble is INVOKE_KIND, low nibble = 2 */
213 short next
; /* byte offset from beginning of group to next fn */
214 short name
; /* Offset within name table to name */
215 int dispid
; /* dispid */
216 short helpcontext
; /* helpcontext (again 1 is special) */
217 short helpstring
; /* helpstring offset to offset */
218 short arg_off
; /* offset to args from start of block */
219 char nacc
; /* lowest 3bits are CALLCONV, rest are no of args */
220 char retnextopt
; /* if 0x80 bit set ret type follows else next WORD
221 is offset to ret type. No of optional args is
223 short rettype
; /* return type VT_?? or offset to ret type */
224 short vtblpos
; /* position in vtbl? */
225 short funcflags
; /* present if magic & 0x20 */
226 /* Param list starts, repeat next two as required */
228 WORD name
; /* offset to 2nd letter of name */
229 WORD
+ type
; /* VT_ of param */
233 struct sltg_impl_info
251 static void add_structure_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
);
252 static void add_interface_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
);
253 static void add_enum_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
);
254 static void add_union_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
);
255 static void add_coclass_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
);
257 static void init_sltg_data(struct sltg_data
*data
)
260 data
->allocated
= 0x10;
261 data
->data
= xmalloc(0x10);
264 static int add_index(struct sltg_data
*index
, const char *name
)
266 int name_offset
= index
->size
;
267 int new_size
= index
->size
+ strlen(name
) + 1;
269 chat("add_index: name_offset %d, \"%s\"\n", name_offset
, name
);
271 if (new_size
> index
->allocated
)
273 index
->allocated
= max(index
->allocated
* 2, new_size
);
274 index
->data
= xrealloc(index
->data
, index
->allocated
);
277 strcpy(index
->data
+ index
->size
, name
);
278 index
->size
= new_size
;
283 static void init_index(struct sltg_data
*index
)
285 static const char compobj
[] = { 1,'C','o','m','p','O','b','j',0 };
287 init_sltg_data(index
);
289 add_index(index
, compobj
);
292 static int add_name(struct sltg_typelib
*sltg
, const char *name
)
294 int name_offset
= sltg
->name_table
.size
;
295 int new_size
= sltg
->name_table
.size
+ strlen(name
) + 1 + 8;
298 chat("add_name: %s\n", name
);
300 aligned_size
= (new_size
+ 0x1f) & ~0x1f;
301 if (aligned_size
- new_size
< 4)
302 new_size
= aligned_size
;
304 new_size
= (new_size
+ 1) & ~1;
306 if (new_size
> sltg
->name_table
.allocated
)
308 sltg
->name_table
.allocated
= max(sltg
->name_table
.allocated
* 2, new_size
);
309 sltg
->name_table
.data
= xrealloc(sltg
->name_table
.data
, sltg
->name_table
.allocated
);
312 memset(sltg
->name_table
.data
+ sltg
->name_table
.size
, 0xff, 8);
313 strcpy(sltg
->name_table
.data
+ sltg
->name_table
.size
+ 8, name
);
314 sltg
->name_table
.size
= new_size
;
315 sltg
->name_table
.data
[sltg
->name_table
.size
- 1] = 0; /* clear alignment */
320 static void init_name_table(struct sltg_typelib
*sltg
)
322 init_sltg_data(&sltg
->name_table
);
325 static void init_library(struct sltg_typelib
*sltg
)
329 sltg
->library
.name
= add_name(sltg
, sltg
->typelib
->name
);
330 sltg
->library
.helpstring
= NULL
;
331 sltg
->library
.helpcontext
= 0;
332 sltg
->library
.syskind
= (pointer_size
== 8) ? SYS_WIN64
: SYS_WIN32
;
333 sltg
->library
.lcid
= 0x0409;
334 sltg
->library
.libflags
= 0;
335 sltg
->library
.version
= 0;
336 sltg
->library
.helpfile
= NULL
;
337 memset(&sltg
->library
.uuid
, 0, sizeof(sltg
->library
.uuid
));
339 if (!sltg
->typelib
->attrs
) return;
341 LIST_FOR_EACH_ENTRY(attr
, sltg
->typelib
->attrs
, const attr_t
, entry
)
348 sltg
->library
.version
= attr
->u
.ival
;
350 case ATTR_HELPSTRING
:
351 sltg
->library
.helpstring
= attr
->u
.pval
;
354 sltg
->library
.helpfile
= attr
->u
.pval
;
357 sltg
->library
.uuid
= *(GUID
*)attr
->u
.pval
;
359 case ATTR_HELPCONTEXT
:
361 sltg
->library
.helpcontext
= expr
->cval
;
365 sltg
->library
.lcid
= expr
->cval
;
368 sltg
->library
.libflags
|= 0x02; /* LIBFLAG_FCONTROL */
371 sltg
->library
.libflags
|= 0x04; /* LIBFLAG_FHIDDEN */
373 case ATTR_RESTRICTED
:
374 sltg
->library
.libflags
|= 0x01; /* LIBFLAG_FRESTRICTED */
382 static void add_block_index(struct sltg_typelib
*sltg
, void *data
, int size
, int index
)
384 struct sltg_block
*block
= xmalloc(sizeof(*block
));
386 block
->length
= size
;
388 block
->index_string
= index
;
393 struct sltg_block
*blocks
= sltg
->blocks
;
396 blocks
= blocks
->next
;
398 blocks
->next
= block
;
401 sltg
->blocks
= block
;
403 sltg
->n_file_blocks
++;
406 static void add_block(struct sltg_typelib
*sltg
, void *data
, int size
, const char *name
)
408 struct sltg_block
*block
= xmalloc(sizeof(*block
));
411 chat("add_block: %p,%d,\"%s\"\n", data
, size
, name
);
413 index
= add_index(&sltg
->index
, name
);
415 add_block_index(sltg
, data
, size
, index
);
418 static void *create_library_block(struct sltg_typelib
*typelib
, int *size
, int *index
)
423 *size
= sizeof(short) * 9 + sizeof(int) * 3 + sizeof(GUID
);
424 if (typelib
->library
.helpstring
) *size
+= strlen(typelib
->library
.helpstring
);
425 if (typelib
->library
.helpfile
) *size
+= strlen(typelib
->library
.helpfile
);
427 block
= xmalloc(*size
);
429 *p
++ = 0x51cc; /* magic */
430 *p
++ = 3; /* res02 */
431 *p
++ = typelib
->library
.name
;
432 *p
++ = 0xffff; /* res06 */
433 if (typelib
->library
.helpstring
)
435 *p
++ = strlen(typelib
->library
.helpstring
);
436 strcpy((char *)p
, typelib
->library
.helpstring
);
437 p
= (short *)((char *)p
+ strlen(typelib
->library
.helpstring
));
441 if (typelib
->library
.helpfile
)
443 *p
++ = strlen(typelib
->library
.helpfile
);
444 strcpy((char *)p
, typelib
->library
.helpfile
);
445 p
= (short *)((char *)p
+ strlen(typelib
->library
.helpfile
));
449 *(int *)p
= typelib
->library
.helpcontext
;
451 *p
++ = typelib
->library
.syskind
;
452 *p
++ = typelib
->library
.lcid
;
453 *(int *)p
= 0; /* res12 */
455 *p
++ = typelib
->library
.libflags
;
456 *(int *)p
= typelib
->library
.version
;
458 *(GUID
*)p
= typelib
->library
.uuid
;
460 *index
= add_index(&typelib
->index
, "dir");
465 static const char *new_index_name(void)
467 static char name
[11] = "0000000000";
471 if (name
[pos
] == 'Z')
475 error("too many index names\n");
480 new_name
= xmalloc(sizeof(name
));
481 strcpy(new_name
, name
);
485 static void sltg_add_typeinfo(struct sltg_typelib
*sltg
, void *data
, int size
, const char *name
)
487 struct sltg_block
*block
= xmalloc(sizeof(*block
));
489 chat("sltg_add_typeinfo: %p,%d,%s\n", data
, size
, name
);
491 block
->length
= size
;
493 block
->index_string
= 0;
498 struct sltg_block
*typeinfo
= sltg
->typeinfo
;
500 while (typeinfo
->next
)
501 typeinfo
= typeinfo
->next
;
503 typeinfo
->next
= block
;
506 sltg
->typeinfo
= block
;
508 sltg
->typeinfo_count
++;
509 sltg
->typeinfo_size
+= size
;
512 static void append_data(struct sltg_data
*block
, const void *data
, int size
)
514 int new_size
= block
->size
+ size
;
516 if (new_size
> block
->allocated
)
518 block
->allocated
= max(block
->allocated
* 2, new_size
);
519 block
->data
= xrealloc(block
->data
, block
->allocated
);
522 memcpy(block
->data
+ block
->size
, data
, size
);
523 block
->size
= new_size
;
526 static void add_module_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
528 error("add_module_typeinfo: %s not implemented\n", type
->name
);
531 static const char *add_typeinfo_block(struct sltg_typelib
*typelib
, const type_t
*type
, int kind
)
533 const char *index_name
, *other_name
;
536 int size
, helpcontext
= 0;
540 index_name
= new_index_name();
541 other_name
= new_index_name();
543 expr
= get_attrp(type
->attrs
, ATTR_HELPCONTEXT
);
544 if (expr
) helpcontext
= expr
->cval
;
546 p
= get_attrp(type
->attrs
, ATTR_UUID
);
547 if (p
) guid
= *(GUID
*)p
;
549 size
= sizeof(short) * 8 + 10 /* index_name */ * 2 + sizeof(int) + sizeof(GUID
);
551 block
= xmalloc(size
);
553 *p
++ = strlen(index_name
);
554 strcpy((char *)p
, index_name
);
555 p
= (short *)((char *)p
+ strlen(index_name
));
556 *p
++ = strlen(other_name
);
557 strcpy((char *)p
, other_name
);
558 p
= (short *)((char *)p
+ strlen(other_name
));
559 *p
++ = -1; /* res1a */
560 *p
++ = add_name(typelib
, type
->name
); /* name offset */
561 *p
++ = 0; /* FIXME: helpstring */
562 *p
++ = -1; /* res20 */
563 *(int *)p
= helpcontext
;
565 *p
++ = -1; /* res26 */
570 sltg_add_typeinfo(typelib
, block
, size
, index_name
);
575 static void init_typeinfo(struct sltg_typeinfo_header
*ti
, const type_t
*type
, int kind
,
576 const struct sltg_hrefmap
*hrefmap
)
579 ti
->href_offset
= -1;
582 ti
->version
= get_attrv(type
->attrs
, ATTR_VERSION
);
583 ti
->res16
= 0xfffe0000;
584 ti
->misc
.unknown1
= 0x02;
585 ti
->misc
.flags
= 0; /* FIXME */
586 ti
->misc
.unknown2
= 0x02;
587 ti
->misc
.typekind
= kind
;
590 ti
->member_offset
= sizeof(*ti
);
592 if (hrefmap
->href_count
)
595 int i
, hrefinfo_size
;
597 hrefinfo_size
= sizeof(struct sltg_hrefinfo
);
599 for (i
= 0; i
< hrefmap
->href_count
; i
++)
601 sprintf(name
, "*\\Rffff*#%x", hrefmap
->href
[i
]);
602 hrefinfo_size
+= 8 + 2 + strlen(name
);
605 ti
->href_offset
= ti
->member_offset
;
606 ti
->member_offset
+= hrefinfo_size
;
610 static void init_sltg_tail(struct sltg_tail
*tail
)
614 tail
->cImplTypes
= 0;
616 tail
->funcs_off
= -1;
618 tail
->impls_off
= -1;
619 tail
->funcs_bytes
= -1;
620 tail
->vars_bytes
= -1;
621 tail
->impls_bytes
= -1;
622 tail
->tdescalias_vt
= -1;
626 tail
->simple_alias
= 0;
628 tail
->cbSizeInstance
= 0;
629 tail
->cbAlignment
= 4;
638 tail
->type_bytes
= 0;
641 static void write_hrefmap(struct sltg_data
*data
, const struct sltg_hrefmap
*hrefmap
)
643 struct sltg_hrefinfo hrefinfo
;
647 if (!hrefmap
->href_count
) return;
649 hrefinfo
.magic
= 0xdf;
668 hrefinfo
.number
= hrefmap
->href_count
* 8;
672 hrefinfo
.resxx
= 0xdf;
674 append_data(data
, &hrefinfo
, offsetof(struct sltg_hrefinfo
, res50
));
676 for (i
= 0; i
< hrefmap
->href_count
; i
++)
677 append_data(data
, "\xff\xff\xff\xff\xff\xff\xff\xff", 8);
679 append_data(data
, &hrefinfo
.res50
, 7);
681 for (i
= 0; i
< hrefmap
->href_count
; i
++)
685 sprintf(name
, "*\\Rffff*#%x", hrefmap
->href
[i
]);
688 append_data(data
, &len
, sizeof(len
));
689 append_data(data
, name
, len
);
692 append_data(data
, &hrefinfo
.resxx
, sizeof(hrefinfo
.resxx
));
695 static void dump_var_desc(const char *data
, int size
)
697 const unsigned char *p
= (const unsigned char *)data
;
700 if (!(debuglevel
& (DEBUGLEVEL_TRACE
| DEBUGLEVEL_CHAT
))) return;
702 chat("dump_var_desc: size %d bytes\n", size
);
704 for (i
= 0; i
< size
; i
++)
705 fprintf(stderr
, " %02x", *p
++);
707 fprintf(stderr
, "\n");
710 static int get_element_size(type_t
*type
)
712 int vt
= get_type_vt(type
);
722 return /* typelib_kind == SYS_WIN16 ? 2 : */ 4;
758 return pointer_size
== 8 ? 24 : 16;
764 error("get_element_size: unrecognized vt %d\n", vt
);
771 static int local_href(struct sltg_hrefmap
*hrefmap
, int typelib_href
)
775 for (i
= 0; i
< hrefmap
->href_count
; i
++)
777 if (hrefmap
->href
[i
] == typelib_href
)
786 href
= hrefmap
->href_count
;
789 hrefmap
->href
= xrealloc(hrefmap
->href
, sizeof(*hrefmap
->href
) * (hrefmap
->href_count
+ 1));
791 hrefmap
->href
= xmalloc(sizeof(*hrefmap
->href
));
793 hrefmap
->href
[hrefmap
->href_count
] = typelib_href
;
794 hrefmap
->href_count
++;
797 chat("typelib href %d mapped to local href %d\n", typelib_href
, href
);
802 static short write_var_desc(struct sltg_typelib
*typelib
, struct sltg_data
*data
, type_t
*type
, short param_flags
,
803 short flags
, short base_offset
, int *size_instance
, struct sltg_hrefmap
*hrefmap
)
805 short vt
, vt_flags
, desc_offset
;
807 chat("write_var_desc: type %p, type->name %s\n",
808 type
, type
->name
? type
->name
: "NULL");
810 if (is_array(type
) && !type_array_is_decl_as_ptr(type
))
812 int num_dims
, elements
, array_start
, size
, array_size
;
831 while (is_array(atype
) && !type_array_is_decl_as_ptr(atype
))
834 elements
*= type_array_get_dim(atype
);
836 atype
= type_array_get_element(atype
);
839 chat("write_var_desc: VT_CARRAY: %d dimensions, %d elements\n", num_dims
, elements
);
841 array_start
= data
->size
;
843 size
= sizeof(*array
) + (num_dims
- 1) * 8 /* sizeof(SAFEARRAYBOUND) */;
844 array
= xmalloc(size
);
846 array
->cDims
= num_dims
;
847 array
->fFeatures
= 0x0004; /* FADF_EMBEDDED */
848 array
->cbElements
= get_element_size(atype
);
850 array
->pvData
= NULL
;
852 bound
= array
->bound
;
854 array_size
= array
->cbElements
;
857 while (is_array(atype
) && !type_array_is_decl_as_ptr(atype
))
859 bound
[0] = type_array_get_dim(atype
);
860 array_size
*= bound
[0];
864 atype
= type_array_get_element(atype
);
869 *size_instance
+= array_size
;
870 size_instance
= NULL
; /* don't account for element size */
873 append_data(data
, array
, size
);
875 desc_offset
= data
->size
;
877 vt_off
[0] = VT_CARRAY
;
878 vt_off
[1] = array_start
+ base_offset
;
879 append_data(data
, vt_off
, sizeof(vt_off
));
881 /* fall through to write array element description */
885 desc_offset
= data
->size
;
887 vt
= get_type_vt(type
);
891 type_t
*ref
= is_ptr(type
) ? type_pointer_get_ref(type
) : type_array_get_element(type
);
895 chat("write_var_desc: vt VT_PTR | 0x0400 | %04x\n", param_flags
);
896 vt
= VT_PTR
| 0x0400 | param_flags
;
897 append_data(data
, &vt
, sizeof(vt
));
898 write_var_desc(typelib
, data
, ref
, 0, 0, base_offset
, size_instance
, hrefmap
);
901 write_var_desc(typelib
, data
, ref
, param_flags
, 0x0e00, base_offset
, size_instance
, hrefmap
);
905 chat("write_var_desc: vt %d, flags %04x\n", vt
, flags
);
907 vt_flags
= vt
| flags
| param_flags
;
908 append_data(data
, &vt_flags
, sizeof(vt_flags
));
910 if (vt
== VT_USERDEFINED
)
914 while (type
->typelib_idx
< 0 && type_is_alias(type
))
915 type
= type_alias_get_aliasee(type
);
917 chat("write_var_desc: VT_USERDEFINED, type %p, name %s, real type %d, href %d\n",
918 type
, type
->name
, type_get_type(type
), type
->typelib_idx
);
920 if (type
->typelib_idx
== -1)
922 chat("write_var_desc: trying to ref not added type\n");
924 switch (type_get_type(type
))
927 add_structure_typeinfo(typelib
, type
);
930 add_interface_typeinfo(typelib
, type
);
933 add_enum_typeinfo(typelib
, type
);
936 add_union_typeinfo(typelib
, type
);
939 add_coclass_typeinfo(typelib
, type
);
942 error("write_var_desc: VT_USERDEFINED - unhandled type %d\n",
943 type_get_type(type
));
947 if (type
->typelib_idx
== -1)
948 error("write_var_desc: trying to ref not added type\n");
950 href
= local_href(hrefmap
, type
->typelib_idx
);
951 chat("write_var_desc: VT_USERDEFINED, local href %d\n", href
);
953 append_data(data
, &href
, sizeof(href
));
957 *size_instance
+= get_element_size(type
);
962 static void add_structure_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
964 struct sltg_data data
, *var_data
= NULL
;
965 struct sltg_hrefmap hrefmap
;
966 const char *index_name
;
967 struct sltg_typeinfo_header ti
;
968 struct sltg_member_header member
;
969 struct sltg_tail tail
;
970 int member_offset
, var_count
= 0, var_data_size
= 0, size_instance
= 0;
971 short *type_desc_offset
= NULL
;
973 if (type
->typelib_idx
!= -1) return;
975 chat("add_structure_typeinfo: type %p, type->name %s\n", type
, type
->name
);
977 type
->typelib_idx
= typelib
->n_file_blocks
;
979 hrefmap
.href_count
= 0;
982 if (type_struct_get_fields(type
))
987 var_count
= list_count(type_struct_get_fields(type
));
989 var_data
= xmalloc(var_count
* sizeof(*var_data
));
990 type_desc_offset
= xmalloc(var_count
* sizeof(*type_desc_offset
));
992 LIST_FOR_EACH_ENTRY(var
, type_struct_get_fields(type
), var_t
, entry
)
996 chat("add_structure_typeinfo: var %p (%s), type %p (%s)\n",
997 var
, var
->name
, var
->type
, var
->type
->name
);
999 init_sltg_data(&var_data
[i
]);
1001 base_offset
= var_data_size
+ (i
+ 1) * sizeof(struct sltg_variable
);
1002 type_desc_offset
[i
] = write_var_desc(typelib
, &var_data
[i
], var
->type
, 0, 0,
1003 base_offset
, &size_instance
, &hrefmap
);
1004 dump_var_desc(var_data
[i
].data
, var_data
[i
].size
);
1006 if (var_data
[i
].size
> sizeof(short))
1007 var_data_size
+= var_data
[i
].size
;
1012 init_sltg_data(&data
);
1014 index_name
= add_typeinfo_block(typelib
, type
, TKIND_RECORD
);
1016 init_typeinfo(&ti
, type
, TKIND_RECORD
, &hrefmap
);
1017 append_data(&data
, &ti
, sizeof(ti
));
1019 write_hrefmap(&data
, &hrefmap
);
1021 member_offset
= data
.size
;
1023 member
.res00
= 0x0001;
1024 member
.res02
= 0xffff;
1025 member
.res04
= 0x01;
1026 member
.extra
= var_data_size
+ var_count
* sizeof(struct sltg_variable
);
1027 append_data(&data
, &member
, sizeof(member
));
1031 if (type_struct_get_fields(type
))
1034 short next
= member_offset
;
1037 LIST_FOR_EACH_ENTRY(var
, type_struct_get_fields(type
), var_t
, entry
)
1039 struct sltg_variable variable
;
1041 next
+= sizeof(variable
);
1043 variable
.magic
= 0x2a; /* always write flags to simplify calculations */
1044 variable
.name
= add_name(typelib
, var
->name
);
1045 variable
.byte_offs
= 0;
1046 if (var_data
[i
].size
> sizeof(short))
1049 var_data_size
= next
- member_offset
+ type_desc_offset
[i
];
1050 variable
.type
= var_data_size
;
1051 next
+= var_data
[i
].size
;
1055 variable
.flags
= 0x02;
1056 variable
.type
= *(short *)var_data
[i
].data
;
1058 variable
.next
= i
< var_count
- 1 ? next
- member_offset
: -1;
1059 variable
.memid
= 0x40000000 + i
;
1060 variable
.helpcontext
= -2; /* 0xfffe */
1061 variable
.helpstring
= -1;
1062 variable
.varflags
= 0;
1064 append_data(&data
, &variable
, sizeof(variable
));
1065 if (var_data
[i
].size
> sizeof(short))
1066 append_data(&data
, var_data
[i
].data
, var_data
[i
].size
);
1072 init_sltg_tail(&tail
);
1074 tail
.cVars
= var_count
;
1076 tail
.vars_bytes
= var_data_size
;
1077 tail
.cbSizeInstance
= size_instance
;
1078 tail
.type_bytes
= data
.size
- member_offset
- sizeof(member
);
1079 append_data(&data
, &tail
, sizeof(tail
));
1081 add_block(typelib
, data
.data
, data
.size
, index_name
);
1084 static importinfo_t
*find_importinfo(typelib_t
*typelib
, const char *name
)
1086 importlib_t
*importlib
;
1088 LIST_FOR_EACH_ENTRY(importlib
, &typelib
->importlibs
, importlib_t
, entry
)
1092 for (i
= 0; i
< importlib
->ntypeinfos
; i
++)
1094 if (!strcmp(name
, importlib
->importinfos
[i
].name
))
1096 chat("Found %s in importlib list\n", name
);
1097 return &importlib
->importinfos
[i
];
1105 static int get_func_flags(const var_t
*func
, int *dispid
, int *invokekind
, int *helpcontext
, const char **helpstring
)
1110 *invokekind
= 1 /* INVOKE_FUNC */;
1114 if (!func
->attrs
) return 0;
1118 LIST_FOR_EACH_ENTRY(attr
, func
->attrs
, const attr_t
, entry
)
1120 expr_t
*expr
= attr
->u
.pval
;
1124 flags
|= 0x4; /* FUNCFLAG_FBINDABLE */
1126 case ATTR_DEFAULTBIND
:
1127 flags
|= 0x20; /* FUNCFLAG_FDEFAULTBIND */
1129 case ATTR_DEFAULTCOLLELEM
:
1130 flags
|= 0x100; /* FUNCFLAG_FDEFAULTCOLLELEM */
1132 case ATTR_DISPLAYBIND
:
1133 flags
|= 0x10; /* FUNCFLAG_FDISPLAYBIND */
1135 case ATTR_HELPCONTEXT
:
1136 *helpcontext
= expr
->u
.lval
;
1138 case ATTR_HELPSTRING
:
1139 *helpstring
= attr
->u
.pval
;
1142 flags
|= 0x40; /* FUNCFLAG_FHIDDEN */
1145 *dispid
= expr
->cval
;
1147 case ATTR_IMMEDIATEBIND
:
1148 flags
|= 0x1000; /* FUNCFLAG_FIMMEDIATEBIND */
1150 case ATTR_NONBROWSABLE
:
1151 flags
|= 0x400; /* FUNCFLAG_FNONBROWSABLE */
1154 *invokekind
= 0x2; /* INVOKE_PROPERTYGET */
1157 *invokekind
= 0x4; /* INVOKE_PROPERTYPUT */
1159 case ATTR_PROPPUTREF
:
1160 *invokekind
= 0x8; /* INVOKE_PROPERTYPUTREF */
1162 /* FIXME: FUNCFLAG_FREPLACEABLE */
1163 case ATTR_REQUESTEDIT
:
1164 flags
|= 0x8; /* FUNCFLAG_FREQUESTEDIT */
1166 case ATTR_RESTRICTED
:
1167 flags
|= 0x1; /* FUNCFLAG_FRESTRICTED */
1170 flags
|= 0x2; /* FUNCFLAG_FSOURCE */
1172 case ATTR_UIDEFAULT
:
1173 flags
|= 0x200; /* FUNCFLAG_FUIDEFAULT */
1175 case ATTR_USESGETLASTERROR
:
1176 flags
|= 0x80; /* FUNCFLAG_FUSESGETLASTERROR */
1186 static int get_param_flags(const var_t
*param
)
1191 if (!param
->attrs
) return 0;
1196 LIST_FOR_EACH_ENTRY(attr
, param
->attrs
, const attr_t
, entry
)
1206 case ATTR_PARAMLCID
:
1213 chat("unhandled param attr %d\n", attr
->type
);
1232 static int add_func_desc(struct sltg_typelib
*typelib
, struct sltg_data
*data
, var_t
*func
,
1233 int idx
, int dispid
, short base_offset
, struct sltg_hrefmap
*hrefmap
)
1235 struct sltg_data ret_data
, *arg_data
;
1236 int arg_count
= 0, arg_data_size
, optional
= 0, defaults
= 0, old_size
;
1237 int funcflags
= 0, invokekind
= 1 /* INVOKE_FUNC */, helpcontext
;
1238 const char *helpstring
;
1240 short ret_desc_offset
, *arg_desc_offset
, arg_offset
;
1241 struct sltg_function func_desc
;
1243 chat("add_func_desc: %s, idx %#x, dispid %#x\n", func
->name
, idx
, dispid
);
1245 old_size
= data
->size
;
1247 init_sltg_data(&ret_data
);
1248 ret_desc_offset
= write_var_desc(typelib
, &ret_data
, type_function_get_rettype(func
->type
),
1249 0, 0, base_offset
, NULL
, hrefmap
);
1250 dump_var_desc(ret_data
.data
, ret_data
.size
);
1253 arg_offset
= base_offset
+ sizeof(struct sltg_function
);
1255 if (ret_data
.size
> sizeof(short))
1257 arg_data_size
+= ret_data
.size
;
1258 arg_offset
+= ret_data
.size
;
1261 if (type_get_function_args(func
->type
))
1265 arg_count
= list_count(type_get_function_args(func
->type
));
1267 arg_data
= xmalloc(arg_count
* sizeof(*arg_data
));
1268 arg_desc_offset
= xmalloc(arg_count
* sizeof(*arg_desc_offset
));
1270 arg_offset
+= arg_count
* 2 * sizeof(short);
1272 LIST_FOR_EACH_ENTRY(arg
, type_get_function_args(func
->type
), const var_t
, entry
)
1275 short param_flags
= get_param_flags(arg
);
1277 chat("add_func_desc: arg[%d] %p (%s), type %p (%s)\n",
1278 i
, arg
, arg
->name
, arg
->type
, arg
->type
->name
);
1280 init_sltg_data(&arg_data
[i
]);
1282 arg_desc_offset
[i
] = write_var_desc(typelib
, &arg_data
[i
], arg
->type
, param_flags
, 0,
1283 arg_offset
, NULL
, hrefmap
);
1284 dump_var_desc(arg_data
[i
].data
, arg_data
[i
].size
);
1286 if (arg_data
[i
].size
> sizeof(short))
1288 arg_data_size
+= arg_data
[i
].size
;
1289 arg_offset
+= arg_data
[i
].size
;;
1294 if (!arg
->attrs
) continue;
1296 LIST_FOR_EACH_ENTRY(attr
, arg
->attrs
, const attr_t
, entry
)
1298 if (attr
->type
== ATTR_DEFAULTVALUE
)
1300 else if(attr
->type
== ATTR_OPTIONAL
)
1306 funcflags
= get_func_flags(func
, &dispid
, &invokekind
, &helpcontext
, &helpstring
);
1308 if (base_offset
!= -1)
1309 chat("add_func_desc: flags %#x, dispid %#x, invokekind %d, helpcontext %#x, helpstring %s\n",
1310 funcflags
, dispid
, invokekind
, helpcontext
, helpstring
);
1312 func_desc
.magic
= 0x6c; /* always write flags to simplify calculations */
1313 func_desc
.flags
= (invokekind
<< 4) | 0x02;
1314 if (idx
& 0x80000000)
1316 func_desc
.next
= -1;
1320 func_desc
.next
= base_offset
+ sizeof(func_desc
) + arg_data_size
+ arg_count
* 2 * sizeof(short);
1321 func_desc
.name
= base_offset
!= -1 ? add_name(typelib
, func
->name
) : -1;
1322 func_desc
.dispid
= dispid
;
1323 func_desc
.helpcontext
= helpcontext
;
1324 func_desc
.helpstring
= (helpstring
&& base_offset
!= -1) ? add_name(typelib
, helpstring
) : -1;
1325 func_desc
.arg_off
= arg_count
? base_offset
+ sizeof(func_desc
) : -1;
1326 func_desc
.nacc
= (arg_count
<< 3) | 4 /* CC_STDCALL */;
1327 func_desc
.retnextopt
= (optional
<< 1);
1328 if (ret_data
.size
> sizeof(short))
1330 func_desc
.rettype
= base_offset
+ sizeof(func_desc
) + ret_desc_offset
;
1332 func_desc
.arg_off
+= ret_data
.size
;
1336 func_desc
.retnextopt
|= 0x80;
1337 func_desc
.rettype
= *(short *)ret_data
.data
;
1339 func_desc
.vtblpos
= idx
* pointer_size
;
1340 func_desc
.funcflags
= funcflags
;
1342 append_data(data
, &func_desc
, sizeof(func_desc
));
1344 arg_offset
= base_offset
+ sizeof(struct sltg_function
);
1346 if (ret_data
.size
> sizeof(short))
1348 append_data(data
, ret_data
.data
, ret_data
.size
);
1349 func_desc
.arg_off
+= ret_data
.size
;
1350 arg_offset
+= ret_data
.size
;
1357 arg_offset
+= arg_count
* 2 * sizeof(short);
1359 LIST_FOR_EACH_ENTRY(arg
, type_get_function_args(func
->type
), const var_t
, entry
)
1361 short name
, type_offset
;
1363 name
= base_offset
!= -1 ? add_name(typelib
, arg
->name
) : -1;
1365 if (arg_data
[i
].size
> sizeof(short))
1367 type_offset
= (arg_offset
+ arg_desc_offset
[i
]);
1368 arg_offset
+= arg_data
[i
].size
;
1373 type_offset
= *(short *)arg_data
[i
].data
;
1376 append_data(data
, &name
, sizeof(name
));
1377 append_data(data
, &type_offset
, sizeof(type_offset
));
1379 if (base_offset
!= -1)
1380 chat("add_func_desc: arg[%d] - name %s (%#x), type_offset %#x\n",
1381 i
, arg
->name
, name
, type_offset
);
1386 for (i
= 0; i
< arg_count
; i
++)
1388 if (arg_data
[i
].size
> sizeof(short))
1389 append_data(data
, arg_data
[i
].data
, arg_data
[i
].size
);
1393 return data
->size
- old_size
;
1396 static void write_impl_href(struct sltg_data
*data
, short href
)
1398 struct sltg_impl_info impl_info
;
1400 impl_info
.res00
= 0x004a;
1401 impl_info
.next
= -1;
1402 impl_info
.res04
= -1;
1403 impl_info
.impltypeflags
= 0;
1404 impl_info
.res07
= 0x80;
1405 impl_info
.res08
= 0x0012;
1406 impl_info
.ref
= href
;
1407 impl_info
.res0c
= 0x4001;
1408 impl_info
.res0e
= -2; /* 0xfffe */
1409 impl_info
.res10
= -1;
1410 impl_info
.res12
= 0x001d;
1413 append_data(data
, &impl_info
, sizeof(impl_info
));
1416 static void add_interface_typeinfo(struct sltg_typelib
*typelib
, type_t
*iface
)
1418 const statement_t
*stmt_func
;
1419 importinfo_t
*ref_importinfo
= NULL
;
1420 short inherit_href
= -1;
1421 struct sltg_data data
;
1422 struct sltg_hrefmap hrefmap
;
1423 const char *index_name
;
1424 struct sltg_typeinfo_header ti
;
1425 struct sltg_member_header member
;
1426 struct sltg_tail tail
;
1427 int member_offset
, base_offset
, func_data_size
, i
;
1428 int func_count
, inherited_func_count
= 0;
1429 int dispid
, inherit_level
= 0;
1431 if (iface
->typelib_idx
!= -1) return;
1433 chat("add_interface_typeinfo: type %p, type->name %s\n", iface
, iface
->name
);
1435 if (!iface
->details
.iface
)
1437 error("interface %s is referenced but not defined\n", iface
->name
);
1441 if (is_attr(iface
->attrs
, ATTR_DISPINTERFACE
))
1443 error("support for dispinterface %s is not implemented\n", iface
->name
);
1447 hrefmap
.href_count
= 0;
1448 hrefmap
.href
= NULL
;
1450 if (type_iface_get_inherit(iface
))
1454 inherit
= type_iface_get_inherit(iface
);
1456 chat("add_interface_typeinfo: inheriting from base interface %s\n", inherit
->name
);
1458 ref_importinfo
= find_importinfo(typelib
->typelib
, inherit
->name
);
1460 if (!ref_importinfo
&& type_iface_get_inherit(inherit
))
1461 add_interface_typeinfo(typelib
, inherit
);
1464 error("support for imported interfaces is not implemented\n");
1466 inherit_href
= local_href(&hrefmap
, inherit
->typelib_idx
);
1471 inherited_func_count
+= list_count(type_iface_get_stmts(inherit
));
1472 inherit
= type_iface_get_inherit(inherit
);
1476 /* check typelib_idx again, it could have been added while resolving the parent interface */
1477 if (iface
->typelib_idx
!= -1) return;
1479 iface
->typelib_idx
= typelib
->n_file_blocks
;
1481 /* pass 1: calculate function descriptions data size */
1482 init_sltg_data(&data
);
1484 STATEMENTS_FOR_EACH_FUNC(stmt_func
, type_iface_get_stmts(iface
))
1486 add_func_desc(typelib
, &data
, stmt_func
->u
.var
, -1, -1, -1, &hrefmap
);
1489 func_data_size
= data
.size
;
1491 /* pass 2: write function descriptions */
1492 init_sltg_data(&data
);
1494 func_count
= list_count(type_iface_get_stmts(iface
));
1496 index_name
= add_typeinfo_block(typelib
, iface
, TKIND_INTERFACE
);
1498 init_typeinfo(&ti
, iface
, TKIND_INTERFACE
, &hrefmap
);
1499 append_data(&data
, &ti
, sizeof(ti
));
1501 write_hrefmap(&data
, &hrefmap
);
1503 member_offset
= data
.size
;
1506 member
.res00
= 0x0001;
1507 member
.res02
= 0xffff;
1508 member
.res04
= 0x01;
1509 member
.extra
= func_data_size
;
1510 if (inherit_href
!= -1)
1512 member
.extra
+= sizeof(struct sltg_impl_info
);
1513 base_offset
+= sizeof(struct sltg_impl_info
);
1515 append_data(&data
, &member
, sizeof(member
));
1517 if (inherit_href
!= -1)
1518 write_impl_href(&data
, inherit_href
);
1521 dispid
= 0x60000000 | (inherit_level
<< 16);
1523 STATEMENTS_FOR_EACH_FUNC(stmt_func
, type_iface_get_stmts(iface
))
1525 int idx
= inherited_func_count
+ i
;
1527 if (i
== func_count
- 1) idx
|= 0x80000000;
1529 base_offset
+= add_func_desc(typelib
, &data
, stmt_func
->u
.var
,
1530 idx
, dispid
+ i
, base_offset
, &hrefmap
);
1534 init_sltg_tail(&tail
);
1536 tail
.cFuncs
= func_count
;
1538 tail
.funcs_bytes
= func_data_size
;
1539 tail
.cbSizeInstance
= pointer_size
;
1540 tail
.cbAlignment
= pointer_size
;
1541 tail
.cbSizeVft
= (inherited_func_count
+ func_count
) * pointer_size
;
1542 tail
.type_bytes
= data
.size
- member_offset
- sizeof(member
);
1545 if (inherit_href
!= -1)
1549 tail
.impls_bytes
= 0;
1551 tail
.funcs_off
+= sizeof(struct sltg_impl_info
);
1553 append_data(&data
, &tail
, sizeof(tail
));
1555 add_block(typelib
, data
.data
, data
.size
, index_name
);
1558 static void add_enum_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
1560 error("add_enum_typeinfo: %s not implemented\n", type
->name
);
1563 static void add_union_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
1565 error("add_union_typeinfo: %s not implemented\n", type
->name
);
1568 static void add_coclass_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
1570 error("add_coclass_typeinfo: %s not implemented\n", type
->name
);
1573 static void add_type_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
1575 chat("add_type_typeinfo: adding %s, type %d\n", type
->name
, type_get_type(type
));
1577 switch (type_get_type(type
))
1579 case TYPE_INTERFACE
:
1580 add_interface_typeinfo(typelib
, type
);
1583 add_structure_typeinfo(typelib
, type
);
1586 add_enum_typeinfo(typelib
, type
);
1589 add_union_typeinfo(typelib
, type
);
1592 add_coclass_typeinfo(typelib
, type
);
1598 error("add_type_typeinfo: unhandled type %d for %s\n", type_get_type(type
), type
->name
);
1603 static void add_statement(struct sltg_typelib
*typelib
, const statement_t
*stmt
)
1611 case STMT_DECLARATION
:
1612 /* not included in typelib */
1614 case STMT_IMPORTLIB
:
1615 /* not processed here */
1620 const type_list_t
*type_entry
= stmt
->u
.type_list
;
1621 for (; type_entry
; type_entry
= type_entry
->next
)
1623 /* in old style typelibs all types are public */
1624 add_type_typeinfo(typelib
, type_entry
->type
);
1630 add_module_typeinfo(typelib
, stmt
->u
.type
);
1636 type_t
*type
= stmt
->u
.type
;
1637 add_type_typeinfo(typelib
, type
);
1642 error("add_statement: unhandled statement type %d\n", stmt
->type
);
1647 static void sltg_write_header(struct sltg_typelib
*sltg
, int *library_block_start
)
1653 short n_file_blocks
;
1655 short size_of_index
;
1661 struct sltg_block_entry
1667 struct sltg_block
*block
;
1670 header
.magic
= 0x47544c53;
1671 header
.n_file_blocks
= sltg
->n_file_blocks
+ 1;
1673 header
.size_of_index
= sltg
->index
.size
;
1674 header
.first_blk
= 1;
1675 header
.uuid
= sltg_library_guid
;
1676 header
.res1c
= 0x00000044;
1677 header
.res20
= 0xffff0000;
1679 put_data(&header
, sizeof(header
));
1681 block
= sltg
->blocks
;
1682 for (i
= 0; i
< sltg
->n_file_blocks
- 1; i
++)
1684 assert(block
->next
!= NULL
);
1686 entry
.length
= block
->length
;
1687 entry
.index_string
= block
->index_string
;
1688 entry
.next
= header
.first_blk
+ i
+ 1;
1689 chat("sltg_write_header: writing block entry %d: length %#x, index_string %#x, next %#x\n",
1690 i
, entry
.length
, entry
.index_string
, entry
.next
);
1691 put_data(&entry
, sizeof(entry
));
1693 block
= block
->next
;
1696 assert(block
->next
== NULL
);
1698 /* library block length includes helpstrings and name table */
1699 entry
.length
= block
->length
+ 0x40 + 2 + sltg
->typeinfo_size
+ 4 + 6 + 12 + 0x200 + sltg
->name_table
.size
+ 12;
1700 entry
.index_string
= block
->index_string
;
1702 chat("sltg_write_header: writing library block entry %d: length %#x, index_string %#x, next %#x\n",
1703 i
, entry
.length
, entry
.index_string
, entry
.next
);
1704 put_data(&entry
, sizeof(entry
));
1706 chat("sltg_write_header: writing index: %d bytes\n", sltg
->index
.size
);
1707 put_data(sltg
->index
.data
, sltg
->index
.size
);
1711 block
= sltg
->blocks
;
1712 for (i
= 0; i
< sltg
->n_file_blocks
- 1; i
++)
1714 chat("sltg_write_header: writing block %d: %d bytes\n", i
, block
->length
);
1716 put_data(block
->data
, block
->length
);
1717 block
= block
->next
;
1720 assert(block
->next
== NULL
);
1723 chat("library_block_start = %#lx\n", (SIZE_T
)output_buffer_pos
);
1724 *library_block_start
= output_buffer_pos
;
1725 chat("sltg_write_header: writing library block %d: %d bytes\n", i
, block
->length
);
1726 put_data(block
->data
, block
->length
);
1728 chat("sltg_write_header: writing pad 0x40 bytes\n");
1729 memset(pad
, 0xff, 0x40);
1730 put_data(pad
, 0x40);
1733 static void sltg_write_typeinfo(struct sltg_typelib
*typelib
)
1736 struct sltg_block
*block
;
1737 short count
= typelib
->typeinfo_count
;
1739 put_data(&count
, sizeof(count
));
1741 block
= typelib
->typeinfo
;
1742 for (i
= 0; i
< typelib
->typeinfo_count
; i
++)
1744 chat("sltg_write_typeinfo: writing block %d: %d bytes\n", i
, block
->length
);
1746 put_data(block
->data
, block
->length
);
1747 block
= block
->next
;
1749 assert(block
== NULL
);
1752 static void sltg_write_helpstrings(struct sltg_typelib
*typelib
)
1754 static const char dummy
[6];
1756 chat("sltg_write_helpstrings: writing dummy 6 bytes\n");
1758 put_data(dummy
, sizeof(dummy
));
1761 static void sltg_write_nametable(struct sltg_typelib
*typelib
)
1763 static const short dummy
[6] = { 0xffff,1,2,0xff00,0xffff,0xffff };
1766 chat("sltg_write_nametable: writing 12+0x200+%d bytes\n", typelib
->name_table
.size
);
1768 put_data(dummy
, sizeof(dummy
));
1769 memset(pad
, 0xff, 0x200);
1770 put_data(pad
, 0x200);
1771 put_data(&typelib
->name_table
.size
, sizeof(typelib
->name_table
.size
));
1772 put_data(typelib
->name_table
.data
, typelib
->name_table
.size
);
1775 static void sltg_write_remainder(void)
1777 static const short dummy1
[] = { 1,0xfffe,0x0a03,0,0xffff,0xffff };
1778 static const short dummy2
[] = { 0xffff,0xffff,0x0200,0,0,0 };
1779 static const char dummy3
[] = { 0xf4,0x39,0xb2,0x71,0,0,0,0,0,0,0,0,0,0,0,0 };
1780 static const char TYPELIB
[] = { 8,0,0,0,'T','Y','P','E','L','I','B',0 };
1784 put_data(&pad
, sizeof(pad
));
1786 put_data(&pad
, sizeof(pad
));
1788 put_data(dummy1
, sizeof(dummy1
));
1790 put_data(&sltg_library_guid
, sizeof(sltg_library_guid
));
1792 put_data(TYPELIB
, sizeof(TYPELIB
));
1794 put_data(dummy2
, sizeof(dummy2
));
1795 put_data(dummy3
, sizeof(dummy3
));
1798 static void save_all_changes(struct sltg_typelib
*typelib
)
1800 int library_block_start
;
1801 int *name_table_offset
;
1803 sltg_write_header(typelib
, &library_block_start
);
1804 sltg_write_typeinfo(typelib
);
1806 name_table_offset
= (int *)(output_buffer
+ output_buffer_pos
);
1807 chat("name_table_offset = %#lx\n", (SIZE_T
)output_buffer_pos
);
1808 put_data(&library_block_start
, sizeof(library_block_start
));
1810 sltg_write_helpstrings(typelib
);
1812 *name_table_offset
= output_buffer_pos
- library_block_start
;
1813 chat("*name_table_offset = %#x\n", *name_table_offset
);
1815 sltg_write_nametable(typelib
);
1816 sltg_write_remainder();
1818 if (strendswith(typelib_name
, ".res")) /* create a binary resource file */
1820 char typelib_id
[13] = "#1";
1822 expr_t
*expr
= get_attrp(typelib
->typelib
->attrs
, ATTR_ID
);
1824 sprintf(typelib_id
, "#%d", expr
->cval
);
1825 add_output_to_resources("TYPELIB", typelib_id
);
1826 output_typelib_regscript(typelib
->typelib
);
1828 else flush_output_buffer(typelib_name
);
1831 int create_sltg_typelib(typelib_t
*typelib
)
1833 struct sltg_typelib sltg
;
1834 const statement_t
*stmt
;
1835 void *library_block
;
1836 int library_block_size
, library_block_index
;
1838 sltg
.typelib
= typelib
;
1839 sltg
.typeinfo_count
= 0;
1840 sltg
.typeinfo_size
= 0;
1841 sltg
.typeinfo
= NULL
;
1843 sltg
.n_file_blocks
= 0;
1844 sltg
.first_block
= 1;
1846 init_index(&sltg
.index
);
1847 init_name_table(&sltg
);
1848 init_library(&sltg
);
1850 library_block
= create_library_block(&sltg
, &library_block_size
, &library_block_index
);
1853 LIST_FOR_EACH_ENTRY(stmt
, typelib
->stmts
, const statement_t
, entry
)
1854 add_statement(&sltg
, stmt
);
1856 add_block_index(&sltg
, library_block
, library_block_size
, library_block_index
);
1858 save_all_changes(&sltg
);