1 /* resbin.c -- manipulate the Windows binary resource format.
2 Copyright 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 /* This file contains functions to convert between the binary resource
23 format and the internal structures that we want to use. The same
24 binary resource format is used in both res and COFF files. */
28 #include "libiberty.h"
31 /* Macros to swap in values. */
33 #define get_16(be, s) ((be) ? bfd_getb16 (s) : bfd_getl16 (s))
34 #define get_32(be, s) ((be) ? bfd_getb32 (s) : bfd_getl32 (s))
36 /* Local functions. */
38 static void toosmall PARAMS ((const char *));
39 static unichar *get_unicode
40 PARAMS ((const unsigned char *, unsigned long, int, int *));
42 PARAMS ((struct res_id *, const unsigned char *, unsigned long, int));
43 static struct res_resource *bin_to_res_generic
44 PARAMS ((enum res_type, const unsigned char *, unsigned long));
45 static struct res_resource *bin_to_res_cursor
46 PARAMS ((const unsigned char *, unsigned long, int));
47 static struct res_resource *bin_to_res_menu
48 PARAMS ((const unsigned char *, unsigned long, int));
49 static struct menuitem *bin_to_res_menuitems
50 PARAMS ((const unsigned char *, unsigned long, int, int *));
51 static struct menuitem *bin_to_res_menuexitems
52 PARAMS ((const unsigned char *, unsigned long, int, int *));
53 static struct res_resource *bin_to_res_dialog
54 PARAMS ((const unsigned char *, unsigned long, int));
55 static struct res_resource *bin_to_res_string
56 PARAMS ((const unsigned char *, unsigned long, int));
57 static struct res_resource *bin_to_res_fontdir
58 PARAMS ((const unsigned char *, unsigned long, int));
59 static struct res_resource *bin_to_res_accelerators
60 PARAMS ((const unsigned char *, unsigned long, int));
61 static struct res_resource *bin_to_res_rcdata
62 PARAMS ((const unsigned char *, unsigned long, int));
63 static struct res_resource *bin_to_res_group_cursor
64 PARAMS ((const unsigned char *, unsigned long, int));
65 static struct res_resource *bin_to_res_group_icon
66 PARAMS ((const unsigned char *, unsigned long, int));
67 static struct res_resource *bin_to_res_version
68 PARAMS ((const unsigned char *, unsigned long, int));
69 static struct res_resource *bin_to_res_userdata
70 PARAMS ((const unsigned char *, unsigned long, int));
71 static void get_version_header
72 PARAMS ((const unsigned char *, unsigned long, int, const char *,
73 unichar **, int *, int *, int *, int *));
75 /* Given a resource type ID, a pointer to data, a length, return a
76 res_resource structure which represents that resource. The caller
77 is responsible for initializing the res_info and coff_info fields
78 of the returned structure. */
81 bin_to_res (type, data, length, big_endian)
83 const unsigned char *data;
88 return bin_to_res_userdata (data, length, big_endian);
94 return bin_to_res_userdata (data, length, big_endian);
96 return bin_to_res_cursor (data, length, big_endian);
98 return bin_to_res_generic (RES_TYPE_BITMAP, data, length);
100 return bin_to_res_generic (RES_TYPE_ICON, data, length);
102 return bin_to_res_menu (data, length, big_endian);
104 return bin_to_res_dialog (data, length, big_endian);
106 return bin_to_res_string (data, length, big_endian);
108 return bin_to_res_fontdir (data, length, big_endian);
110 return bin_to_res_generic (RES_TYPE_FONT, data, length);
112 return bin_to_res_accelerators (data, length, big_endian);
114 return bin_to_res_rcdata (data, length, big_endian);
115 case RT_MESSAGETABLE:
116 return bin_to_res_generic (RES_TYPE_MESSAGETABLE, data, length);
117 case RT_GROUP_CURSOR:
118 return bin_to_res_group_cursor (data, length, big_endian);
120 return bin_to_res_group_icon (data, length, big_endian);
122 return bin_to_res_version (data, length, big_endian);
127 /* Give an error if the binary data is too small. */
133 fatal (_("%s: not enough binary data"), msg);
136 /* Swap in a NULL terminated unicode string. */
139 get_unicode (data, length, big_endian, retlen)
140 const unsigned char *data;
141 unsigned long length;
151 if (length < (unsigned long) c * 2 + 2)
152 toosmall (_("null terminated unicode string"));
153 if (get_16 (big_endian, data + c * 2) == 0)
158 ret = (unichar *) res_alloc ((c + 1) * sizeof (unichar));
160 for (i = 0; i < c; i++)
161 ret[i] = get_16 (big_endian, data + i * 2);
170 /* Get a resource identifier. This returns the number of bytes used. */
173 get_resid (id, data, length, big_endian)
175 const unsigned char *data;
176 unsigned long length;
182 toosmall (_("resource ID"));
184 first = get_16 (big_endian, data);
188 toosmall (_("resource ID"));
190 id->u.id = get_16 (big_endian, data + 2);
196 id->u.n.name = get_unicode (data, length, big_endian, &id->u.n.length);
197 return id->u.n.length * 2 + 2;
201 /* Convert a resource which just stores uninterpreted data from
204 struct res_resource *
205 bin_to_res_generic (type, data, length)
207 const unsigned char *data;
208 unsigned long length;
210 struct res_resource *r;
212 r = (struct res_resource *) res_alloc (sizeof *r);
214 r->u.data.data = data;
215 r->u.data.length = length;
220 /* Convert a cursor resource from binary. */
222 struct res_resource *
223 bin_to_res_cursor (data, length, big_endian)
224 const unsigned char *data;
225 unsigned long length;
229 struct res_resource *r;
232 toosmall (_("cursor"));
234 c = (struct cursor *) res_alloc (sizeof *c);
235 c->xhotspot = get_16 (big_endian, data);
236 c->yhotspot = get_16 (big_endian, data + 2);
237 c->length = length - 4;
240 r = (struct res_resource *) res_alloc (sizeof *r);
241 r->type = RES_TYPE_CURSOR;
247 /* Convert a menu resource from binary. */
249 struct res_resource *
250 bin_to_res_menu (data, length, big_endian)
251 const unsigned char *data;
252 unsigned long length;
255 struct res_resource *r;
259 r = (struct res_resource *) res_alloc (sizeof *r);
260 r->type = RES_TYPE_MENU;
262 m = (struct menu *) res_alloc (sizeof *m);
266 toosmall (_("menu header"));
268 version = get_16 (big_endian, data);
273 toosmall (_("menu header"));
275 m->items = bin_to_res_menuitems (data + 4, length - 4, big_endian,
278 else if (version == 1)
283 toosmall (_("menuex header"));
284 m->help = get_32 (big_endian, data + 4);
285 offset = get_16 (big_endian, data + 2);
286 if (offset + 4 >= length)
287 toosmall (_("menuex offset"));
288 m->items = bin_to_res_menuexitems (data + 4 + offset,
289 length - (4 + offset),
294 fatal (_("unsupported menu version %d"), version);
299 /* Convert menu items from binary. */
301 static struct menuitem *
302 bin_to_res_menuitems (data, length, big_endian, read)
303 const unsigned char *data;
304 unsigned long length;
308 struct menuitem *first, **pp;
317 int flags, slen, itemlen;
322 toosmall (_("menuitem header"));
324 mi = (struct menuitem *) res_alloc (sizeof *mi);
328 flags = get_16 (big_endian, data);
329 mi->type = flags &~ (MENUITEM_POPUP | MENUITEM_ENDMENU);
331 if ((flags & MENUITEM_POPUP) == 0)
336 if (length < stroff + 2)
337 toosmall (_("menuitem header"));
339 if (get_16 (big_endian, data + stroff) == 0)
345 mi->text = get_unicode (data + stroff, length - stroff, big_endian,
348 itemlen = stroff + slen * 2 + 2;
350 if ((flags & MENUITEM_POPUP) == 0)
353 mi->id = get_16 (big_endian, data + 2);
360 mi->popup = bin_to_res_menuitems (data + itemlen, length - itemlen,
361 big_endian, &subread);
373 if ((flags & MENUITEM_ENDMENU) != 0)
380 /* Convert menuex items from binary. */
382 static struct menuitem *
383 bin_to_res_menuexitems (data, length, big_endian, read)
384 const unsigned char *data;
385 unsigned long length;
389 struct menuitem *first, **pp;
399 unsigned int itemlen;
403 toosmall (_("menuitem header"));
405 mi = (struct menuitem *) res_alloc (sizeof *mi);
406 mi->type = get_32 (big_endian, data);
407 mi->state = get_32 (big_endian, data + 4);
408 mi->id = get_16 (big_endian, data + 8);
410 flags = get_16 (big_endian, data + 10);
412 if (get_16 (big_endian, data + 12) == 0)
418 mi->text = get_unicode (data + 12, length - 12, big_endian, &slen);
420 itemlen = 12 + slen * 2 + 2;
421 itemlen = (itemlen + 3) &~ 3;
423 if ((flags & 1) == 0)
432 if (length < itemlen + 4)
433 toosmall (_("menuitem"));
434 mi->help = get_32 (big_endian, data + itemlen);
437 mi->popup = bin_to_res_menuexitems (data + itemlen,
439 big_endian, &subread);
451 if ((flags & 0x80) != 0)
458 /* Convert a dialog resource from binary. */
460 static struct res_resource *
461 bin_to_res_dialog (data, length, big_endian)
462 const unsigned char *data;
463 unsigned long length;
470 struct dialog_control **pp;
471 struct res_resource *r;
474 toosmall (_("dialog header"));
476 d = (struct dialog *) res_alloc (sizeof *d);
478 signature = get_16 (big_endian, data + 2);
479 if (signature != 0xffff)
482 d->style = get_32 (big_endian, data);
483 d->exstyle = get_32 (big_endian, data + 4);
490 version = get_16 (big_endian, data);
492 fatal (_("unexpected DIALOGEX version %d"), version);
494 d->ex = (struct dialog_ex *) res_alloc (sizeof (struct dialog_ex));
495 d->ex->help = get_32 (big_endian, data + 4);
496 d->exstyle = get_32 (big_endian, data + 8);
497 d->style = get_32 (big_endian, data + 12);
501 if (length < off + 10)
502 toosmall (_("dialog header"));
504 c = get_16 (big_endian, data + off);
505 d->x = get_16 (big_endian, data + off + 2);
506 d->y = get_16 (big_endian, data + off + 4);
507 d->width = get_16 (big_endian, data + off + 6);
508 d->height = get_16 (big_endian, data + off + 8);
512 sublen = get_resid (&d->menu, data + off, length - off, big_endian);
515 sublen = get_resid (&d->class, data + off, length - off, big_endian);
518 d->caption = get_unicode (data + off, length - off, big_endian, &sublen);
519 off += sublen * 2 + 2;
521 if ((d->style & DS_SETFONT) == 0)
533 if (length < off + 2)
534 toosmall (_("dialog font point size"));
536 d->pointsize = get_16 (big_endian, data + off);
541 if (length < off + 4)
542 toosmall (_("dialogex font information"));
543 d->ex->weight = get_16 (big_endian, data + off);
544 d->ex->italic = get_16 (big_endian, data + off + 2);
548 d->font = get_unicode (data + off, length - off, big_endian, &sublen);
549 off += sublen * 2 + 2;
555 for (i = 0; i < c; i++)
557 struct dialog_control *dc;
560 off = (off + 3) &~ 3;
562 dc = (struct dialog_control *) res_alloc (sizeof *dc);
566 if (length < off + 8)
567 toosmall (_("dialog control"));
569 dc->style = get_32 (big_endian, data + off);
570 dc->exstyle = get_32 (big_endian, data + off + 4);
576 if (length < off + 12)
577 toosmall (_("dialogex control"));
578 dc->help = get_32 (big_endian, data + off);
579 dc->exstyle = get_32 (big_endian, data + off + 4);
580 dc->style = get_32 (big_endian, data + off + 8);
584 if (length < off + 10)
585 toosmall (_("dialog control"));
587 dc->x = get_16 (big_endian, data + off);
588 dc->y = get_16 (big_endian, data + off + 2);
589 dc->width = get_16 (big_endian, data + off + 4);
590 dc->height = get_16 (big_endian, data + off + 6);
593 dc->id = get_32 (big_endian, data + off + 8);
595 dc->id = get_16 (big_endian, data + off + 8);
597 off += 10 + (d->ex != NULL ? 2 : 0);
599 sublen = get_resid (&dc->class, data + off, length - off, big_endian);
602 sublen = get_resid (&dc->text, data + off, length - off, big_endian);
605 if (length < off + 2)
606 toosmall (_("dialog control end"));
608 datalen = get_16 (big_endian, data + off);
615 off = (off + 3) &~ 3;
617 if (length < off + datalen)
618 toosmall (_("dialog control data"));
620 dc->data = ((struct rcdata_item *)
621 res_alloc (sizeof (struct rcdata_item)));
622 dc->data->next = NULL;
623 dc->data->type = RCDATA_BUFFER;
624 dc->data->u.buffer.length = datalen;
625 dc->data->u.buffer.data = data + off;
635 r = (struct res_resource *) res_alloc (sizeof *r);
636 r->type = RES_TYPE_DIALOG;
642 /* Convert a stringtable resource from binary. */
644 static struct res_resource *
645 bin_to_res_string (data, length, big_endian)
646 const unsigned char *data;
647 unsigned long length;
650 struct stringtable *st;
652 struct res_resource *r;
654 st = (struct stringtable *) res_alloc (sizeof *st);
656 for (i = 0; i < 16; i++)
661 toosmall (_("stringtable string length"));
662 slen = get_16 (big_endian, data);
663 st->strings[i].length = slen;
670 if (length < 2 + 2 * slen)
671 toosmall (_("stringtable string"));
673 s = (unichar *) res_alloc (slen * sizeof (unichar));
674 st->strings[i].string = s;
676 for (j = 0; j < slen; j++)
677 s[j] = get_16 (big_endian, data + 2 + j * 2);
680 data += 2 + 2 * slen;
681 length -= 2 + 2 * slen;
684 r = (struct res_resource *) res_alloc (sizeof *r);
685 r->type = RES_TYPE_STRINGTABLE;
686 r->u.stringtable = st;
691 /* Convert a fontdir resource from binary. */
693 static struct res_resource *
694 bin_to_res_fontdir (data, length, big_endian)
695 const unsigned char *data;
696 unsigned long length;
700 struct fontdir *first, **pp;
701 struct res_resource *r;
704 toosmall (_("fontdir header"));
706 c = get_16 (big_endian, data);
711 for (i = 0; i < c; i++)
717 toosmall (_("fontdir"));
719 fd = (struct fontdir *) res_alloc (sizeof *fd);
720 fd->index = get_16 (big_endian, data);
722 /* To work out the length of the fontdir data, we must get the
723 length of the device name and face name strings, even though
724 we don't store them in the fontdir structure. The
725 documentation says that these are NULL terminated char
726 strings, not Unicode strings. */
730 while (off < length && data[off] != '\0')
733 toosmall (_("fontdir device name"));
736 while (off < length && data[off] != '\0')
739 toosmall (_("fontdir face name"));
749 /* The documentation does not indicate that any rounding is
756 r = (struct res_resource *) res_alloc (sizeof *r);
757 r->type = RES_TYPE_FONTDIR;
758 r->u.fontdir = first;
763 /* Convert an accelerators resource from binary. */
765 static struct res_resource *
766 bin_to_res_accelerators (data, length, big_endian)
767 const unsigned char *data;
768 unsigned long length;
771 struct accelerator *first, **pp;
772 struct res_resource *r;
779 struct accelerator *a;
782 toosmall (_("accelerator"));
784 a = (struct accelerator *) res_alloc (sizeof *a);
786 a->flags = get_16 (big_endian, data);
787 a->key = get_16 (big_endian, data + 2);
788 a->id = get_16 (big_endian, data + 4);
794 if ((a->flags & ACC_LAST) != 0)
801 r = (struct res_resource *) res_alloc (sizeof *r);
802 r->type = RES_TYPE_ACCELERATOR;
808 /* Convert an rcdata resource from binary. */
810 static struct res_resource *
811 bin_to_res_rcdata (data, length, big_endian)
812 const unsigned char *data;
813 unsigned long length;
814 int big_endian ATTRIBUTE_UNUSED;
816 struct rcdata_item *ri;
817 struct res_resource *r;
819 ri = (struct rcdata_item *) res_alloc (sizeof *ri);
822 ri->type = RCDATA_BUFFER;
823 ri->u.buffer.length = length;
824 ri->u.buffer.data = data;
826 r = (struct res_resource *) res_alloc (sizeof *r);
827 r->type = RES_TYPE_RCDATA;
833 /* Convert a group cursor resource from binary. */
835 static struct res_resource *
836 bin_to_res_group_cursor (data, length, big_endian)
837 const unsigned char *data;
838 unsigned long length;
842 struct group_cursor *first, **pp;
843 struct res_resource *r;
846 toosmall (_("group cursor header"));
848 type = get_16 (big_endian, data + 2);
850 fatal (_("unexpected group cursor type %d"), type);
852 c = get_16 (big_endian, data + 4);
860 for (i = 0; i < c; i++)
862 struct group_cursor *gc;
865 toosmall (_("group cursor"));
867 gc = (struct group_cursor *) res_alloc (sizeof *gc);
869 gc->width = get_16 (big_endian, data);
870 gc->height = get_16 (big_endian, data + 2);
871 gc->planes = get_16 (big_endian, data + 4);
872 gc->bits = get_16 (big_endian, data + 6);
873 gc->bytes = get_32 (big_endian, data + 8);
874 gc->index = get_16 (big_endian, data + 12);
884 r = (struct res_resource *) res_alloc (sizeof *r);
885 r->type = RES_TYPE_GROUP_CURSOR;
886 r->u.group_cursor = first;
891 /* Convert a group icon resource from binary. */
893 static struct res_resource *
894 bin_to_res_group_icon (data, length, big_endian)
895 const unsigned char *data;
896 unsigned long length;
900 struct group_icon *first, **pp;
901 struct res_resource *r;
904 toosmall (_("group icon header"));
906 type = get_16 (big_endian, data + 2);
908 fatal (_("unexpected group icon type %d"), type);
910 c = get_16 (big_endian, data + 4);
918 for (i = 0; i < c; i++)
920 struct group_icon *gi;
923 toosmall (_("group icon"));
925 gi = (struct group_icon *) res_alloc (sizeof *gi);
928 gi->height = data[1];
929 gi->colors = data[2];
930 gi->planes = get_16 (big_endian, data + 4);
931 gi->bits = get_16 (big_endian, data + 6);
932 gi->bytes = get_32 (big_endian, data + 8);
933 gi->index = get_16 (big_endian, data + 12);
943 r = (struct res_resource *) res_alloc (sizeof *r);
944 r->type = RES_TYPE_GROUP_ICON;
945 r->u.group_icon = first;
950 /* Extract data from a version header. If KEY is not NULL, then the
951 key must be KEY; otherwise, the key is returned in *PKEY. This
952 sets *LEN to the total length, *VALLEN to the value length, *TYPE
953 to the type, and *OFF to the offset to the children. */
956 get_version_header (data, length, big_endian, key, pkey, len, vallen, type,
958 const unsigned char *data;
959 unsigned long length;
971 *len = get_16 (big_endian, data);
972 *vallen = get_16 (big_endian, data + 2);
973 *type = get_16 (big_endian, data + 4);
984 *pkey = get_unicode (data, length, big_endian, &sublen);
985 *off += sublen * 2 + 2;
993 if (get_16 (big_endian, data) != (unsigned char) *key)
994 fatal (_("unexpected version string"));
1007 *off = (*off + 3) &~ 3;
1010 /* Convert a version resource from binary. */
1012 static struct res_resource *
1013 bin_to_res_version (data, length, big_endian)
1014 const unsigned char *data;
1015 unsigned long length;
1018 int verlen, vallen, type, off;
1019 struct fixed_versioninfo *fi;
1020 struct ver_info *first, **pp;
1021 struct versioninfo *v;
1022 struct res_resource *r;
1024 get_version_header (data, length, big_endian, "VS_VERSION_INFO",
1025 (unichar **) NULL, &verlen, &vallen, &type, &off);
1027 if ((unsigned int) verlen != length)
1028 fatal (_("version length %d does not match resource length %lu"),
1032 fatal (_("unexpected version type %d"), type);
1041 unsigned long signature, fiv;
1044 fatal (_("unexpected fixed version information length %d"), vallen);
1047 toosmall (_("fixed version info"));
1049 signature = get_32 (big_endian, data);
1050 if (signature != 0xfeef04bd)
1051 fatal (_("unexpected fixed version signature %lu"), signature);
1053 fiv = get_32 (big_endian, data + 4);
1054 if (fiv != 0 && fiv != 0x10000)
1055 fatal (_("unexpected fixed version info version %lu"), fiv);
1057 fi = (struct fixed_versioninfo *) res_alloc (sizeof *fi);
1059 fi->file_version_ms = get_32 (big_endian, data + 8);
1060 fi->file_version_ls = get_32 (big_endian, data + 12);
1061 fi->product_version_ms = get_32 (big_endian, data + 16);
1062 fi->product_version_ls = get_32 (big_endian, data + 20);
1063 fi->file_flags_mask = get_32 (big_endian, data + 24);
1064 fi->file_flags = get_32 (big_endian, data + 28);
1065 fi->file_os = get_32 (big_endian, data + 32);
1066 fi->file_type = get_32 (big_endian, data + 36);
1067 fi->file_subtype = get_32 (big_endian, data + 40);
1068 fi->file_date_ms = get_32 (big_endian, data + 44);
1069 fi->file_date_ls = get_32 (big_endian, data + 48);
1080 struct ver_info *vi;
1084 toosmall (_("version var info"));
1086 vi = (struct ver_info *) res_alloc (sizeof *vi);
1088 ch = get_16 (big_endian, data + 6);
1092 struct ver_stringinfo **ppvs;
1094 vi->type = VERINFO_STRING;
1096 get_version_header (data, length, big_endian, "StringFileInfo",
1097 (unichar **) NULL, &verlen, &vallen, &type,
1101 fatal (_("unexpected stringfileinfo value length %d"), vallen);
1106 get_version_header (data, length, big_endian, (const char *) NULL,
1107 &vi->u.string.language, &verlen, &vallen,
1111 fatal (_("unexpected version stringtable value length %d"), vallen);
1117 vi->u.string.strings = NULL;
1118 ppvs = &vi->u.string.strings;
1120 /* It's convenient to round verlen to a 4 byte alignment,
1121 since we round the subvariables in the loop. */
1122 verlen = (verlen + 3) &~ 3;
1126 struct ver_stringinfo *vs;
1127 int subverlen, vslen, valoff;
1129 vs = (struct ver_stringinfo *) res_alloc (sizeof *vs);
1131 get_version_header (data, length, big_endian,
1132 (const char *) NULL, &vs->key, &subverlen,
1133 &vallen, &type, &off);
1135 subverlen = (subverlen + 3) &~ 3;
1140 vs->value = get_unicode (data, length, big_endian, &vslen);
1141 valoff = vslen * 2 + 2;
1142 valoff = (valoff + 3) &~ 3;
1144 if (off + valoff != subverlen)
1145 fatal (_("unexpected version string length %d != %d + %d"),
1146 subverlen, off, valoff);
1155 if (verlen < subverlen)
1156 fatal (_("unexpected version string length %d < %d"),
1159 verlen -= subverlen;
1164 struct ver_varinfo **ppvv;
1166 vi->type = VERINFO_VAR;
1168 get_version_header (data, length, big_endian, "VarFileInfo",
1169 (unichar **) NULL, &verlen, &vallen, &type,
1173 fatal (_("unexpected varfileinfo value length %d"), vallen);
1178 get_version_header (data, length, big_endian, (const char *) NULL,
1179 &vi->u.var.key, &verlen, &vallen, &type, &off);
1184 vi->u.var.var = NULL;
1185 ppvv = &vi->u.var.var;
1189 struct ver_varinfo *vv;
1192 toosmall (_("version varfileinfo"));
1194 vv = (struct ver_varinfo *) res_alloc (sizeof *vv);
1196 vv->language = get_16 (big_endian, data);
1197 vv->charset = get_16 (big_endian, data + 2);
1207 fatal (_("unexpected version value length %d"), vallen);
1213 fatal (_("unexpected version string"));
1220 v = (struct versioninfo *) res_alloc (sizeof *v);
1224 r = (struct res_resource *) res_alloc (sizeof *r);
1225 r->type = RES_TYPE_VERSIONINFO;
1226 r->u.versioninfo = v;
1231 /* Convert an arbitrary user defined resource from binary. */
1233 static struct res_resource *
1234 bin_to_res_userdata (data, length, big_endian)
1235 const unsigned char *data;
1236 unsigned long length;
1237 int big_endian ATTRIBUTE_UNUSED;
1239 struct rcdata_item *ri;
1240 struct res_resource *r;
1242 ri = (struct rcdata_item *) res_alloc (sizeof *ri);
1245 ri->type = RCDATA_BUFFER;
1246 ri->u.buffer.length = length;
1247 ri->u.buffer.data = data;
1249 r = (struct res_resource *) res_alloc (sizeof *r);
1250 r->type = RES_TYPE_USERDATA;
1256 /* Macros to swap out values. */
1258 #define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
1259 #define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
1261 /* Local functions used to convert resources to binary format. */
1263 static void dword_align_bin PARAMS ((struct bindata ***, unsigned long *));
1264 static struct bindata *resid_to_bin PARAMS ((struct res_id, int));
1265 static struct bindata *unicode_to_bin PARAMS ((const unichar *, int));
1266 static struct bindata *res_to_bin_accelerator
1267 PARAMS ((const struct accelerator *, int));
1268 static struct bindata *res_to_bin_cursor
1269 PARAMS ((const struct cursor *, int));
1270 static struct bindata *res_to_bin_group_cursor
1271 PARAMS ((const struct group_cursor *, int));
1272 static struct bindata *res_to_bin_dialog
1273 PARAMS ((const struct dialog *, int));
1274 static struct bindata *res_to_bin_fontdir
1275 PARAMS ((const struct fontdir *, int));
1276 static struct bindata *res_to_bin_group_icon
1277 PARAMS ((const struct group_icon *, int));
1278 static struct bindata *res_to_bin_menu
1279 PARAMS ((const struct menu *, int));
1280 static struct bindata *res_to_bin_menuitems
1281 PARAMS ((const struct menuitem *, int));
1282 static struct bindata *res_to_bin_menuexitems
1283 PARAMS ((const struct menuitem *, int));
1284 static struct bindata *res_to_bin_rcdata
1285 PARAMS ((const struct rcdata_item *, int));
1286 static struct bindata *res_to_bin_stringtable
1287 PARAMS ((const struct stringtable *, int));
1288 static struct bindata *string_to_unicode_bin PARAMS ((const char *, int));
1289 static struct bindata *res_to_bin_versioninfo
1290 PARAMS ((const struct versioninfo *, int));
1291 static struct bindata *res_to_bin_generic
1292 PARAMS ((unsigned long, const unsigned char *));
1294 /* Convert a resource to binary. */
1297 res_to_bin (res, big_endian)
1298 const struct res_resource *res;
1305 case RES_TYPE_BITMAP:
1308 case RES_TYPE_MESSAGETABLE:
1309 return res_to_bin_generic (res->u.data.length, res->u.data.data);
1310 case RES_TYPE_ACCELERATOR:
1311 return res_to_bin_accelerator (res->u.acc, big_endian);
1312 case RES_TYPE_CURSOR:
1313 return res_to_bin_cursor (res->u.cursor, big_endian);
1314 case RES_TYPE_GROUP_CURSOR:
1315 return res_to_bin_group_cursor (res->u.group_cursor, big_endian);
1316 case RES_TYPE_DIALOG:
1317 return res_to_bin_dialog (res->u.dialog, big_endian);
1318 case RES_TYPE_FONTDIR:
1319 return res_to_bin_fontdir (res->u.fontdir, big_endian);
1320 case RES_TYPE_GROUP_ICON:
1321 return res_to_bin_group_icon (res->u.group_icon, big_endian);
1323 return res_to_bin_menu (res->u.menu, big_endian);
1324 case RES_TYPE_RCDATA:
1325 return res_to_bin_rcdata (res->u.rcdata, big_endian);
1326 case RES_TYPE_STRINGTABLE:
1327 return res_to_bin_stringtable (res->u.stringtable, big_endian);
1328 case RES_TYPE_USERDATA:
1329 return res_to_bin_rcdata (res->u.rcdata, big_endian);
1330 case RES_TYPE_VERSIONINFO:
1331 return res_to_bin_versioninfo (res->u.versioninfo, big_endian);
1335 /* Align to a 32 bit boundary. PPP points to the of a list of bindata
1336 structures. LENGTH points to the length of the structures. If
1337 necessary, this adds a new bindata to bring length up to a 32 bit
1338 boundary. It updates *PPP and *LENGTH. */
1341 dword_align_bin (ppp, length)
1342 struct bindata ***ppp;
1343 unsigned long *length;
1348 if ((*length & 3) == 0)
1351 add = 4 - (*length & 3);
1353 d = (struct bindata *) reswr_alloc (sizeof *d);
1355 d->data = (unsigned char *) reswr_alloc (add);
1356 memset (d->data, 0, add);
1360 *ppp = &(**ppp)->next;
1365 /* Convert a resource ID to binary. This always returns exactly one
1366 bindata structure. */
1368 static struct bindata *
1369 resid_to_bin (id, big_endian)
1375 d = (struct bindata *) reswr_alloc (sizeof *d);
1380 d->data = (unsigned char *) reswr_alloc (4);
1381 put_16 (big_endian, 0xffff, d->data);
1382 put_16 (big_endian, id.u.id, d->data + 2);
1388 d->length = id.u.n.length * 2 + 2;
1389 d->data = (unsigned char *) reswr_alloc (d->length);
1390 for (i = 0; i < id.u.n.length; i++)
1391 put_16 (big_endian, id.u.n.name[i], d->data + i * 2);
1392 put_16 (big_endian, 0, d->data + i * 2);
1400 /* Convert a null terminated unicode string to binary. This always
1401 returns exactly one bindata structure. */
1403 static struct bindata *
1404 unicode_to_bin (str, big_endian)
1416 for (s = str; *s != 0; s++)
1420 d = (struct bindata *) reswr_alloc (sizeof *d);
1421 d->length = len * 2 + 2;
1422 d->data = (unsigned char *) reswr_alloc (d->length);
1425 put_16 (big_endian, 0, d->data);
1431 for (s = str, i = 0; *s != 0; s++, i++)
1432 put_16 (big_endian, *s, d->data + i * 2);
1433 put_16 (big_endian, 0, d->data + i * 2);
1441 /* Convert an accelerator resource to binary. */
1443 static struct bindata *
1444 res_to_bin_accelerator (accelerators, big_endian)
1445 const struct accelerator *accelerators;
1448 struct bindata *first, **pp;
1449 const struct accelerator *a;
1454 for (a = accelerators; a != NULL; a = a->next)
1458 d = (struct bindata *) reswr_alloc (sizeof *d);
1460 d->data = (unsigned char *) reswr_alloc (8);
1463 a->flags | (a->next != NULL ? 0 : ACC_LAST),
1465 put_16 (big_endian, a->key, d->data + 2);
1466 put_16 (big_endian, a->id, d->data + 4);
1467 put_16 (big_endian, 0, d->data + 8);
1477 /* Convert a cursor resource to binary. */
1479 static struct bindata *
1480 res_to_bin_cursor (c, big_endian)
1481 const struct cursor *c;
1486 d = (struct bindata *) reswr_alloc (sizeof *d);
1488 d->data = (unsigned char *) reswr_alloc (4);
1490 put_16 (big_endian, c->xhotspot, d->data);
1491 put_16 (big_endian, c->yhotspot, d->data + 2);
1493 d->next = (struct bindata *) reswr_alloc (sizeof *d);
1494 d->next->length = c->length;
1495 d->next->data = (unsigned char *) c->data;
1496 d->next->next = NULL;
1501 /* Convert a group cursor resource to binary. */
1503 static struct bindata *
1504 res_to_bin_group_cursor (group_cursors, big_endian)
1505 const struct group_cursor *group_cursors;
1508 struct bindata *first, **pp;
1510 const struct group_cursor *gc;
1512 first = (struct bindata *) reswr_alloc (sizeof *first);
1514 first->data = (unsigned char *) reswr_alloc (6);
1516 put_16 (big_endian, 0, first->data);
1517 put_16 (big_endian, 2, first->data + 2);
1523 for (gc = group_cursors; gc != NULL; gc = gc->next)
1529 d = (struct bindata *) reswr_alloc (sizeof *d);
1531 d->data = (unsigned char *) reswr_alloc (14);
1533 put_16 (big_endian, gc->width, d->data);
1534 put_16 (big_endian, gc->height, d->data + 2);
1535 put_16 (big_endian, gc->planes, d->data + 4);
1536 put_16 (big_endian, gc->bits, d->data + 6);
1537 put_32 (big_endian, gc->bytes, d->data + 8);
1538 put_16 (big_endian, gc->index, d->data + 12);
1545 put_16 (big_endian, c, first->data + 4);
1550 /* Convert a dialog resource to binary. */
1552 static struct bindata *
1553 res_to_bin_dialog (dialog, big_endian)
1554 const struct dialog *dialog;
1558 struct bindata *first, **pp;
1559 unsigned long length;
1561 struct dialog_control *dc;
1563 dialogex = extended_dialog (dialog);
1565 first = (struct bindata *) reswr_alloc (sizeof *first);
1566 first->length = dialogex ? 26 : 18;
1567 first->data = (unsigned char *) reswr_alloc (first->length);
1569 length = first->length;
1573 put_32 (big_endian, dialog->style, first->data);
1574 put_32 (big_endian, dialog->exstyle, first->data + 4);
1579 put_16 (big_endian, 1, first->data);
1580 put_16 (big_endian, 0xffff, first->data + 2);
1582 if (dialog->ex == NULL)
1583 put_32 (big_endian, 0, first->data + 4);
1585 put_32 (big_endian, dialog->ex->help, first->data + 4);
1586 put_32 (big_endian, dialog->exstyle, first->data + 8);
1587 put_32 (big_endian, dialog->style, first->data + 12);
1591 put_16 (big_endian, dialog->x, first->data + off + 2);
1592 put_16 (big_endian, dialog->y, first->data + off + 4);
1593 put_16 (big_endian, dialog->width, first->data + off + 6);
1594 put_16 (big_endian, dialog->height, first->data + off + 8);
1598 *pp = resid_to_bin (dialog->menu, big_endian);
1599 length += (*pp)->length;
1602 *pp = resid_to_bin (dialog->class, big_endian);
1603 length += (*pp)->length;
1606 *pp = unicode_to_bin (dialog->caption, big_endian);
1607 length += (*pp)->length;
1610 if ((dialog->style & DS_SETFONT) != 0)
1614 d = (struct bindata *) reswr_alloc (sizeof *d);
1615 d->length = dialogex ? 6 : 2;
1616 d->data = (unsigned char *) reswr_alloc (d->length);
1618 length += d->length;
1620 put_16 (big_endian, dialog->pointsize, d->data);
1624 if (dialog->ex == NULL)
1626 put_16 (big_endian, 0, d->data + 2);
1627 put_16 (big_endian, 0, d->data + 4);
1631 put_16 (big_endian, dialog->ex->weight, d->data + 2);
1632 put_16 (big_endian, dialog->ex->italic, d->data + 4);
1639 *pp = unicode_to_bin (dialog->font, big_endian);
1640 length += (*pp)->length;
1645 for (dc = dialog->controls; dc != NULL; dc = dc->next)
1652 dword_align_bin (&pp, &length);
1654 d = (struct bindata *) reswr_alloc (sizeof *d);
1655 d->length = dialogex ? 24 : 18;
1656 d->data = (unsigned char *) reswr_alloc (d->length);
1658 length += d->length;
1662 put_32 (big_endian, dc->style, d->data);
1663 put_32 (big_endian, dc->exstyle, d->data + 4);
1668 put_32 (big_endian, dc->help, d->data);
1669 put_32 (big_endian, dc->exstyle, d->data + 4);
1670 put_32 (big_endian, dc->style, d->data + 8);
1674 put_16 (big_endian, dc->x, d->data + dcoff);
1675 put_16 (big_endian, dc->y, d->data + dcoff + 2);
1676 put_16 (big_endian, dc->width, d->data + dcoff + 4);
1677 put_16 (big_endian, dc->height, d->data + dcoff + 6);
1680 put_32 (big_endian, dc->id, d->data + dcoff + 8);
1682 put_16 (big_endian, dc->id, d->data + dcoff + 8);
1687 *pp = resid_to_bin (dc->class, big_endian);
1688 length += (*pp)->length;
1691 *pp = resid_to_bin (dc->text, big_endian);
1692 length += (*pp)->length;
1695 d = (struct bindata *) reswr_alloc (sizeof *d);
1697 d->data = (unsigned char *) reswr_alloc (2);
1705 if (dc->data == NULL)
1706 put_16 (big_endian, 0, d->data);
1709 unsigned long sublen;
1711 dword_align_bin (&pp, &length);
1713 *pp = res_to_bin_rcdata (dc->data, big_endian);
1717 sublen += (*pp)->length;
1721 put_16 (big_endian, sublen, d->data);
1726 put_16 (big_endian, c, first->data + off);
1731 /* Convert a fontdir resource to binary. */
1733 static struct bindata *
1734 res_to_bin_fontdir (fontdirs, big_endian)
1735 const struct fontdir *fontdirs;
1738 struct bindata *first, **pp;
1740 const struct fontdir *fd;
1742 first = (struct bindata *) reswr_alloc (sizeof *first);
1744 first->data = (unsigned char *) reswr_alloc (2);
1750 for (fd = fontdirs; fd != NULL; fd = fd->next)
1756 d = (struct bindata *) reswr_alloc (sizeof *d);
1758 d->data = (unsigned char *) reswr_alloc (2);
1760 put_16 (big_endian, fd->index, d->data);
1765 d = (struct bindata *) reswr_alloc (sizeof *d);
1766 d->length = fd->length;
1767 d->data = (unsigned char *) fd->data;
1774 put_16 (big_endian, c, first->data);
1779 /* Convert a group icon resource to binary. */
1781 static struct bindata *
1782 res_to_bin_group_icon (group_icons, big_endian)
1783 const struct group_icon *group_icons;
1786 struct bindata *first, **pp;
1788 const struct group_icon *gi;
1790 first = (struct bindata *) reswr_alloc (sizeof *first);
1792 first->data = (unsigned char *) reswr_alloc (6);
1794 put_16 (big_endian, 0, first->data);
1795 put_16 (big_endian, 1, first->data + 2);
1801 for (gi = group_icons; gi != NULL; gi = gi->next)
1807 d = (struct bindata *) reswr_alloc (sizeof *d);
1809 d->data = (unsigned char *) reswr_alloc (14);
1811 d->data[0] = gi->width;
1812 d->data[1] = gi->height;
1813 d->data[2] = gi->colors;
1815 put_16 (big_endian, gi->planes, d->data + 4);
1816 put_16 (big_endian, gi->bits, d->data + 6);
1817 put_32 (big_endian, gi->bytes, d->data + 8);
1818 put_16 (big_endian, gi->index, d->data + 12);
1825 put_16 (big_endian, c, first->data + 4);
1830 /* Convert a menu resource to binary. */
1832 static struct bindata *
1833 res_to_bin_menu (menu, big_endian)
1834 const struct menu *menu;
1840 menuex = extended_menu (menu);
1842 d = (struct bindata *) reswr_alloc (sizeof *d);
1843 d->length = menuex ? 8 : 4;
1844 d->data = (unsigned char *) reswr_alloc (d->length);
1848 put_16 (big_endian, 0, d->data);
1849 put_16 (big_endian, 0, d->data + 2);
1851 d->next = res_to_bin_menuitems (menu->items, big_endian);
1855 put_16 (big_endian, 1, d->data);
1856 put_16 (big_endian, 4, d->data + 2);
1857 put_32 (big_endian, menu->help, d->data + 4);
1859 d->next = res_to_bin_menuexitems (menu->items, big_endian);
1865 /* Convert menu items to binary. */
1867 static struct bindata *
1868 res_to_bin_menuitems (items, big_endian)
1869 const struct menuitem *items;
1872 struct bindata *first, **pp;
1873 const struct menuitem *mi;
1878 for (mi = items; mi != NULL; mi = mi->next)
1883 d = (struct bindata *) reswr_alloc (sizeof *d);
1884 d->length = mi->popup == NULL ? 4 : 2;
1885 d->data = (unsigned char *) reswr_alloc (d->length);
1888 if (mi->next == NULL)
1889 flags |= MENUITEM_ENDMENU;
1890 if (mi->popup != NULL)
1891 flags |= MENUITEM_POPUP;
1893 put_16 (big_endian, flags, d->data);
1895 if (mi->popup == NULL)
1896 put_16 (big_endian, mi->id, d->data + 2);
1901 *pp = unicode_to_bin (mi->text, big_endian);
1904 if (mi->popup != NULL)
1906 *pp = res_to_bin_menuitems (mi->popup, big_endian);
1915 /* Convert menuex items to binary. */
1917 static struct bindata *
1918 res_to_bin_menuexitems (items, big_endian)
1919 const struct menuitem *items;
1922 struct bindata *first, **pp;
1923 unsigned long length;
1924 const struct menuitem *mi;
1931 for (mi = items; mi != NULL; mi = mi->next)
1936 dword_align_bin (&pp, &length);
1938 d = (struct bindata *) reswr_alloc (sizeof *d);
1940 d->data = (unsigned char *) reswr_alloc (12);
1944 put_32 (big_endian, mi->type, d->data);
1945 put_32 (big_endian, mi->state, d->data + 4);
1946 put_16 (big_endian, mi->id, d->data + 8);
1949 if (mi->next == NULL)
1951 if (mi->popup != NULL)
1953 put_16 (big_endian, flags, d->data + 10);
1958 *pp = unicode_to_bin (mi->text, big_endian);
1959 length += (*pp)->length;
1962 if (mi->popup != NULL)
1964 dword_align_bin (&pp, &length);
1966 d = (struct bindata *) reswr_alloc (sizeof *d);
1968 d->data = (unsigned char *) reswr_alloc (4);
1970 put_32 (big_endian, mi->help, d->data);
1975 *pp = res_to_bin_menuexitems (mi->popup, big_endian);
1978 length += (*pp)->length;
1987 /* Convert an rcdata resource to binary. This is also used to convert
1988 other information which happens to be stored in rcdata_item lists
1991 static struct bindata *
1992 res_to_bin_rcdata (items, big_endian)
1993 const struct rcdata_item *items;
1996 struct bindata *first, **pp;
1997 const struct rcdata_item *ri;
2002 for (ri = items; ri != NULL; ri = ri->next)
2006 d = (struct bindata *) reswr_alloc (sizeof *d);
2015 d->data = (unsigned char *) reswr_alloc (2);
2016 put_16 (big_endian, ri->u.word, d->data);
2021 d->data = (unsigned char *) reswr_alloc (4);
2022 put_32 (big_endian, ri->u.dword, d->data);
2026 d->length = ri->u.string.length;
2027 d->data = (unsigned char *) ri->u.string.s;
2030 case RCDATA_WSTRING:
2034 d->length = ri->u.wstring.length * 2;
2035 d->data = (unsigned char *) reswr_alloc (d->length);
2036 for (i = 0; i < ri->u.wstring.length; i++)
2037 put_16 (big_endian, ri->u.wstring.w[i], d->data + i * 2);
2042 d->length = ri->u.buffer.length;
2043 d->data = (unsigned char *) ri->u.buffer.data;
2055 /* Convert a stringtable resource to binary. */
2057 static struct bindata *
2058 res_to_bin_stringtable (st, big_endian)
2059 const struct stringtable *st;
2062 struct bindata *first, **pp;
2068 for (i = 0; i < 16; i++)
2074 slen = st->strings[i].length;
2075 s = st->strings[i].string;
2077 d = (struct bindata *) reswr_alloc (sizeof *d);
2078 d->length = 2 + slen * 2;
2079 d->data = (unsigned char *) reswr_alloc (d->length);
2081 put_16 (big_endian, slen, d->data);
2083 for (j = 0; j < slen; j++)
2084 put_16 (big_endian, s[j], d->data + 2 + j * 2);
2094 /* Convert an ASCII string to a unicode binary string. This always
2095 returns exactly one bindata structure. */
2097 static struct bindata *
2098 string_to_unicode_bin (s, big_endian)
2107 d = (struct bindata *) reswr_alloc (sizeof *d);
2108 d->length = len * 2 + 2;
2109 d->data = (unsigned char *) reswr_alloc (d->length);
2111 for (i = 0; i < len; i++)
2112 put_16 (big_endian, s[i], d->data + i * 2);
2113 put_16 (big_endian, 0, d->data + i * 2);
2120 /* Convert a versioninfo resource to binary. */
2122 static struct bindata *
2123 res_to_bin_versioninfo (versioninfo, big_endian)
2124 const struct versioninfo *versioninfo;
2127 struct bindata *first, **pp;
2128 unsigned long length;
2129 struct ver_info *vi;
2131 first = (struct bindata *) reswr_alloc (sizeof *first);
2133 first->data = (unsigned char *) reswr_alloc (6);
2137 if (versioninfo->fixed == NULL)
2138 put_16 (big_endian, 0, first->data + 2);
2140 put_16 (big_endian, 52, first->data + 2);
2142 put_16 (big_endian, 0, first->data + 4);
2146 *pp = string_to_unicode_bin ("VS_VERSION_INFO", big_endian);
2147 length += (*pp)->length;
2150 dword_align_bin (&pp, &length);
2152 if (versioninfo->fixed != NULL)
2154 const struct fixed_versioninfo *fi;
2157 d = (struct bindata *) reswr_alloc (sizeof *d);
2159 d->data = (unsigned char *) reswr_alloc (52);
2163 fi = versioninfo->fixed;
2165 put_32 (big_endian, 0xfeef04bd, d->data);
2166 put_32 (big_endian, 0x10000, d->data + 4);
2167 put_32 (big_endian, fi->file_version_ms, d->data + 8);
2168 put_32 (big_endian, fi->file_version_ls, d->data + 12);
2169 put_32 (big_endian, fi->product_version_ms, d->data + 16);
2170 put_32 (big_endian, fi->product_version_ls, d->data + 20);
2171 put_32 (big_endian, fi->file_flags_mask, d->data + 24);
2172 put_32 (big_endian, fi->file_flags, d->data + 28);
2173 put_32 (big_endian, fi->file_os, d->data + 32);
2174 put_32 (big_endian, fi->file_type, d->data + 36);
2175 put_32 (big_endian, fi->file_subtype, d->data + 40);
2176 put_32 (big_endian, fi->file_date_ms, d->data + 44);
2177 put_32 (big_endian, fi->file_date_ls, d->data + 48);
2184 for (vi = versioninfo->var; vi != NULL; vi = vi->next)
2186 struct bindata *vid;
2187 unsigned long vilen;
2189 dword_align_bin (&pp, &length);
2191 vid = (struct bindata *) reswr_alloc (sizeof *vid);
2193 vid->data = (unsigned char *) reswr_alloc (6);
2198 put_16 (big_endian, 0, vid->data + 2);
2199 put_16 (big_endian, 0, vid->data + 4);
2209 case VERINFO_STRING:
2211 unsigned long hold, vslen;
2212 struct bindata *vsd;
2213 const struct ver_stringinfo *vs;
2215 *pp = string_to_unicode_bin ("StringFileInfo", big_endian);
2216 length += (*pp)->length;
2217 vilen += (*pp)->length;
2221 dword_align_bin (&pp, &length);
2222 vilen += length - hold;
2224 vsd = (struct bindata *) reswr_alloc (sizeof *vsd);
2226 vsd->data = (unsigned char *) reswr_alloc (6);
2232 put_16 (big_endian, 0, vsd->data + 2);
2233 put_16 (big_endian, 0, vsd->data + 4);
2238 *pp = unicode_to_bin (vi->u.string.language, big_endian);
2239 length += (*pp)->length;
2240 vilen += (*pp)->length;
2241 vslen += (*pp)->length;
2244 for (vs = vi->u.string.strings; vs != NULL; vs = vs->next)
2246 struct bindata *vssd;
2247 unsigned long vsslen;
2250 dword_align_bin (&pp, &length);
2251 vilen += length - hold;
2252 vslen += length - hold;
2254 vssd = (struct bindata *) reswr_alloc (sizeof *vssd);
2256 vssd->data = (unsigned char *) reswr_alloc (6);
2263 put_16 (big_endian, 1, vssd->data + 4);
2268 *pp = unicode_to_bin (vs->key, big_endian);
2269 length += (*pp)->length;
2270 vilen += (*pp)->length;
2271 vslen += (*pp)->length;
2272 vsslen += (*pp)->length;
2276 dword_align_bin (&pp, &length);
2277 vilen += length - hold;
2278 vslen += length - hold;
2279 vsslen += length - hold;
2281 *pp = unicode_to_bin (vs->value, big_endian);
2282 put_16 (big_endian, (*pp)->length / 2, vssd->data + 2);
2283 length += (*pp)->length;
2284 vilen += (*pp)->length;
2285 vslen += (*pp)->length;
2286 vsslen += (*pp)->length;
2289 put_16 (big_endian, vsslen, vssd->data);
2292 put_16 (big_endian, vslen, vsd->data);
2299 unsigned long hold, vvlen, vvvlen;
2300 struct bindata *vvd;
2301 const struct ver_varinfo *vv;
2303 *pp = string_to_unicode_bin ("VarFileInfo", big_endian);
2304 length += (*pp)->length;
2305 vilen += (*pp)->length;
2309 dword_align_bin (&pp, &length);
2310 vilen += length - hold;
2312 vvd = (struct bindata *) reswr_alloc (sizeof *vvd);
2314 vvd->data = (unsigned char *) reswr_alloc (6);
2320 put_16 (big_endian, 0, vvd->data + 4);
2325 *pp = unicode_to_bin (vi->u.var.key, big_endian);
2326 length += (*pp)->length;
2327 vilen += (*pp)->length;
2328 vvlen += (*pp)->length;
2332 dword_align_bin (&pp, &length);
2333 vilen += length - hold;
2334 vvlen += length - hold;
2338 for (vv = vi->u.var.var; vv != NULL; vv = vv->next)
2340 struct bindata *vvsd;
2342 vvsd = (struct bindata *) reswr_alloc (sizeof *vvsd);
2344 vvsd->data = (unsigned char *) reswr_alloc (4);
2351 put_16 (big_endian, vv->language, vvsd->data);
2352 put_16 (big_endian, vv->charset, vvsd->data + 2);
2359 put_16 (big_endian, vvlen, vvd->data);
2360 put_16 (big_endian, vvvlen, vvd->data + 2);
2366 put_16 (big_endian, vilen, vid->data);
2369 put_16 (big_endian, length, first->data);
2374 /* Convert a generic resource to binary. */
2376 static struct bindata *
2377 res_to_bin_generic (length, data)
2378 unsigned long length;
2379 const unsigned char *data;
2383 d = (struct bindata *) reswr_alloc (sizeof *d);
2385 d->data = (unsigned char *) data;