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
38 #include "typelib_struct.h"
43 static const GUID sltg_library_guid
= { 0x204ff,0,0,{ 0xc0,0,0,0,0,0,0,0x46 } };
69 struct sltg_block
*next
;
75 struct sltg_data index
;
76 struct sltg_data name_table
;
77 struct sltg_library library
;
78 struct sltg_block
*blocks
;
83 struct sltg_block
*typeinfo
;
93 struct sltg_typeinfo_header
104 unsigned unknown1
: 3;
106 unsigned unknown2
: 8;
107 unsigned typekind
: 8;
112 struct sltg_member_header
122 char magic
; /* 0x0a */
126 short byte_offs
; /* pos in struct, or offset to const type or const data (if flags & 0x08) */
127 short type
; /* if flags & 0x02 this is the type, else offset to type */
131 short varflags
; /* only present if magic & 0x02 */
139 short res06
; /* always 0000 */
140 short funcs_off
; /* offset to functions (starting from the member header) */
141 short vars_off
; /* offset to vars (starting from the member header) */
142 short impls_off
; /* offset to implemented types (starting from the member header) */
143 short funcs_bytes
; /* bytes used by function data */
144 short vars_bytes
; /* bytes used by var data */
145 short impls_bytes
; /* bytes used by implemented type data */
146 short tdescalias_vt
; /* for TKIND_ALIAS */
147 short res16
; /* always ffff */
148 short res18
; /* always 0000 */
149 short res1a
; /* always 0000 */
150 short simple_alias
; /* tdescalias_vt is a vt rather than an offset? */
151 short res1e
; /* always 0000 */
152 short cbSizeInstance
;
157 short res2a
; /* always ffff */
158 short res2c
; /* always ffff */
159 short res2e
; /* always ffff */
160 short res30
; /* always ffff */
161 short res32
; /* unknown */
162 short type_bytes
; /* bytes used by type descriptions */
167 char magic
; /* 0xdf */
168 char res01
; /* 0x00 */
169 int res02
; /* 0xffffffff */
170 int res06
; /* 0xffffffff */
171 int res0a
; /* 0xffffffff */
172 int res0e
; /* 0xffffffff */
173 int res12
; /* 0xffffffff */
174 int res16
; /* 0xffffffff */
175 int res1a
; /* 0xffffffff */
176 int res1e
; /* 0xffffffff */
177 int res22
; /* 0xffffffff */
178 int res26
; /* 0xffffffff */
179 int res2a
; /* 0xffffffff */
180 int res2e
; /* 0xffffffff */
181 int res32
; /* 0xffffffff */
182 int res36
; /* 0xffffffff */
183 int res3a
; /* 0xffffffff */
184 int res3e
; /* 0xffffffff */
185 short res42
;/* 0xffff */
186 int number
; /* this is 8 times the number of refs */
187 /* Now we have number bytes (8 for each ref) of SLTG_UnknownRefInfo */
189 short res50
;/* 0xffff */
190 char res52
; /* 0x01 */
191 int res53
; /* 0x00000000 */
192 /* Now we have number/8 SLTG_Names (first WORD is no of bytes in the ascii
193 * string). Strings look like "*\Rxxxx*#n". If xxxx == ffff then the
194 * ref refers to the nth type listed in this library (0 based). Else
195 * the xxxx (which maybe fewer than 4 digits) is the offset into the name
196 * table to a string "*\G{<guid>}#1.0#0#C:\WINNT\System32\stdole32.tlb#"
197 * The guid is the typelib guid; the ref again refers to the nth type of
198 * the imported typelib.
201 char resxx
; /* 0xdf */
206 char magic
; /* 0x4c, 0xcb or 0x8b with optional SLTG_FUNCTION_FLAGS_PRESENT flag */
207 char flags
; /* high nibble is INVOKE_KIND, low nibble = 2 */
208 short next
; /* byte offset from beginning of group to next fn */
209 short name
; /* Offset within name table to name */
210 int dispid
; /* dispid */
211 short helpcontext
; /* helpcontext (again 1 is special) */
212 short helpstring
; /* helpstring offset to offset */
213 short arg_off
; /* offset to args from start of block */
214 char nacc
; /* lowest 3bits are CALLCONV, rest are no of args */
215 char retnextopt
; /* if 0x80 bit set ret type follows else next WORD
216 is offset to ret type. No of optional args is
218 short rettype
; /* return type VT_?? or offset to ret type */
219 short vtblpos
; /* position in vtbl? */
220 short funcflags
; /* present if magic & 0x20 */
221 /* Param list starts, repeat next two as required */
223 WORD name
; /* offset to 2nd letter of name */
224 WORD
+ type
; /* VT_ of param */
228 struct sltg_impl_info
246 static void add_structure_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
);
247 static void add_interface_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
);
248 static void add_enum_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
);
249 static void add_union_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
);
250 static void add_coclass_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
);
252 static void init_sltg_data(struct sltg_data
*data
)
255 data
->allocated
= 0x10;
256 data
->data
= xmalloc(0x10);
259 static int add_index(struct sltg_data
*index
, const char *name
)
261 int name_offset
= index
->size
;
262 int new_size
= index
->size
+ strlen(name
) + 1;
264 chat("add_index: name_offset %d, \"%s\"\n", name_offset
, name
);
266 if (new_size
> index
->allocated
)
268 index
->allocated
= max(index
->allocated
* 2, new_size
);
269 index
->data
= xrealloc(index
->data
, index
->allocated
);
272 strcpy(index
->data
+ index
->size
, name
);
273 index
->size
= new_size
;
278 static void init_index(struct sltg_data
*index
)
280 static const char compobj
[] = { 1,'C','o','m','p','O','b','j',0 };
282 init_sltg_data(index
);
284 add_index(index
, compobj
);
287 static int add_name(struct sltg_typelib
*sltg
, const char *name
)
289 int name_offset
= sltg
->name_table
.size
;
290 int new_size
= sltg
->name_table
.size
+ strlen(name
) + 1 + 8;
293 chat("add_name: %s\n", name
);
295 aligned_size
= (new_size
+ 0x1f) & ~0x1f;
296 if (aligned_size
- new_size
< 4)
297 new_size
= aligned_size
;
299 new_size
= (new_size
+ 1) & ~1;
301 if (new_size
> sltg
->name_table
.allocated
)
303 sltg
->name_table
.allocated
= max(sltg
->name_table
.allocated
* 2, new_size
);
304 sltg
->name_table
.data
= xrealloc(sltg
->name_table
.data
, sltg
->name_table
.allocated
);
307 memset(sltg
->name_table
.data
+ sltg
->name_table
.size
, 0xff, 8);
308 strcpy(sltg
->name_table
.data
+ sltg
->name_table
.size
+ 8, name
);
309 sltg
->name_table
.size
= new_size
;
310 sltg
->name_table
.data
[sltg
->name_table
.size
- 1] = 0; /* clear alignment */
315 static void init_name_table(struct sltg_typelib
*sltg
)
317 init_sltg_data(&sltg
->name_table
);
320 static void init_library(struct sltg_typelib
*sltg
)
324 sltg
->library
.name
= add_name(sltg
, sltg
->typelib
->name
);
325 sltg
->library
.helpstring
= NULL
;
326 sltg
->library
.helpcontext
= 0;
327 sltg
->library
.syskind
= typelib_kind
;
328 sltg
->library
.lcid
= 0x0409;
329 sltg
->library
.libflags
= 0;
330 sltg
->library
.version
= 0;
331 sltg
->library
.helpfile
= NULL
;
332 memset(&sltg
->library
.uuid
, 0, sizeof(sltg
->library
.uuid
));
334 if (!sltg
->typelib
->attrs
) return;
336 LIST_FOR_EACH_ENTRY(attr
, sltg
->typelib
->attrs
, const attr_t
, entry
)
343 sltg
->library
.version
= attr
->u
.ival
;
345 case ATTR_HELPSTRING
:
346 sltg
->library
.helpstring
= attr
->u
.pval
;
349 sltg
->library
.helpfile
= attr
->u
.pval
;
352 sltg
->library
.uuid
= *(GUID
*)attr
->u
.pval
;
354 case ATTR_HELPCONTEXT
:
356 sltg
->library
.helpcontext
= expr
->cval
;
360 sltg
->library
.lcid
= expr
->cval
;
363 sltg
->library
.libflags
|= 0x02; /* LIBFLAG_FCONTROL */
366 sltg
->library
.libflags
|= 0x04; /* LIBFLAG_FHIDDEN */
368 case ATTR_RESTRICTED
:
369 sltg
->library
.libflags
|= 0x01; /* LIBFLAG_FRESTRICTED */
377 static void add_block_index(struct sltg_typelib
*sltg
, void *data
, int size
, int index
)
379 struct sltg_block
*block
= xmalloc(sizeof(*block
));
381 block
->length
= size
;
383 block
->index_string
= index
;
388 struct sltg_block
*blocks
= sltg
->blocks
;
391 blocks
= blocks
->next
;
393 blocks
->next
= block
;
396 sltg
->blocks
= block
;
398 sltg
->n_file_blocks
++;
401 static void add_block(struct sltg_typelib
*sltg
, void *data
, int size
, const char *name
)
403 struct sltg_block
*block
= xmalloc(sizeof(*block
));
406 chat("add_block: %p,%d,\"%s\"\n", data
, size
, name
);
408 index
= add_index(&sltg
->index
, name
);
410 add_block_index(sltg
, data
, size
, index
);
413 static void *create_library_block(struct sltg_typelib
*typelib
, int *size
, int *index
)
418 *size
= sizeof(short) * 9 + sizeof(int) * 3 + sizeof(GUID
);
419 if (typelib
->library
.helpstring
) *size
+= strlen(typelib
->library
.helpstring
);
420 if (typelib
->library
.helpfile
) *size
+= strlen(typelib
->library
.helpfile
);
422 block
= xmalloc(*size
);
424 *p
++ = 0x51cc; /* magic */
425 *p
++ = 3; /* res02 */
426 *p
++ = typelib
->library
.name
;
427 *p
++ = 0xffff; /* res06 */
428 if (typelib
->library
.helpstring
)
430 *p
++ = strlen(typelib
->library
.helpstring
);
431 strcpy((char *)p
, typelib
->library
.helpstring
);
432 p
= (short *)((char *)p
+ strlen(typelib
->library
.helpstring
));
436 if (typelib
->library
.helpfile
)
438 *p
++ = strlen(typelib
->library
.helpfile
);
439 strcpy((char *)p
, typelib
->library
.helpfile
);
440 p
= (short *)((char *)p
+ strlen(typelib
->library
.helpfile
));
444 *(int *)p
= typelib
->library
.helpcontext
;
446 *p
++ = typelib
->library
.syskind
;
447 *p
++ = typelib
->library
.lcid
;
448 *(int *)p
= 0; /* res12 */
450 *p
++ = typelib
->library
.libflags
;
451 *(int *)p
= typelib
->library
.version
;
453 *(GUID
*)p
= typelib
->library
.uuid
;
455 *index
= add_index(&typelib
->index
, "dir");
460 static const char *new_index_name(void)
462 static char name
[11] = "0000000000";
466 if (name
[pos
] == 'Z')
470 error("too many index names\n");
475 new_name
= xmalloc(sizeof(name
));
476 strcpy(new_name
, name
);
480 static void sltg_add_typeinfo(struct sltg_typelib
*sltg
, void *data
, int size
, const char *name
)
482 struct sltg_block
*block
= xmalloc(sizeof(*block
));
484 chat("sltg_add_typeinfo: %p,%d,%s\n", data
, size
, name
);
486 block
->length
= size
;
488 block
->index_string
= 0;
493 struct sltg_block
*typeinfo
= sltg
->typeinfo
;
495 while (typeinfo
->next
)
496 typeinfo
= typeinfo
->next
;
498 typeinfo
->next
= block
;
501 sltg
->typeinfo
= block
;
503 sltg
->typeinfo_count
++;
504 sltg
->typeinfo_size
+= size
;
507 static void append_data(struct sltg_data
*block
, const void *data
, int size
)
509 int new_size
= block
->size
+ size
;
511 if (new_size
> block
->allocated
)
513 block
->allocated
= max(block
->allocated
* 2, new_size
);
514 block
->data
= xrealloc(block
->data
, block
->allocated
);
517 memcpy(block
->data
+ block
->size
, data
, size
);
518 block
->size
= new_size
;
521 static void add_module_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
523 error("add_module_typeinfo: %s not implemented\n", type
->name
);
526 static const char *add_typeinfo_block(struct sltg_typelib
*typelib
, const type_t
*type
, int kind
)
528 const char *index_name
, *other_name
;
531 int size
, helpcontext
= 0;
535 index_name
= new_index_name();
536 other_name
= new_index_name();
538 expr
= get_attrp(type
->attrs
, ATTR_HELPCONTEXT
);
539 if (expr
) helpcontext
= expr
->cval
;
541 p
= get_attrp(type
->attrs
, ATTR_UUID
);
542 if (p
) guid
= *(GUID
*)p
;
544 size
= sizeof(short) * 8 + 10 /* index_name */ * 2 + sizeof(int) + sizeof(GUID
);
546 block
= xmalloc(size
);
548 *p
++ = strlen(index_name
);
549 strcpy((char *)p
, index_name
);
550 p
= (short *)((char *)p
+ strlen(index_name
));
551 *p
++ = strlen(other_name
);
552 strcpy((char *)p
, other_name
);
553 p
= (short *)((char *)p
+ strlen(other_name
));
554 *p
++ = -1; /* res1a */
555 *p
++ = add_name(typelib
, type
->name
); /* name offset */
556 *p
++ = 0; /* FIXME: helpstring */
557 *p
++ = -1; /* res20 */
558 *(int *)p
= helpcontext
;
560 *p
++ = -1; /* res26 */
565 sltg_add_typeinfo(typelib
, block
, size
, index_name
);
570 static void init_typeinfo(struct sltg_typeinfo_header
*ti
, const type_t
*type
, int kind
,
571 const struct sltg_hrefmap
*hrefmap
)
574 ti
->href_offset
= -1;
577 ti
->version
= get_attrv(type
->attrs
, ATTR_VERSION
);
578 ti
->res16
= 0xfffe0000;
579 ti
->misc
.unknown1
= 0x02;
580 ti
->misc
.flags
= 0; /* FIXME */
581 ti
->misc
.unknown2
= 0x02;
582 ti
->misc
.typekind
= kind
;
585 ti
->member_offset
= sizeof(*ti
);
587 if (hrefmap
->href_count
)
590 int i
, hrefinfo_size
;
592 hrefinfo_size
= sizeof(struct sltg_hrefinfo
);
594 for (i
= 0; i
< hrefmap
->href_count
; i
++)
596 sprintf(name
, "*\\Rffff*#%x", hrefmap
->href
[i
]);
597 hrefinfo_size
+= 8 + 2 + strlen(name
);
600 ti
->href_offset
= ti
->member_offset
;
601 ti
->member_offset
+= hrefinfo_size
;
605 static void init_sltg_tail(struct sltg_tail
*tail
)
609 tail
->cImplTypes
= 0;
611 tail
->funcs_off
= -1;
613 tail
->impls_off
= -1;
614 tail
->funcs_bytes
= -1;
615 tail
->vars_bytes
= -1;
616 tail
->impls_bytes
= -1;
617 tail
->tdescalias_vt
= -1;
621 tail
->simple_alias
= 0;
623 tail
->cbSizeInstance
= 0;
624 tail
->cbAlignment
= 4;
633 tail
->type_bytes
= 0;
636 static void write_hrefmap(struct sltg_data
*data
, const struct sltg_hrefmap
*hrefmap
)
638 struct sltg_hrefinfo hrefinfo
;
642 if (!hrefmap
->href_count
) return;
644 hrefinfo
.magic
= 0xdf;
663 hrefinfo
.number
= hrefmap
->href_count
* 8;
667 hrefinfo
.resxx
= 0xdf;
669 append_data(data
, &hrefinfo
, offsetof(struct sltg_hrefinfo
, res50
));
671 for (i
= 0; i
< hrefmap
->href_count
; i
++)
672 append_data(data
, "\xff\xff\xff\xff\xff\xff\xff\xff", 8);
674 append_data(data
, &hrefinfo
.res50
, 7);
676 for (i
= 0; i
< hrefmap
->href_count
; i
++)
680 sprintf(name
, "*\\Rffff*#%x", hrefmap
->href
[i
]);
683 append_data(data
, &len
, sizeof(len
));
684 append_data(data
, name
, len
);
687 append_data(data
, &hrefinfo
.resxx
, sizeof(hrefinfo
.resxx
));
690 static void dump_var_desc(const char *data
, int size
)
692 const unsigned char *p
= (const unsigned char *)data
;
695 if (!(debuglevel
& (DEBUGLEVEL_TRACE
| DEBUGLEVEL_CHAT
))) return;
697 chat("dump_var_desc: size %d bytes\n", size
);
699 for (i
= 0; i
< size
; i
++)
700 fprintf(stderr
, " %02x", *p
++);
702 fprintf(stderr
, "\n");
705 static int get_element_size(type_t
*type
)
707 int vt
= get_type_vt(type
);
717 return typelib_kind
== SYS_WIN16
? 2 : 4;
753 return pointer_size
== 8 ? 24 : 16;
759 error("get_element_size: unrecognized vt %d\n", vt
);
766 static int local_href(struct sltg_hrefmap
*hrefmap
, int typelib_href
)
770 for (i
= 0; i
< hrefmap
->href_count
; i
++)
772 if (hrefmap
->href
[i
] == typelib_href
)
781 href
= hrefmap
->href_count
;
784 hrefmap
->href
= xrealloc(hrefmap
->href
, sizeof(*hrefmap
->href
) * (hrefmap
->href_count
+ 1));
786 hrefmap
->href
= xmalloc(sizeof(*hrefmap
->href
));
788 hrefmap
->href
[hrefmap
->href_count
] = typelib_href
;
789 hrefmap
->href_count
++;
792 chat("typelib href %d mapped to local href %d\n", typelib_href
, href
);
797 static short write_var_desc(struct sltg_typelib
*typelib
, struct sltg_data
*data
, type_t
*type
, short param_flags
,
798 short flags
, short base_offset
, int *size_instance
, struct sltg_hrefmap
*hrefmap
)
800 short vt
, vt_flags
, desc_offset
;
802 chat("write_var_desc: type %p, type->name %s\n",
803 type
, type
->name
? type
->name
: "NULL");
805 if (is_array(type
) && !type_array_is_decl_as_ptr(type
))
807 int num_dims
, elements
, array_start
, size
, array_size
;
826 while (is_array(atype
) && !type_array_is_decl_as_ptr(atype
))
829 elements
*= type_array_get_dim(atype
);
831 atype
= type_array_get_element(atype
);
834 chat("write_var_desc: VT_CARRAY: %d dimensions, %d elements\n", num_dims
, elements
);
836 array_start
= data
->size
;
838 size
= sizeof(*array
) + (num_dims
- 1) * 8 /* sizeof(SAFEARRAYBOUND) */;
839 array
= xmalloc(size
);
841 array
->cDims
= num_dims
;
842 array
->fFeatures
= 0x0004; /* FADF_EMBEDDED */
843 array
->cbElements
= get_element_size(atype
);
845 array
->pvData
= NULL
;
847 bound
= array
->bound
;
849 array_size
= array
->cbElements
;
852 while (is_array(atype
) && !type_array_is_decl_as_ptr(atype
))
854 bound
[0] = type_array_get_dim(atype
);
855 array_size
*= bound
[0];
859 atype
= type_array_get_element(atype
);
864 *size_instance
+= array_size
;
865 size_instance
= NULL
; /* don't account for element size */
868 append_data(data
, array
, size
);
870 desc_offset
= data
->size
;
872 vt_off
[0] = VT_CARRAY
;
873 vt_off
[1] = array_start
+ base_offset
;
874 append_data(data
, vt_off
, sizeof(vt_off
));
876 /* fall through to write array element description */
880 desc_offset
= data
->size
;
882 vt
= get_type_vt(type
);
886 type_t
*ref
= is_ptr(type
) ? type_pointer_get_ref(type
) : type_array_get_element(type
);
890 chat("write_var_desc: vt VT_PTR | 0x0400 | %04x\n", param_flags
);
891 vt
= VT_PTR
| 0x0400 | param_flags
;
892 append_data(data
, &vt
, sizeof(vt
));
893 write_var_desc(typelib
, data
, ref
, 0, 0, base_offset
, size_instance
, hrefmap
);
896 write_var_desc(typelib
, data
, ref
, param_flags
, 0x0e00, base_offset
, size_instance
, hrefmap
);
900 chat("write_var_desc: vt %d, flags %04x\n", vt
, flags
);
902 vt_flags
= vt
| flags
| param_flags
;
903 append_data(data
, &vt_flags
, sizeof(vt_flags
));
905 if (vt
== VT_USERDEFINED
)
909 while (type
->typelib_idx
< 0 && type_is_alias(type
))
910 type
= type_alias_get_aliasee(type
);
912 chat("write_var_desc: VT_USERDEFINED, type %p, name %s, real type %d, href %d\n",
913 type
, type
->name
, type_get_type(type
), type
->typelib_idx
);
915 if (type
->typelib_idx
== -1)
917 chat("write_var_desc: trying to ref not added type\n");
919 switch (type_get_type(type
))
922 add_structure_typeinfo(typelib
, type
);
925 add_interface_typeinfo(typelib
, type
);
928 add_enum_typeinfo(typelib
, type
);
931 add_union_typeinfo(typelib
, type
);
934 add_coclass_typeinfo(typelib
, type
);
937 error("write_var_desc: VT_USERDEFINED - unhandled type %d\n",
938 type_get_type(type
));
942 if (type
->typelib_idx
== -1)
943 error("write_var_desc: trying to ref not added type\n");
945 href
= local_href(hrefmap
, type
->typelib_idx
);
946 chat("write_var_desc: VT_USERDEFINED, local href %d\n", href
);
948 append_data(data
, &href
, sizeof(href
));
952 *size_instance
+= get_element_size(type
);
957 static void add_structure_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
959 struct sltg_data data
, *var_data
= NULL
;
960 struct sltg_hrefmap hrefmap
;
961 const char *index_name
;
962 struct sltg_typeinfo_header ti
;
963 struct sltg_member_header member
;
964 struct sltg_tail tail
;
965 int member_offset
, var_count
= 0, var_data_size
= 0, size_instance
= 0;
966 short *type_desc_offset
= NULL
;
968 if (type
->typelib_idx
!= -1) return;
970 chat("add_structure_typeinfo: type %p, type->name %s\n", type
, type
->name
);
972 type
->typelib_idx
= typelib
->n_file_blocks
;
974 hrefmap
.href_count
= 0;
977 if (type_struct_get_fields(type
))
982 var_count
= list_count(type_struct_get_fields(type
));
984 var_data
= xmalloc(var_count
* sizeof(*var_data
));
985 type_desc_offset
= xmalloc(var_count
* sizeof(*type_desc_offset
));
987 LIST_FOR_EACH_ENTRY(var
, type_struct_get_fields(type
), var_t
, entry
)
991 chat("add_structure_typeinfo: var %p (%s), type %p (%s)\n",
992 var
, var
->name
, var
->type
, var
->type
->name
);
994 init_sltg_data(&var_data
[i
]);
996 base_offset
= var_data_size
+ (i
+ 1) * sizeof(struct sltg_variable
);
997 type_desc_offset
[i
] = write_var_desc(typelib
, &var_data
[i
], var
->type
, 0, 0,
998 base_offset
, &size_instance
, &hrefmap
);
999 dump_var_desc(var_data
[i
].data
, var_data
[i
].size
);
1001 if (var_data
[i
].size
> sizeof(short))
1002 var_data_size
+= var_data
[i
].size
;
1007 init_sltg_data(&data
);
1009 index_name
= add_typeinfo_block(typelib
, type
, TKIND_RECORD
);
1011 init_typeinfo(&ti
, type
, TKIND_RECORD
, &hrefmap
);
1012 append_data(&data
, &ti
, sizeof(ti
));
1014 write_hrefmap(&data
, &hrefmap
);
1016 member_offset
= data
.size
;
1018 member
.res00
= 0x0001;
1019 member
.res02
= 0xffff;
1020 member
.res04
= 0x01;
1021 member
.extra
= var_data_size
+ var_count
* sizeof(struct sltg_variable
);
1022 append_data(&data
, &member
, sizeof(member
));
1026 if (type_struct_get_fields(type
))
1029 short next
= member_offset
;
1032 LIST_FOR_EACH_ENTRY(var
, type_struct_get_fields(type
), var_t
, entry
)
1034 struct sltg_variable variable
;
1036 next
+= sizeof(variable
);
1038 variable
.magic
= 0x2a; /* always write flags to simplify calculations */
1039 variable
.name
= add_name(typelib
, var
->name
);
1040 variable
.byte_offs
= 0;
1041 if (var_data
[i
].size
> sizeof(short))
1044 var_data_size
= next
- member_offset
+ type_desc_offset
[i
];
1045 variable
.type
= var_data_size
;
1046 next
+= var_data
[i
].size
;
1050 variable
.flags
= 0x02;
1051 variable
.type
= *(short *)var_data
[i
].data
;
1053 variable
.next
= i
< var_count
- 1 ? next
- member_offset
: -1;
1054 variable
.memid
= 0x40000000 + i
;
1055 variable
.helpcontext
= -2; /* 0xfffe */
1056 variable
.helpstring
= -1;
1057 variable
.varflags
= 0;
1059 append_data(&data
, &variable
, sizeof(variable
));
1060 if (var_data
[i
].size
> sizeof(short))
1061 append_data(&data
, var_data
[i
].data
, var_data
[i
].size
);
1067 init_sltg_tail(&tail
);
1069 tail
.cVars
= var_count
;
1071 tail
.vars_bytes
= var_data_size
;
1072 tail
.cbSizeInstance
= size_instance
;
1073 tail
.type_bytes
= data
.size
- member_offset
- sizeof(member
);
1074 append_data(&data
, &tail
, sizeof(tail
));
1076 add_block(typelib
, data
.data
, data
.size
, index_name
);
1079 static importinfo_t
*find_importinfo(typelib_t
*typelib
, const char *name
)
1081 importlib_t
*importlib
;
1083 LIST_FOR_EACH_ENTRY(importlib
, &typelib
->importlibs
, importlib_t
, entry
)
1087 for (i
= 0; i
< importlib
->ntypeinfos
; i
++)
1089 if (!strcmp(name
, importlib
->importinfos
[i
].name
))
1091 chat("Found %s in importlib list\n", name
);
1092 return &importlib
->importinfos
[i
];
1100 static int get_func_flags(const var_t
*func
, int *dispid
, int *invokekind
, int *helpcontext
, const char **helpstring
)
1105 *invokekind
= 1 /* INVOKE_FUNC */;
1109 if (!func
->attrs
) return 0;
1113 LIST_FOR_EACH_ENTRY(attr
, func
->attrs
, const attr_t
, entry
)
1115 expr_t
*expr
= attr
->u
.pval
;
1119 flags
|= 0x4; /* FUNCFLAG_FBINDABLE */
1121 case ATTR_DEFAULTBIND
:
1122 flags
|= 0x20; /* FUNCFLAG_FDEFAULTBIND */
1124 case ATTR_DEFAULTCOLLELEM
:
1125 flags
|= 0x100; /* FUNCFLAG_FDEFAULTCOLLELEM */
1127 case ATTR_DISPLAYBIND
:
1128 flags
|= 0x10; /* FUNCFLAG_FDISPLAYBIND */
1130 case ATTR_HELPCONTEXT
:
1131 *helpcontext
= expr
->u
.lval
;
1133 case ATTR_HELPSTRING
:
1134 *helpstring
= attr
->u
.pval
;
1137 flags
|= 0x40; /* FUNCFLAG_FHIDDEN */
1140 *dispid
= expr
->cval
;
1142 case ATTR_IMMEDIATEBIND
:
1143 flags
|= 0x1000; /* FUNCFLAG_FIMMEDIATEBIND */
1145 case ATTR_NONBROWSABLE
:
1146 flags
|= 0x400; /* FUNCFLAG_FNONBROWSABLE */
1149 *invokekind
= 0x2; /* INVOKE_PROPERTYGET */
1152 *invokekind
= 0x4; /* INVOKE_PROPERTYPUT */
1154 case ATTR_PROPPUTREF
:
1155 *invokekind
= 0x8; /* INVOKE_PROPERTYPUTREF */
1157 /* FIXME: FUNCFLAG_FREPLACEABLE */
1158 case ATTR_REQUESTEDIT
:
1159 flags
|= 0x8; /* FUNCFLAG_FREQUESTEDIT */
1161 case ATTR_RESTRICTED
:
1162 flags
|= 0x1; /* FUNCFLAG_FRESTRICTED */
1165 flags
|= 0x2; /* FUNCFLAG_FSOURCE */
1167 case ATTR_UIDEFAULT
:
1168 flags
|= 0x200; /* FUNCFLAG_FUIDEFAULT */
1170 case ATTR_USESGETLASTERROR
:
1171 flags
|= 0x80; /* FUNCFLAG_FUSESGETLASTERROR */
1181 static int get_param_flags(const var_t
*param
)
1186 if (!param
->attrs
) return 0;
1191 LIST_FOR_EACH_ENTRY(attr
, param
->attrs
, const attr_t
, entry
)
1201 case ATTR_PARAMLCID
:
1208 chat("unhandled param attr %d\n", attr
->type
);
1227 static int add_func_desc(struct sltg_typelib
*typelib
, struct sltg_data
*data
, var_t
*func
,
1228 int idx
, int dispid
, short base_offset
, struct sltg_hrefmap
*hrefmap
)
1230 struct sltg_data ret_data
, *arg_data
;
1231 int arg_count
= 0, arg_data_size
, optional
= 0, defaults
= 0, old_size
;
1232 int funcflags
= 0, invokekind
= 1 /* INVOKE_FUNC */, helpcontext
;
1233 const char *helpstring
;
1235 short ret_desc_offset
, *arg_desc_offset
, arg_offset
;
1236 struct sltg_function func_desc
;
1238 chat("add_func_desc: %s, idx %#x, dispid %#x\n", func
->name
, idx
, dispid
);
1240 old_size
= data
->size
;
1242 init_sltg_data(&ret_data
);
1243 ret_desc_offset
= write_var_desc(typelib
, &ret_data
, type_function_get_rettype(func
->type
),
1244 0, 0, base_offset
, NULL
, hrefmap
);
1245 dump_var_desc(ret_data
.data
, ret_data
.size
);
1248 arg_offset
= base_offset
+ sizeof(struct sltg_function
);
1250 if (ret_data
.size
> sizeof(short))
1252 arg_data_size
+= ret_data
.size
;
1253 arg_offset
+= ret_data
.size
;
1256 if (type_get_function_args(func
->type
))
1260 arg_count
= list_count(type_get_function_args(func
->type
));
1262 arg_data
= xmalloc(arg_count
* sizeof(*arg_data
));
1263 arg_desc_offset
= xmalloc(arg_count
* sizeof(*arg_desc_offset
));
1265 arg_offset
+= arg_count
* 2 * sizeof(short);
1267 LIST_FOR_EACH_ENTRY(arg
, type_get_function_args(func
->type
), const var_t
, entry
)
1270 short param_flags
= get_param_flags(arg
);
1272 chat("add_func_desc: arg[%d] %p (%s), type %p (%s)\n",
1273 i
, arg
, arg
->name
, arg
->type
, arg
->type
->name
);
1275 init_sltg_data(&arg_data
[i
]);
1277 arg_desc_offset
[i
] = write_var_desc(typelib
, &arg_data
[i
], arg
->type
, param_flags
, 0,
1278 arg_offset
, NULL
, hrefmap
);
1279 dump_var_desc(arg_data
[i
].data
, arg_data
[i
].size
);
1281 if (arg_data
[i
].size
> sizeof(short))
1283 arg_data_size
+= arg_data
[i
].size
;
1284 arg_offset
+= arg_data
[i
].size
;;
1289 if (!arg
->attrs
) continue;
1291 LIST_FOR_EACH_ENTRY(attr
, arg
->attrs
, const attr_t
, entry
)
1293 if (attr
->type
== ATTR_DEFAULTVALUE
)
1295 else if(attr
->type
== ATTR_OPTIONAL
)
1301 funcflags
= get_func_flags(func
, &dispid
, &invokekind
, &helpcontext
, &helpstring
);
1303 if (base_offset
!= -1)
1304 chat("add_func_desc: flags %#x, dispid %#x, invokekind %d, helpcontext %#x, helpstring %s\n",
1305 funcflags
, dispid
, invokekind
, helpcontext
, helpstring
);
1307 func_desc
.magic
= 0x6c; /* always write flags to simplify calculations */
1308 func_desc
.flags
= (invokekind
<< 4) | 0x02;
1309 if (idx
& 0x80000000)
1311 func_desc
.next
= -1;
1315 func_desc
.next
= base_offset
+ sizeof(func_desc
) + arg_data_size
+ arg_count
* 2 * sizeof(short);
1316 func_desc
.name
= base_offset
!= -1 ? add_name(typelib
, func
->name
) : -1;
1317 func_desc
.dispid
= dispid
;
1318 func_desc
.helpcontext
= helpcontext
;
1319 func_desc
.helpstring
= (helpstring
&& base_offset
!= -1) ? add_name(typelib
, helpstring
) : -1;
1320 func_desc
.arg_off
= arg_count
? base_offset
+ sizeof(func_desc
) : -1;
1321 func_desc
.nacc
= (arg_count
<< 3) | 4 /* CC_STDCALL */;
1322 func_desc
.retnextopt
= (optional
<< 1);
1323 if (ret_data
.size
> sizeof(short))
1325 func_desc
.rettype
= base_offset
+ sizeof(func_desc
) + ret_desc_offset
;
1327 func_desc
.arg_off
+= ret_data
.size
;
1331 func_desc
.retnextopt
|= 0x80;
1332 func_desc
.rettype
= *(short *)ret_data
.data
;
1334 func_desc
.vtblpos
= idx
* pointer_size
;
1335 func_desc
.funcflags
= funcflags
;
1337 append_data(data
, &func_desc
, sizeof(func_desc
));
1339 arg_offset
= base_offset
+ sizeof(struct sltg_function
);
1341 if (ret_data
.size
> sizeof(short))
1343 append_data(data
, ret_data
.data
, ret_data
.size
);
1344 func_desc
.arg_off
+= ret_data
.size
;
1345 arg_offset
+= ret_data
.size
;
1352 arg_offset
+= arg_count
* 2 * sizeof(short);
1354 LIST_FOR_EACH_ENTRY(arg
, type_get_function_args(func
->type
), const var_t
, entry
)
1356 short name
, type_offset
;
1358 name
= base_offset
!= -1 ? add_name(typelib
, arg
->name
) : -1;
1360 if (arg_data
[i
].size
> sizeof(short))
1362 type_offset
= (arg_offset
+ arg_desc_offset
[i
]);
1363 arg_offset
+= arg_data
[i
].size
;
1368 type_offset
= *(short *)arg_data
[i
].data
;
1371 append_data(data
, &name
, sizeof(name
));
1372 append_data(data
, &type_offset
, sizeof(type_offset
));
1374 if (base_offset
!= -1)
1375 chat("add_func_desc: arg[%d] - name %s (%#x), type_offset %#x\n",
1376 i
, arg
->name
, name
, type_offset
);
1381 for (i
= 0; i
< arg_count
; i
++)
1383 if (arg_data
[i
].size
> sizeof(short))
1384 append_data(data
, arg_data
[i
].data
, arg_data
[i
].size
);
1388 return data
->size
- old_size
;
1391 static void write_impl_href(struct sltg_data
*data
, short href
)
1393 struct sltg_impl_info impl_info
;
1395 impl_info
.res00
= 0x004a;
1396 impl_info
.next
= -1;
1397 impl_info
.res04
= -1;
1398 impl_info
.impltypeflags
= 0;
1399 impl_info
.res07
= 0x80;
1400 impl_info
.res08
= 0x0012;
1401 impl_info
.ref
= href
;
1402 impl_info
.res0c
= 0x4001;
1403 impl_info
.res0e
= -2; /* 0xfffe */
1404 impl_info
.res10
= -1;
1405 impl_info
.res12
= 0x001d;
1408 append_data(data
, &impl_info
, sizeof(impl_info
));
1411 static void add_interface_typeinfo(struct sltg_typelib
*typelib
, type_t
*iface
)
1413 const statement_t
*stmt_func
;
1414 importinfo_t
*ref_importinfo
= NULL
;
1415 short inherit_href
= -1;
1416 struct sltg_data data
;
1417 struct sltg_hrefmap hrefmap
;
1418 const char *index_name
;
1419 struct sltg_typeinfo_header ti
;
1420 struct sltg_member_header member
;
1421 struct sltg_tail tail
;
1422 int member_offset
, base_offset
, func_data_size
, i
;
1423 int func_count
, inherited_func_count
= 0;
1424 int dispid
, inherit_level
= 0;
1426 if (iface
->typelib_idx
!= -1) return;
1428 chat("add_interface_typeinfo: type %p, type->name %s\n", iface
, iface
->name
);
1430 if (!iface
->details
.iface
)
1432 error("interface %s is referenced but not defined\n", iface
->name
);
1436 if (is_attr(iface
->attrs
, ATTR_DISPINTERFACE
))
1438 error("support for dispinterface %s is not implemented\n", iface
->name
);
1442 hrefmap
.href_count
= 0;
1443 hrefmap
.href
= NULL
;
1445 if (type_iface_get_inherit(iface
))
1449 inherit
= type_iface_get_inherit(iface
);
1451 chat("add_interface_typeinfo: inheriting from base interface %s\n", inherit
->name
);
1453 ref_importinfo
= find_importinfo(typelib
->typelib
, inherit
->name
);
1455 if (!ref_importinfo
&& type_iface_get_inherit(inherit
))
1456 add_interface_typeinfo(typelib
, inherit
);
1459 error("support for imported interfaces is not implemented\n");
1461 inherit_href
= local_href(&hrefmap
, inherit
->typelib_idx
);
1466 inherited_func_count
+= list_count(type_iface_get_stmts(inherit
));
1467 inherit
= type_iface_get_inherit(inherit
);
1471 /* check typelib_idx again, it could have been added while resolving the parent interface */
1472 if (iface
->typelib_idx
!= -1) return;
1474 iface
->typelib_idx
= typelib
->n_file_blocks
;
1476 /* pass 1: calculate function descriptions data size */
1477 init_sltg_data(&data
);
1479 STATEMENTS_FOR_EACH_FUNC(stmt_func
, type_iface_get_stmts(iface
))
1481 add_func_desc(typelib
, &data
, stmt_func
->u
.var
, -1, -1, -1, &hrefmap
);
1484 func_data_size
= data
.size
;
1486 /* pass 2: write function descriptions */
1487 init_sltg_data(&data
);
1489 func_count
= list_count(type_iface_get_stmts(iface
));
1491 index_name
= add_typeinfo_block(typelib
, iface
, TKIND_INTERFACE
);
1493 init_typeinfo(&ti
, iface
, TKIND_INTERFACE
, &hrefmap
);
1494 append_data(&data
, &ti
, sizeof(ti
));
1496 write_hrefmap(&data
, &hrefmap
);
1498 member_offset
= data
.size
;
1501 member
.res00
= 0x0001;
1502 member
.res02
= 0xffff;
1503 member
.res04
= 0x01;
1504 member
.extra
= func_data_size
;
1505 if (inherit_href
!= -1)
1507 member
.extra
+= sizeof(struct sltg_impl_info
);
1508 base_offset
+= sizeof(struct sltg_impl_info
);
1510 append_data(&data
, &member
, sizeof(member
));
1512 if (inherit_href
!= -1)
1513 write_impl_href(&data
, inherit_href
);
1516 dispid
= 0x60000000 | (inherit_level
<< 16);
1518 STATEMENTS_FOR_EACH_FUNC(stmt_func
, type_iface_get_stmts(iface
))
1520 int idx
= inherited_func_count
+ i
;
1522 if (i
== func_count
- 1) idx
|= 0x80000000;
1524 base_offset
+= add_func_desc(typelib
, &data
, stmt_func
->u
.var
,
1525 idx
, dispid
+ i
, base_offset
, &hrefmap
);
1529 init_sltg_tail(&tail
);
1531 tail
.cFuncs
= func_count
;
1533 tail
.funcs_bytes
= func_data_size
;
1534 tail
.cbSizeInstance
= pointer_size
;
1535 tail
.cbAlignment
= pointer_size
;
1536 tail
.cbSizeVft
= (inherited_func_count
+ func_count
) * pointer_size
;
1537 tail
.type_bytes
= data
.size
- member_offset
- sizeof(member
);
1540 if (inherit_href
!= -1)
1544 tail
.impls_bytes
= 0;
1546 tail
.funcs_off
+= sizeof(struct sltg_impl_info
);
1548 append_data(&data
, &tail
, sizeof(tail
));
1550 add_block(typelib
, data
.data
, data
.size
, index_name
);
1553 static void add_enum_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
1555 error("add_enum_typeinfo: %s not implemented\n", type
->name
);
1558 static void add_union_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
1560 error("add_union_typeinfo: %s not implemented\n", type
->name
);
1563 static void add_coclass_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
1565 error("add_coclass_typeinfo: %s not implemented\n", type
->name
);
1568 static void add_type_typeinfo(struct sltg_typelib
*typelib
, type_t
*type
)
1570 chat("add_type_typeinfo: adding %s, type %d\n", type
->name
, type_get_type(type
));
1572 switch (type_get_type(type
))
1574 case TYPE_INTERFACE
:
1575 add_interface_typeinfo(typelib
, type
);
1578 add_structure_typeinfo(typelib
, type
);
1581 add_enum_typeinfo(typelib
, type
);
1584 add_union_typeinfo(typelib
, type
);
1587 add_coclass_typeinfo(typelib
, type
);
1593 error("add_type_typeinfo: unhandled type %d for %s\n", type_get_type(type
), type
->name
);
1598 static void add_statement(struct sltg_typelib
*typelib
, const statement_t
*stmt
)
1606 case STMT_DECLARATION
:
1607 /* not included in typelib */
1609 case STMT_IMPORTLIB
:
1610 /* not processed here */
1615 const type_list_t
*type_entry
= stmt
->u
.type_list
;
1616 for (; type_entry
; type_entry
= type_entry
->next
)
1618 /* in old style typelibs all types are public */
1619 add_type_typeinfo(typelib
, type_entry
->type
);
1625 add_module_typeinfo(typelib
, stmt
->u
.type
);
1631 type_t
*type
= stmt
->u
.type
;
1632 add_type_typeinfo(typelib
, type
);
1637 error("add_statement: unhandled statement type %d\n", stmt
->type
);
1642 static void sltg_write_header(struct sltg_typelib
*sltg
, int *library_block_start
)
1648 short n_file_blocks
;
1650 short size_of_index
;
1656 struct sltg_block_entry
1662 struct sltg_block
*block
;
1665 header
.magic
= 0x47544c53;
1666 header
.n_file_blocks
= sltg
->n_file_blocks
+ 1;
1668 header
.size_of_index
= sltg
->index
.size
;
1669 header
.first_blk
= 1;
1670 header
.uuid
= sltg_library_guid
;
1671 header
.res1c
= 0x00000044;
1672 header
.res20
= 0xffff0000;
1674 put_data(&header
, sizeof(header
));
1676 block
= sltg
->blocks
;
1677 for (i
= 0; i
< sltg
->n_file_blocks
- 1; i
++)
1679 assert(block
->next
!= NULL
);
1681 entry
.length
= block
->length
;
1682 entry
.index_string
= block
->index_string
;
1683 entry
.next
= header
.first_blk
+ i
+ 1;
1684 chat("sltg_write_header: writing block entry %d: length %#x, index_string %#x, next %#x\n",
1685 i
, entry
.length
, entry
.index_string
, entry
.next
);
1686 put_data(&entry
, sizeof(entry
));
1688 block
= block
->next
;
1691 assert(block
->next
== NULL
);
1693 /* library block length includes helpstrings and name table */
1694 entry
.length
= block
->length
+ 0x40 + 2 + sltg
->typeinfo_size
+ 4 + 6 + 12 + 0x200 + sltg
->name_table
.size
+ 12;
1695 entry
.index_string
= block
->index_string
;
1697 chat("sltg_write_header: writing library block entry %d: length %#x, index_string %#x, next %#x\n",
1698 i
, entry
.length
, entry
.index_string
, entry
.next
);
1699 put_data(&entry
, sizeof(entry
));
1701 chat("sltg_write_header: writing index: %d bytes\n", sltg
->index
.size
);
1702 put_data(sltg
->index
.data
, sltg
->index
.size
);
1706 block
= sltg
->blocks
;
1707 for (i
= 0; i
< sltg
->n_file_blocks
- 1; i
++)
1709 chat("sltg_write_header: writing block %d: %d bytes\n", i
, block
->length
);
1711 put_data(block
->data
, block
->length
);
1712 block
= block
->next
;
1715 assert(block
->next
== NULL
);
1718 chat("library_block_start = %#lx\n", (SIZE_T
)output_buffer_pos
);
1719 *library_block_start
= output_buffer_pos
;
1720 chat("sltg_write_header: writing library block %d: %d bytes\n", i
, block
->length
);
1721 put_data(block
->data
, block
->length
);
1723 chat("sltg_write_header: writing pad 0x40 bytes\n");
1724 memset(pad
, 0xff, 0x40);
1725 put_data(pad
, 0x40);
1728 static void sltg_write_typeinfo(struct sltg_typelib
*typelib
)
1731 struct sltg_block
*block
;
1732 short count
= typelib
->typeinfo_count
;
1734 put_data(&count
, sizeof(count
));
1736 block
= typelib
->typeinfo
;
1737 for (i
= 0; i
< typelib
->typeinfo_count
; i
++)
1739 chat("sltg_write_typeinfo: writing block %d: %d bytes\n", i
, block
->length
);
1741 put_data(block
->data
, block
->length
);
1742 block
= block
->next
;
1744 assert(block
== NULL
);
1747 static void sltg_write_helpstrings(struct sltg_typelib
*typelib
)
1749 static const char dummy
[6];
1751 chat("sltg_write_helpstrings: writing dummy 6 bytes\n");
1753 put_data(dummy
, sizeof(dummy
));
1756 static void sltg_write_nametable(struct sltg_typelib
*typelib
)
1758 static const short dummy
[6] = { 0xffff,1,2,0xff00,0xffff,0xffff };
1761 chat("sltg_write_nametable: writing 12+0x200+%d bytes\n", typelib
->name_table
.size
);
1763 put_data(dummy
, sizeof(dummy
));
1764 memset(pad
, 0xff, 0x200);
1765 put_data(pad
, 0x200);
1766 put_data(&typelib
->name_table
.size
, sizeof(typelib
->name_table
.size
));
1767 put_data(typelib
->name_table
.data
, typelib
->name_table
.size
);
1770 static void sltg_write_remainder(void)
1772 static const short dummy1
[] = { 1,0xfffe,0x0a03,0,0xffff,0xffff };
1773 static const short dummy2
[] = { 0xffff,0xffff,0x0200,0,0,0 };
1774 static const char dummy3
[] = { 0xf4,0x39,0xb2,0x71,0,0,0,0,0,0,0,0,0,0,0,0 };
1775 static const char TYPELIB
[] = { 8,0,0,0,'T','Y','P','E','L','I','B',0 };
1779 put_data(&pad
, sizeof(pad
));
1781 put_data(&pad
, sizeof(pad
));
1783 put_data(dummy1
, sizeof(dummy1
));
1785 put_data(&sltg_library_guid
, sizeof(sltg_library_guid
));
1787 put_data(TYPELIB
, sizeof(TYPELIB
));
1789 put_data(dummy2
, sizeof(dummy2
));
1790 put_data(dummy3
, sizeof(dummy3
));
1793 static void save_all_changes(struct sltg_typelib
*typelib
)
1795 int library_block_start
;
1796 int *name_table_offset
;
1798 sltg_write_header(typelib
, &library_block_start
);
1799 sltg_write_typeinfo(typelib
);
1801 name_table_offset
= (int *)(output_buffer
+ output_buffer_pos
);
1802 chat("name_table_offset = %#lx\n", (SIZE_T
)output_buffer_pos
);
1803 put_data(&library_block_start
, sizeof(library_block_start
));
1805 sltg_write_helpstrings(typelib
);
1807 *name_table_offset
= output_buffer_pos
- library_block_start
;
1808 chat("*name_table_offset = %#x\n", *name_table_offset
);
1810 sltg_write_nametable(typelib
);
1811 sltg_write_remainder();
1813 if (strendswith(typelib_name
, ".res")) /* create a binary resource file */
1815 char typelib_id
[13] = "#1";
1817 expr_t
*expr
= get_attrp(typelib
->typelib
->attrs
, ATTR_ID
);
1819 sprintf(typelib_id
, "#%d", expr
->cval
);
1820 add_output_to_resources("TYPELIB", typelib_id
);
1821 output_typelib_regscript(typelib
->typelib
);
1822 flush_output_resources(typelib_name
);
1824 else flush_output_buffer(typelib_name
);
1827 int create_sltg_typelib(typelib_t
*typelib
)
1829 struct sltg_typelib sltg
;
1830 const statement_t
*stmt
;
1831 void *library_block
;
1832 int library_block_size
, library_block_index
;
1834 pointer_size
= (typelib_kind
== SYS_WIN64
) ? 8 : 4;
1836 sltg
.typelib
= typelib
;
1837 sltg
.typeinfo_count
= 0;
1838 sltg
.typeinfo_size
= 0;
1839 sltg
.typeinfo
= NULL
;
1841 sltg
.n_file_blocks
= 0;
1842 sltg
.first_block
= 1;
1844 init_index(&sltg
.index
);
1845 init_name_table(&sltg
);
1846 init_library(&sltg
);
1848 library_block
= create_library_block(&sltg
, &library_block_size
, &library_block_index
);
1851 LIST_FOR_EACH_ENTRY(stmt
, typelib
->stmts
, const statement_t
, entry
)
1852 add_statement(&sltg
, stmt
);
1854 add_block_index(&sltg
, library_block
, library_block_size
, library_block_index
);
1856 save_all_changes(&sltg
);