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;
523 if ((d
->style
& DS_SETFONT
) == 0)
535 if (length
< off
+ 2)
536 toosmall (_("dialog font point size"));
538 d
->pointsize
= get_16 (big_endian
, data
+ off
);
543 if (length
< off
+ 4)
544 toosmall (_("dialogex font information"));
545 d
->ex
->weight
= get_16 (big_endian
, data
+ off
);
546 d
->ex
->italic
= get_16 (big_endian
, data
+ off
+ 2);
550 d
->font
= get_unicode (data
+ off
, length
- off
, big_endian
, &sublen
);
551 off
+= sublen
* 2 + 2;
557 for (i
= 0; i
< c
; i
++)
559 struct dialog_control
*dc
;
562 off
= (off
+ 3) &~ 3;
564 dc
= (struct dialog_control
*) res_alloc (sizeof *dc
);
568 if (length
< off
+ 8)
569 toosmall (_("dialog control"));
571 dc
->style
= get_32 (big_endian
, data
+ off
);
572 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
578 if (length
< off
+ 12)
579 toosmall (_("dialogex control"));
580 dc
->help
= get_32 (big_endian
, data
+ off
);
581 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
582 dc
->style
= get_32 (big_endian
, data
+ off
+ 8);
586 if (length
< off
+ 10)
587 toosmall (_("dialog control"));
589 dc
->x
= get_16 (big_endian
, data
+ off
);
590 dc
->y
= get_16 (big_endian
, data
+ off
+ 2);
591 dc
->width
= get_16 (big_endian
, data
+ off
+ 4);
592 dc
->height
= get_16 (big_endian
, data
+ off
+ 6);
595 dc
->id
= get_32 (big_endian
, data
+ off
+ 8);
597 dc
->id
= get_16 (big_endian
, data
+ off
+ 8);
599 off
+= 10 + (d
->ex
!= NULL
? 2 : 0);
601 sublen
= get_resid (&dc
->class, data
+ off
, length
- off
, big_endian
);
604 sublen
= get_resid (&dc
->text
, data
+ off
, length
- off
, big_endian
);
607 if (length
< off
+ 2)
608 toosmall (_("dialog control end"));
610 datalen
= get_16 (big_endian
, data
+ off
);
617 off
= (off
+ 3) &~ 3;
619 if (length
< off
+ datalen
)
620 toosmall (_("dialog control data"));
622 dc
->data
= ((struct rcdata_item
*)
623 res_alloc (sizeof (struct rcdata_item
)));
624 dc
->data
->next
= NULL
;
625 dc
->data
->type
= RCDATA_BUFFER
;
626 dc
->data
->u
.buffer
.length
= datalen
;
627 dc
->data
->u
.buffer
.data
= data
+ off
;
637 r
= (struct res_resource
*) res_alloc (sizeof *r
);
638 r
->type
= RES_TYPE_DIALOG
;
644 /* Convert a stringtable resource from binary. */
646 static struct res_resource
*
647 bin_to_res_string (data
, length
, big_endian
)
648 const unsigned char *data
;
649 unsigned long length
;
652 struct stringtable
*st
;
654 struct res_resource
*r
;
656 st
= (struct stringtable
*) res_alloc (sizeof *st
);
658 for (i
= 0; i
< 16; i
++)
663 toosmall (_("stringtable string length"));
664 slen
= get_16 (big_endian
, data
);
665 st
->strings
[i
].length
= slen
;
672 if (length
< 2 + 2 * slen
)
673 toosmall (_("stringtable string"));
675 s
= (unichar
*) res_alloc (slen
* sizeof (unichar
));
676 st
->strings
[i
].string
= s
;
678 for (j
= 0; j
< slen
; j
++)
679 s
[j
] = get_16 (big_endian
, data
+ 2 + j
* 2);
682 data
+= 2 + 2 * slen
;
683 length
-= 2 + 2 * slen
;
686 r
= (struct res_resource
*) res_alloc (sizeof *r
);
687 r
->type
= RES_TYPE_STRINGTABLE
;
688 r
->u
.stringtable
= st
;
693 /* Convert a fontdir resource from binary. */
695 static struct res_resource
*
696 bin_to_res_fontdir (data
, length
, big_endian
)
697 const unsigned char *data
;
698 unsigned long length
;
702 struct fontdir
*first
, **pp
;
703 struct res_resource
*r
;
706 toosmall (_("fontdir header"));
708 c
= get_16 (big_endian
, data
);
713 for (i
= 0; i
< c
; i
++)
719 toosmall (_("fontdir"));
721 fd
= (struct fontdir
*) res_alloc (sizeof *fd
);
722 fd
->index
= get_16 (big_endian
, data
);
724 /* To work out the length of the fontdir data, we must get the
725 length of the device name and face name strings, even though
726 we don't store them in the fontdir structure. The
727 documentation says that these are NULL terminated char
728 strings, not Unicode strings. */
732 while (off
< length
&& data
[off
] != '\0')
735 toosmall (_("fontdir device name"));
738 while (off
< length
&& data
[off
] != '\0')
741 toosmall (_("fontdir face name"));
751 /* The documentation does not indicate that any rounding is
758 r
= (struct res_resource
*) res_alloc (sizeof *r
);
759 r
->type
= RES_TYPE_FONTDIR
;
760 r
->u
.fontdir
= first
;
765 /* Convert an accelerators resource from binary. */
767 static struct res_resource
*
768 bin_to_res_accelerators (data
, length
, big_endian
)
769 const unsigned char *data
;
770 unsigned long length
;
773 struct accelerator
*first
, **pp
;
774 struct res_resource
*r
;
781 struct accelerator
*a
;
784 toosmall (_("accelerator"));
786 a
= (struct accelerator
*) res_alloc (sizeof *a
);
788 a
->flags
= get_16 (big_endian
, data
);
789 a
->key
= get_16 (big_endian
, data
+ 2);
790 a
->id
= get_16 (big_endian
, data
+ 4);
796 if ((a
->flags
& ACC_LAST
) != 0)
803 r
= (struct res_resource
*) res_alloc (sizeof *r
);
804 r
->type
= RES_TYPE_ACCELERATOR
;
810 /* Convert an rcdata resource from binary. */
812 static struct res_resource
*
813 bin_to_res_rcdata (data
, length
, big_endian
)
814 const unsigned char *data
;
815 unsigned long length
;
816 int big_endian ATTRIBUTE_UNUSED
;
818 struct rcdata_item
*ri
;
819 struct res_resource
*r
;
821 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
824 ri
->type
= RCDATA_BUFFER
;
825 ri
->u
.buffer
.length
= length
;
826 ri
->u
.buffer
.data
= data
;
828 r
= (struct res_resource
*) res_alloc (sizeof *r
);
829 r
->type
= RES_TYPE_RCDATA
;
835 /* Convert a group cursor resource from binary. */
837 static struct res_resource
*
838 bin_to_res_group_cursor (data
, length
, big_endian
)
839 const unsigned char *data
;
840 unsigned long length
;
844 struct group_cursor
*first
, **pp
;
845 struct res_resource
*r
;
848 toosmall (_("group cursor header"));
850 type
= get_16 (big_endian
, data
+ 2);
852 fatal (_("unexpected group cursor type %d"), type
);
854 c
= get_16 (big_endian
, data
+ 4);
862 for (i
= 0; i
< c
; i
++)
864 struct group_cursor
*gc
;
867 toosmall (_("group cursor"));
869 gc
= (struct group_cursor
*) res_alloc (sizeof *gc
);
871 gc
->width
= get_16 (big_endian
, data
);
872 gc
->height
= get_16 (big_endian
, data
+ 2);
873 gc
->planes
= get_16 (big_endian
, data
+ 4);
874 gc
->bits
= get_16 (big_endian
, data
+ 6);
875 gc
->bytes
= get_32 (big_endian
, data
+ 8);
876 gc
->index
= get_16 (big_endian
, data
+ 12);
886 r
= (struct res_resource
*) res_alloc (sizeof *r
);
887 r
->type
= RES_TYPE_GROUP_CURSOR
;
888 r
->u
.group_cursor
= first
;
893 /* Convert a group icon resource from binary. */
895 static struct res_resource
*
896 bin_to_res_group_icon (data
, length
, big_endian
)
897 const unsigned char *data
;
898 unsigned long length
;
902 struct group_icon
*first
, **pp
;
903 struct res_resource
*r
;
906 toosmall (_("group icon header"));
908 type
= get_16 (big_endian
, data
+ 2);
910 fatal (_("unexpected group icon type %d"), type
);
912 c
= get_16 (big_endian
, data
+ 4);
920 for (i
= 0; i
< c
; i
++)
922 struct group_icon
*gi
;
925 toosmall (_("group icon"));
927 gi
= (struct group_icon
*) res_alloc (sizeof *gi
);
930 gi
->height
= data
[1];
931 gi
->colors
= data
[2];
932 gi
->planes
= get_16 (big_endian
, data
+ 4);
933 gi
->bits
= get_16 (big_endian
, data
+ 6);
934 gi
->bytes
= get_32 (big_endian
, data
+ 8);
935 gi
->index
= get_16 (big_endian
, data
+ 12);
945 r
= (struct res_resource
*) res_alloc (sizeof *r
);
946 r
->type
= RES_TYPE_GROUP_ICON
;
947 r
->u
.group_icon
= first
;
952 /* Extract data from a version header. If KEY is not NULL, then the
953 key must be KEY; otherwise, the key is returned in *PKEY. This
954 sets *LEN to the total length, *VALLEN to the value length, *TYPE
955 to the type, and *OFF to the offset to the children. */
958 get_version_header (data
, length
, big_endian
, key
, pkey
, len
, vallen
, type
,
960 const unsigned char *data
;
961 unsigned long length
;
973 *len
= get_16 (big_endian
, data
);
974 *vallen
= get_16 (big_endian
, data
+ 2);
975 *type
= get_16 (big_endian
, data
+ 4);
986 *pkey
= get_unicode (data
, length
, big_endian
, &sublen
);
987 *off
+= sublen
* 2 + 2;
995 if (get_16 (big_endian
, data
) != (unsigned char) *key
)
996 fatal (_("unexpected version string"));
1009 *off
= (*off
+ 3) &~ 3;
1012 /* Convert a version resource from binary. */
1014 static struct res_resource
*
1015 bin_to_res_version (data
, length
, big_endian
)
1016 const unsigned char *data
;
1017 unsigned long length
;
1020 int verlen
, vallen
, type
, off
;
1021 struct fixed_versioninfo
*fi
;
1022 struct ver_info
*first
, **pp
;
1023 struct versioninfo
*v
;
1024 struct res_resource
*r
;
1026 get_version_header (data
, length
, big_endian
, "VS_VERSION_INFO",
1027 (unichar
**) NULL
, &verlen
, &vallen
, &type
, &off
);
1029 if ((unsigned int) verlen
!= length
)
1030 fatal (_("version length %d does not match resource length %lu"),
1034 fatal (_("unexpected version type %d"), type
);
1043 unsigned long signature
, fiv
;
1046 fatal (_("unexpected fixed version information length %d"), vallen
);
1049 toosmall (_("fixed version info"));
1051 signature
= get_32 (big_endian
, data
);
1052 if (signature
!= 0xfeef04bd)
1053 fatal (_("unexpected fixed version signature %lu"), signature
);
1055 fiv
= get_32 (big_endian
, data
+ 4);
1056 if (fiv
!= 0 && fiv
!= 0x10000)
1057 fatal (_("unexpected fixed version info version %lu"), fiv
);
1059 fi
= (struct fixed_versioninfo
*) res_alloc (sizeof *fi
);
1061 fi
->file_version_ms
= get_32 (big_endian
, data
+ 8);
1062 fi
->file_version_ls
= get_32 (big_endian
, data
+ 12);
1063 fi
->product_version_ms
= get_32 (big_endian
, data
+ 16);
1064 fi
->product_version_ls
= get_32 (big_endian
, data
+ 20);
1065 fi
->file_flags_mask
= get_32 (big_endian
, data
+ 24);
1066 fi
->file_flags
= get_32 (big_endian
, data
+ 28);
1067 fi
->file_os
= get_32 (big_endian
, data
+ 32);
1068 fi
->file_type
= get_32 (big_endian
, data
+ 36);
1069 fi
->file_subtype
= get_32 (big_endian
, data
+ 40);
1070 fi
->file_date_ms
= get_32 (big_endian
, data
+ 44);
1071 fi
->file_date_ls
= get_32 (big_endian
, data
+ 48);
1082 struct ver_info
*vi
;
1086 toosmall (_("version var info"));
1088 vi
= (struct ver_info
*) res_alloc (sizeof *vi
);
1090 ch
= get_16 (big_endian
, data
+ 6);
1094 struct ver_stringinfo
**ppvs
;
1096 vi
->type
= VERINFO_STRING
;
1098 get_version_header (data
, length
, big_endian
, "StringFileInfo",
1099 (unichar
**) NULL
, &verlen
, &vallen
, &type
,
1103 fatal (_("unexpected stringfileinfo value length %d"), vallen
);
1108 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1109 &vi
->u
.string
.language
, &verlen
, &vallen
,
1113 fatal (_("unexpected version stringtable value length %d"), vallen
);
1119 vi
->u
.string
.strings
= NULL
;
1120 ppvs
= &vi
->u
.string
.strings
;
1122 /* It's convenient to round verlen to a 4 byte alignment,
1123 since we round the subvariables in the loop. */
1124 verlen
= (verlen
+ 3) &~ 3;
1128 struct ver_stringinfo
*vs
;
1129 int subverlen
, vslen
, valoff
;
1131 vs
= (struct ver_stringinfo
*) res_alloc (sizeof *vs
);
1133 get_version_header (data
, length
, big_endian
,
1134 (const char *) NULL
, &vs
->key
, &subverlen
,
1135 &vallen
, &type
, &off
);
1137 subverlen
= (subverlen
+ 3) &~ 3;
1142 vs
->value
= get_unicode (data
, length
, big_endian
, &vslen
);
1143 valoff
= vslen
* 2 + 2;
1144 valoff
= (valoff
+ 3) &~ 3;
1146 if (off
+ valoff
!= subverlen
)
1147 fatal (_("unexpected version string length %d != %d + %d"),
1148 subverlen
, off
, valoff
);
1157 if (verlen
< subverlen
)
1158 fatal (_("unexpected version string length %d < %d"),
1161 verlen
-= subverlen
;
1166 struct ver_varinfo
**ppvv
;
1168 vi
->type
= VERINFO_VAR
;
1170 get_version_header (data
, length
, big_endian
, "VarFileInfo",
1171 (unichar
**) NULL
, &verlen
, &vallen
, &type
,
1175 fatal (_("unexpected varfileinfo value length %d"), vallen
);
1180 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1181 &vi
->u
.var
.key
, &verlen
, &vallen
, &type
, &off
);
1186 vi
->u
.var
.var
= NULL
;
1187 ppvv
= &vi
->u
.var
.var
;
1191 struct ver_varinfo
*vv
;
1194 toosmall (_("version varfileinfo"));
1196 vv
= (struct ver_varinfo
*) res_alloc (sizeof *vv
);
1198 vv
->language
= get_16 (big_endian
, data
);
1199 vv
->charset
= get_16 (big_endian
, data
+ 2);
1209 fatal (_("unexpected version value length %d"), vallen
);
1215 fatal (_("unexpected version string"));
1222 v
= (struct versioninfo
*) res_alloc (sizeof *v
);
1226 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1227 r
->type
= RES_TYPE_VERSIONINFO
;
1228 r
->u
.versioninfo
= v
;
1233 /* Convert an arbitrary user defined resource from binary. */
1235 static struct res_resource
*
1236 bin_to_res_userdata (data
, length
, big_endian
)
1237 const unsigned char *data
;
1238 unsigned long length
;
1239 int big_endian ATTRIBUTE_UNUSED
;
1241 struct rcdata_item
*ri
;
1242 struct res_resource
*r
;
1244 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
1247 ri
->type
= RCDATA_BUFFER
;
1248 ri
->u
.buffer
.length
= length
;
1249 ri
->u
.buffer
.data
= data
;
1251 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1252 r
->type
= RES_TYPE_USERDATA
;
1258 /* Macros to swap out values. */
1260 #define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
1261 #define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
1263 /* Local functions used to convert resources to binary format. */
1265 static void dword_align_bin
PARAMS ((struct bindata
***, unsigned long *));
1266 static struct bindata
*resid_to_bin
PARAMS ((struct res_id
, int));
1267 static struct bindata
*unicode_to_bin
PARAMS ((const unichar
*, int));
1268 static struct bindata
*res_to_bin_accelerator
1269 PARAMS ((const struct accelerator
*, int));
1270 static struct bindata
*res_to_bin_cursor
1271 PARAMS ((const struct cursor
*, int));
1272 static struct bindata
*res_to_bin_group_cursor
1273 PARAMS ((const struct group_cursor
*, int));
1274 static struct bindata
*res_to_bin_dialog
1275 PARAMS ((const struct dialog
*, int));
1276 static struct bindata
*res_to_bin_fontdir
1277 PARAMS ((const struct fontdir
*, int));
1278 static struct bindata
*res_to_bin_group_icon
1279 PARAMS ((const struct group_icon
*, int));
1280 static struct bindata
*res_to_bin_menu
1281 PARAMS ((const struct menu
*, int));
1282 static struct bindata
*res_to_bin_menuitems
1283 PARAMS ((const struct menuitem
*, int));
1284 static struct bindata
*res_to_bin_menuexitems
1285 PARAMS ((const struct menuitem
*, int));
1286 static struct bindata
*res_to_bin_rcdata
1287 PARAMS ((const struct rcdata_item
*, int));
1288 static struct bindata
*res_to_bin_stringtable
1289 PARAMS ((const struct stringtable
*, int));
1290 static struct bindata
*string_to_unicode_bin
PARAMS ((const char *, int));
1291 static struct bindata
*res_to_bin_versioninfo
1292 PARAMS ((const struct versioninfo
*, int));
1293 static struct bindata
*res_to_bin_generic
1294 PARAMS ((unsigned long, const unsigned char *));
1296 /* Convert a resource to binary. */
1299 res_to_bin (res
, big_endian
)
1300 const struct res_resource
*res
;
1307 case RES_TYPE_BITMAP
:
1310 case RES_TYPE_MESSAGETABLE
:
1311 return res_to_bin_generic (res
->u
.data
.length
, res
->u
.data
.data
);
1312 case RES_TYPE_ACCELERATOR
:
1313 return res_to_bin_accelerator (res
->u
.acc
, big_endian
);
1314 case RES_TYPE_CURSOR
:
1315 return res_to_bin_cursor (res
->u
.cursor
, big_endian
);
1316 case RES_TYPE_GROUP_CURSOR
:
1317 return res_to_bin_group_cursor (res
->u
.group_cursor
, big_endian
);
1318 case RES_TYPE_DIALOG
:
1319 return res_to_bin_dialog (res
->u
.dialog
, big_endian
);
1320 case RES_TYPE_FONTDIR
:
1321 return res_to_bin_fontdir (res
->u
.fontdir
, big_endian
);
1322 case RES_TYPE_GROUP_ICON
:
1323 return res_to_bin_group_icon (res
->u
.group_icon
, big_endian
);
1325 return res_to_bin_menu (res
->u
.menu
, big_endian
);
1326 case RES_TYPE_RCDATA
:
1327 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1328 case RES_TYPE_STRINGTABLE
:
1329 return res_to_bin_stringtable (res
->u
.stringtable
, big_endian
);
1330 case RES_TYPE_USERDATA
:
1331 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1332 case RES_TYPE_VERSIONINFO
:
1333 return res_to_bin_versioninfo (res
->u
.versioninfo
, big_endian
);
1337 /* Align to a 32 bit boundary. PPP points to the of a list of bindata
1338 structures. LENGTH points to the length of the structures. If
1339 necessary, this adds a new bindata to bring length up to a 32 bit
1340 boundary. It updates *PPP and *LENGTH. */
1343 dword_align_bin (ppp
, length
)
1344 struct bindata
***ppp
;
1345 unsigned long *length
;
1350 if ((*length
& 3) == 0)
1353 add
= 4 - (*length
& 3);
1355 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1357 d
->data
= (unsigned char *) reswr_alloc (add
);
1358 memset (d
->data
, 0, add
);
1362 *ppp
= &(**ppp
)->next
;
1367 /* Convert a resource ID to binary. This always returns exactly one
1368 bindata structure. */
1370 static struct bindata
*
1371 resid_to_bin (id
, big_endian
)
1377 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1382 d
->data
= (unsigned char *) reswr_alloc (4);
1383 put_16 (big_endian
, 0xffff, d
->data
);
1384 put_16 (big_endian
, id
.u
.id
, d
->data
+ 2);
1390 d
->length
= id
.u
.n
.length
* 2 + 2;
1391 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1392 for (i
= 0; i
< id
.u
.n
.length
; i
++)
1393 put_16 (big_endian
, id
.u
.n
.name
[i
], d
->data
+ i
* 2);
1394 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1402 /* Convert a null terminated unicode string to binary. This always
1403 returns exactly one bindata structure. */
1405 static struct bindata
*
1406 unicode_to_bin (str
, big_endian
)
1418 for (s
= str
; *s
!= 0; s
++)
1422 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1423 d
->length
= len
* 2 + 2;
1424 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1427 put_16 (big_endian
, 0, d
->data
);
1433 for (s
= str
, i
= 0; *s
!= 0; s
++, i
++)
1434 put_16 (big_endian
, *s
, d
->data
+ i
* 2);
1435 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1443 /* Convert an accelerator resource to binary. */
1445 static struct bindata
*
1446 res_to_bin_accelerator (accelerators
, big_endian
)
1447 const struct accelerator
*accelerators
;
1450 struct bindata
*first
, **pp
;
1451 const struct accelerator
*a
;
1456 for (a
= accelerators
; a
!= NULL
; a
= a
->next
)
1460 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1462 d
->data
= (unsigned char *) reswr_alloc (8);
1465 a
->flags
| (a
->next
!= NULL
? 0 : ACC_LAST
),
1467 put_16 (big_endian
, a
->key
, d
->data
+ 2);
1468 put_16 (big_endian
, a
->id
, d
->data
+ 4);
1469 put_16 (big_endian
, 0, d
->data
+ 8);
1479 /* Convert a cursor resource to binary. */
1481 static struct bindata
*
1482 res_to_bin_cursor (c
, big_endian
)
1483 const struct cursor
*c
;
1488 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1490 d
->data
= (unsigned char *) reswr_alloc (4);
1492 put_16 (big_endian
, c
->xhotspot
, d
->data
);
1493 put_16 (big_endian
, c
->yhotspot
, d
->data
+ 2);
1495 d
->next
= (struct bindata
*) reswr_alloc (sizeof *d
);
1496 d
->next
->length
= c
->length
;
1497 d
->next
->data
= (unsigned char *) c
->data
;
1498 d
->next
->next
= NULL
;
1503 /* Convert a group cursor resource to binary. */
1505 static struct bindata
*
1506 res_to_bin_group_cursor (group_cursors
, big_endian
)
1507 const struct group_cursor
*group_cursors
;
1510 struct bindata
*first
, **pp
;
1512 const struct group_cursor
*gc
;
1514 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1516 first
->data
= (unsigned char *) reswr_alloc (6);
1518 put_16 (big_endian
, 0, first
->data
);
1519 put_16 (big_endian
, 2, first
->data
+ 2);
1525 for (gc
= group_cursors
; gc
!= NULL
; gc
= gc
->next
)
1531 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1533 d
->data
= (unsigned char *) reswr_alloc (14);
1535 put_16 (big_endian
, gc
->width
, d
->data
);
1536 put_16 (big_endian
, gc
->height
, d
->data
+ 2);
1537 put_16 (big_endian
, gc
->planes
, d
->data
+ 4);
1538 put_16 (big_endian
, gc
->bits
, d
->data
+ 6);
1539 put_32 (big_endian
, gc
->bytes
, d
->data
+ 8);
1540 put_16 (big_endian
, gc
->index
, d
->data
+ 12);
1547 put_16 (big_endian
, c
, first
->data
+ 4);
1552 /* Convert a dialog resource to binary. */
1554 static struct bindata
*
1555 res_to_bin_dialog (dialog
, big_endian
)
1556 const struct dialog
*dialog
;
1560 struct bindata
*first
, **pp
;
1561 unsigned long length
;
1563 struct dialog_control
*dc
;
1565 dialogex
= extended_dialog (dialog
);
1567 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1568 first
->length
= dialogex
? 26 : 18;
1569 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1571 length
= first
->length
;
1575 put_32 (big_endian
, dialog
->style
, first
->data
);
1576 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 4);
1581 put_16 (big_endian
, 1, first
->data
);
1582 put_16 (big_endian
, 0xffff, first
->data
+ 2);
1584 if (dialog
->ex
== NULL
)
1585 put_32 (big_endian
, 0, first
->data
+ 4);
1587 put_32 (big_endian
, dialog
->ex
->help
, first
->data
+ 4);
1588 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 8);
1589 put_32 (big_endian
, dialog
->style
, first
->data
+ 12);
1593 put_16 (big_endian
, dialog
->x
, first
->data
+ off
+ 2);
1594 put_16 (big_endian
, dialog
->y
, first
->data
+ off
+ 4);
1595 put_16 (big_endian
, dialog
->width
, first
->data
+ off
+ 6);
1596 put_16 (big_endian
, dialog
->height
, first
->data
+ off
+ 8);
1600 *pp
= resid_to_bin (dialog
->menu
, big_endian
);
1601 length
+= (*pp
)->length
;
1604 *pp
= resid_to_bin (dialog
->class, big_endian
);
1605 length
+= (*pp
)->length
;
1608 *pp
= unicode_to_bin (dialog
->caption
, big_endian
);
1609 length
+= (*pp
)->length
;
1612 if ((dialog
->style
& DS_SETFONT
) != 0)
1616 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1617 d
->length
= dialogex
? 6 : 2;
1618 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1620 length
+= d
->length
;
1622 put_16 (big_endian
, dialog
->pointsize
, d
->data
);
1626 if (dialog
->ex
== NULL
)
1628 put_16 (big_endian
, 0, d
->data
+ 2);
1629 put_16 (big_endian
, 0, d
->data
+ 4);
1633 put_16 (big_endian
, dialog
->ex
->weight
, d
->data
+ 2);
1634 put_16 (big_endian
, dialog
->ex
->italic
, d
->data
+ 4);
1641 *pp
= unicode_to_bin (dialog
->font
, big_endian
);
1642 length
+= (*pp
)->length
;
1647 for (dc
= dialog
->controls
; dc
!= NULL
; dc
= dc
->next
)
1654 dword_align_bin (&pp
, &length
);
1656 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1657 d
->length
= dialogex
? 24 : 18;
1658 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1660 length
+= d
->length
;
1664 put_32 (big_endian
, dc
->style
, d
->data
);
1665 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1670 put_32 (big_endian
, dc
->help
, d
->data
);
1671 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1672 put_32 (big_endian
, dc
->style
, d
->data
+ 8);
1676 put_16 (big_endian
, dc
->x
, d
->data
+ dcoff
);
1677 put_16 (big_endian
, dc
->y
, d
->data
+ dcoff
+ 2);
1678 put_16 (big_endian
, dc
->width
, d
->data
+ dcoff
+ 4);
1679 put_16 (big_endian
, dc
->height
, d
->data
+ dcoff
+ 6);
1682 put_32 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1684 put_16 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1689 *pp
= resid_to_bin (dc
->class, big_endian
);
1690 length
+= (*pp
)->length
;
1693 *pp
= resid_to_bin (dc
->text
, big_endian
);
1694 length
+= (*pp
)->length
;
1697 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1699 d
->data
= (unsigned char *) reswr_alloc (2);
1707 if (dc
->data
== NULL
)
1708 put_16 (big_endian
, 0, d
->data
);
1711 unsigned long sublen
;
1713 dword_align_bin (&pp
, &length
);
1715 *pp
= res_to_bin_rcdata (dc
->data
, big_endian
);
1719 sublen
+= (*pp
)->length
;
1723 put_16 (big_endian
, sublen
, d
->data
);
1728 put_16 (big_endian
, c
, first
->data
+ off
);
1733 /* Convert a fontdir resource to binary. */
1735 static struct bindata
*
1736 res_to_bin_fontdir (fontdirs
, big_endian
)
1737 const struct fontdir
*fontdirs
;
1740 struct bindata
*first
, **pp
;
1742 const struct fontdir
*fd
;
1744 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1746 first
->data
= (unsigned char *) reswr_alloc (2);
1752 for (fd
= fontdirs
; fd
!= NULL
; fd
= fd
->next
)
1758 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1760 d
->data
= (unsigned char *) reswr_alloc (2);
1762 put_16 (big_endian
, fd
->index
, d
->data
);
1767 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1768 d
->length
= fd
->length
;
1769 d
->data
= (unsigned char *) fd
->data
;
1776 put_16 (big_endian
, c
, first
->data
);
1781 /* Convert a group icon resource to binary. */
1783 static struct bindata
*
1784 res_to_bin_group_icon (group_icons
, big_endian
)
1785 const struct group_icon
*group_icons
;
1788 struct bindata
*first
, **pp
;
1790 const struct group_icon
*gi
;
1792 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1794 first
->data
= (unsigned char *) reswr_alloc (6);
1796 put_16 (big_endian
, 0, first
->data
);
1797 put_16 (big_endian
, 1, first
->data
+ 2);
1803 for (gi
= group_icons
; gi
!= NULL
; gi
= gi
->next
)
1809 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1811 d
->data
= (unsigned char *) reswr_alloc (14);
1813 d
->data
[0] = gi
->width
;
1814 d
->data
[1] = gi
->height
;
1815 d
->data
[2] = gi
->colors
;
1817 put_16 (big_endian
, gi
->planes
, d
->data
+ 4);
1818 put_16 (big_endian
, gi
->bits
, d
->data
+ 6);
1819 put_32 (big_endian
, gi
->bytes
, d
->data
+ 8);
1820 put_16 (big_endian
, gi
->index
, d
->data
+ 12);
1827 put_16 (big_endian
, c
, first
->data
+ 4);
1832 /* Convert a menu resource to binary. */
1834 static struct bindata
*
1835 res_to_bin_menu (menu
, big_endian
)
1836 const struct menu
*menu
;
1842 menuex
= extended_menu (menu
);
1844 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1845 d
->length
= menuex
? 8 : 4;
1846 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1850 put_16 (big_endian
, 0, d
->data
);
1851 put_16 (big_endian
, 0, d
->data
+ 2);
1853 d
->next
= res_to_bin_menuitems (menu
->items
, big_endian
);
1857 put_16 (big_endian
, 1, d
->data
);
1858 put_16 (big_endian
, 4, d
->data
+ 2);
1859 put_32 (big_endian
, menu
->help
, d
->data
+ 4);
1861 d
->next
= res_to_bin_menuexitems (menu
->items
, big_endian
);
1867 /* Convert menu items to binary. */
1869 static struct bindata
*
1870 res_to_bin_menuitems (items
, big_endian
)
1871 const struct menuitem
*items
;
1874 struct bindata
*first
, **pp
;
1875 const struct menuitem
*mi
;
1880 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1885 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1886 d
->length
= mi
->popup
== NULL
? 4 : 2;
1887 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1890 if (mi
->next
== NULL
)
1891 flags
|= MENUITEM_ENDMENU
;
1892 if (mi
->popup
!= NULL
)
1893 flags
|= MENUITEM_POPUP
;
1895 put_16 (big_endian
, flags
, d
->data
);
1897 if (mi
->popup
== NULL
)
1898 put_16 (big_endian
, mi
->id
, d
->data
+ 2);
1903 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1906 if (mi
->popup
!= NULL
)
1908 *pp
= res_to_bin_menuitems (mi
->popup
, big_endian
);
1917 /* Convert menuex items to binary. */
1919 static struct bindata
*
1920 res_to_bin_menuexitems (items
, big_endian
)
1921 const struct menuitem
*items
;
1924 struct bindata
*first
, **pp
;
1925 unsigned long length
;
1926 const struct menuitem
*mi
;
1933 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1938 dword_align_bin (&pp
, &length
);
1940 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1942 d
->data
= (unsigned char *) reswr_alloc (12);
1946 put_32 (big_endian
, mi
->type
, d
->data
);
1947 put_32 (big_endian
, mi
->state
, d
->data
+ 4);
1948 put_16 (big_endian
, mi
->id
, d
->data
+ 8);
1951 if (mi
->next
== NULL
)
1953 if (mi
->popup
!= NULL
)
1955 put_16 (big_endian
, flags
, d
->data
+ 10);
1960 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1961 length
+= (*pp
)->length
;
1964 if (mi
->popup
!= NULL
)
1966 dword_align_bin (&pp
, &length
);
1968 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1970 d
->data
= (unsigned char *) reswr_alloc (4);
1972 put_32 (big_endian
, mi
->help
, d
->data
);
1977 *pp
= res_to_bin_menuexitems (mi
->popup
, big_endian
);
1980 length
+= (*pp
)->length
;
1989 /* Convert an rcdata resource to binary. This is also used to convert
1990 other information which happens to be stored in rcdata_item lists
1993 static struct bindata
*
1994 res_to_bin_rcdata (items
, big_endian
)
1995 const struct rcdata_item
*items
;
1998 struct bindata
*first
, **pp
;
1999 const struct rcdata_item
*ri
;
2004 for (ri
= items
; ri
!= NULL
; ri
= ri
->next
)
2008 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2017 d
->data
= (unsigned char *) reswr_alloc (2);
2018 put_16 (big_endian
, ri
->u
.word
, d
->data
);
2023 d
->data
= (unsigned char *) reswr_alloc (4);
2024 put_32 (big_endian
, ri
->u
.dword
, d
->data
);
2028 d
->length
= ri
->u
.string
.length
;
2029 d
->data
= (unsigned char *) ri
->u
.string
.s
;
2032 case RCDATA_WSTRING
:
2036 d
->length
= ri
->u
.wstring
.length
* 2;
2037 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2038 for (i
= 0; i
< ri
->u
.wstring
.length
; i
++)
2039 put_16 (big_endian
, ri
->u
.wstring
.w
[i
], d
->data
+ i
* 2);
2044 d
->length
= ri
->u
.buffer
.length
;
2045 d
->data
= (unsigned char *) ri
->u
.buffer
.data
;
2057 /* Convert a stringtable resource to binary. */
2059 static struct bindata
*
2060 res_to_bin_stringtable (st
, big_endian
)
2061 const struct stringtable
*st
;
2064 struct bindata
*first
, **pp
;
2070 for (i
= 0; i
< 16; i
++)
2076 slen
= st
->strings
[i
].length
;
2077 s
= st
->strings
[i
].string
;
2079 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2080 d
->length
= 2 + slen
* 2;
2081 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2083 put_16 (big_endian
, slen
, d
->data
);
2085 for (j
= 0; j
< slen
; j
++)
2086 put_16 (big_endian
, s
[j
], d
->data
+ 2 + j
* 2);
2096 /* Convert an ASCII string to a unicode binary string. This always
2097 returns exactly one bindata structure. */
2099 static struct bindata
*
2100 string_to_unicode_bin (s
, big_endian
)
2109 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2110 d
->length
= len
* 2 + 2;
2111 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2113 for (i
= 0; i
< len
; i
++)
2114 put_16 (big_endian
, s
[i
], d
->data
+ i
* 2);
2115 put_16 (big_endian
, 0, d
->data
+ i
* 2);
2122 /* Convert a versioninfo resource to binary. */
2124 static struct bindata
*
2125 res_to_bin_versioninfo (versioninfo
, big_endian
)
2126 const struct versioninfo
*versioninfo
;
2129 struct bindata
*first
, **pp
;
2130 unsigned long length
;
2131 struct ver_info
*vi
;
2133 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
2135 first
->data
= (unsigned char *) reswr_alloc (6);
2139 if (versioninfo
->fixed
== NULL
)
2140 put_16 (big_endian
, 0, first
->data
+ 2);
2142 put_16 (big_endian
, 52, first
->data
+ 2);
2144 put_16 (big_endian
, 0, first
->data
+ 4);
2148 *pp
= string_to_unicode_bin ("VS_VERSION_INFO", big_endian
);
2149 length
+= (*pp
)->length
;
2152 dword_align_bin (&pp
, &length
);
2154 if (versioninfo
->fixed
!= NULL
)
2156 const struct fixed_versioninfo
*fi
;
2159 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2161 d
->data
= (unsigned char *) reswr_alloc (52);
2165 fi
= versioninfo
->fixed
;
2167 put_32 (big_endian
, 0xfeef04bd, d
->data
);
2168 put_32 (big_endian
, 0x10000, d
->data
+ 4);
2169 put_32 (big_endian
, fi
->file_version_ms
, d
->data
+ 8);
2170 put_32 (big_endian
, fi
->file_version_ls
, d
->data
+ 12);
2171 put_32 (big_endian
, fi
->product_version_ms
, d
->data
+ 16);
2172 put_32 (big_endian
, fi
->product_version_ls
, d
->data
+ 20);
2173 put_32 (big_endian
, fi
->file_flags_mask
, d
->data
+ 24);
2174 put_32 (big_endian
, fi
->file_flags
, d
->data
+ 28);
2175 put_32 (big_endian
, fi
->file_os
, d
->data
+ 32);
2176 put_32 (big_endian
, fi
->file_type
, d
->data
+ 36);
2177 put_32 (big_endian
, fi
->file_subtype
, d
->data
+ 40);
2178 put_32 (big_endian
, fi
->file_date_ms
, d
->data
+ 44);
2179 put_32 (big_endian
, fi
->file_date_ls
, d
->data
+ 48);
2186 for (vi
= versioninfo
->var
; vi
!= NULL
; vi
= vi
->next
)
2188 struct bindata
*vid
;
2189 unsigned long vilen
;
2191 dword_align_bin (&pp
, &length
);
2193 vid
= (struct bindata
*) reswr_alloc (sizeof *vid
);
2195 vid
->data
= (unsigned char *) reswr_alloc (6);
2200 put_16 (big_endian
, 0, vid
->data
+ 2);
2201 put_16 (big_endian
, 0, vid
->data
+ 4);
2211 case VERINFO_STRING
:
2213 unsigned long hold
, vslen
;
2214 struct bindata
*vsd
;
2215 const struct ver_stringinfo
*vs
;
2217 *pp
= string_to_unicode_bin ("StringFileInfo", big_endian
);
2218 length
+= (*pp
)->length
;
2219 vilen
+= (*pp
)->length
;
2223 dword_align_bin (&pp
, &length
);
2224 vilen
+= length
- hold
;
2226 vsd
= (struct bindata
*) reswr_alloc (sizeof *vsd
);
2228 vsd
->data
= (unsigned char *) reswr_alloc (6);
2234 put_16 (big_endian
, 0, vsd
->data
+ 2);
2235 put_16 (big_endian
, 0, vsd
->data
+ 4);
2240 *pp
= unicode_to_bin (vi
->u
.string
.language
, big_endian
);
2241 length
+= (*pp
)->length
;
2242 vilen
+= (*pp
)->length
;
2243 vslen
+= (*pp
)->length
;
2246 for (vs
= vi
->u
.string
.strings
; vs
!= NULL
; vs
= vs
->next
)
2248 struct bindata
*vssd
;
2249 unsigned long vsslen
;
2252 dword_align_bin (&pp
, &length
);
2253 vilen
+= length
- hold
;
2254 vslen
+= length
- hold
;
2256 vssd
= (struct bindata
*) reswr_alloc (sizeof *vssd
);
2258 vssd
->data
= (unsigned char *) reswr_alloc (6);
2265 put_16 (big_endian
, 1, vssd
->data
+ 4);
2270 *pp
= unicode_to_bin (vs
->key
, big_endian
);
2271 length
+= (*pp
)->length
;
2272 vilen
+= (*pp
)->length
;
2273 vslen
+= (*pp
)->length
;
2274 vsslen
+= (*pp
)->length
;
2278 dword_align_bin (&pp
, &length
);
2279 vilen
+= length
- hold
;
2280 vslen
+= length
- hold
;
2281 vsslen
+= length
- hold
;
2283 *pp
= unicode_to_bin (vs
->value
, big_endian
);
2284 put_16 (big_endian
, (*pp
)->length
/ 2, vssd
->data
+ 2);
2285 length
+= (*pp
)->length
;
2286 vilen
+= (*pp
)->length
;
2287 vslen
+= (*pp
)->length
;
2288 vsslen
+= (*pp
)->length
;
2291 put_16 (big_endian
, vsslen
, vssd
->data
);
2294 put_16 (big_endian
, vslen
, vsd
->data
);
2301 unsigned long hold
, vvlen
, vvvlen
;
2302 struct bindata
*vvd
;
2303 const struct ver_varinfo
*vv
;
2305 *pp
= string_to_unicode_bin ("VarFileInfo", big_endian
);
2306 length
+= (*pp
)->length
;
2307 vilen
+= (*pp
)->length
;
2311 dword_align_bin (&pp
, &length
);
2312 vilen
+= length
- hold
;
2314 vvd
= (struct bindata
*) reswr_alloc (sizeof *vvd
);
2316 vvd
->data
= (unsigned char *) reswr_alloc (6);
2322 put_16 (big_endian
, 0, vvd
->data
+ 4);
2327 *pp
= unicode_to_bin (vi
->u
.var
.key
, big_endian
);
2328 length
+= (*pp
)->length
;
2329 vilen
+= (*pp
)->length
;
2330 vvlen
+= (*pp
)->length
;
2334 dword_align_bin (&pp
, &length
);
2335 vilen
+= length
- hold
;
2336 vvlen
+= length
- hold
;
2340 for (vv
= vi
->u
.var
.var
; vv
!= NULL
; vv
= vv
->next
)
2342 struct bindata
*vvsd
;
2344 vvsd
= (struct bindata
*) reswr_alloc (sizeof *vvsd
);
2346 vvsd
->data
= (unsigned char *) reswr_alloc (4);
2353 put_16 (big_endian
, vv
->language
, vvsd
->data
);
2354 put_16 (big_endian
, vv
->charset
, vvsd
->data
+ 2);
2361 put_16 (big_endian
, vvlen
, vvd
->data
);
2362 put_16 (big_endian
, vvvlen
, vvd
->data
+ 2);
2368 put_16 (big_endian
, vilen
, vid
->data
);
2371 put_16 (big_endian
, length
, first
->data
);
2376 /* Convert a generic resource to binary. */
2378 static struct bindata
*
2379 res_to_bin_generic (length
, data
)
2380 unsigned long length
;
2381 const unsigned char *data
;
2385 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2387 d
->data
= (unsigned char *) data
;