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_8(s) (*((unsigned char *)(s)))
34 #define get_16(be, s) ((be) ? bfd_getb16 (s) : bfd_getl16 (s))
35 #define get_32(be, s) ((be) ? bfd_getb32 (s) : bfd_getl32 (s))
37 /* Local functions. */
39 static void toosmall
PARAMS ((const char *));
40 static unichar
*get_unicode
41 PARAMS ((const unsigned char *, unsigned long, int, int *));
43 PARAMS ((struct res_id
*, const unsigned char *, unsigned long, int));
44 static struct res_resource
*bin_to_res_generic
45 PARAMS ((enum res_type
, const unsigned char *, unsigned long));
46 static struct res_resource
*bin_to_res_cursor
47 PARAMS ((const unsigned char *, unsigned long, int));
48 static struct res_resource
*bin_to_res_menu
49 PARAMS ((const unsigned char *, unsigned long, int));
50 static struct menuitem
*bin_to_res_menuitems
51 PARAMS ((const unsigned char *, unsigned long, int, int *));
52 static struct menuitem
*bin_to_res_menuexitems
53 PARAMS ((const unsigned char *, unsigned long, int, int *));
54 static struct res_resource
*bin_to_res_dialog
55 PARAMS ((const unsigned char *, unsigned long, int));
56 static struct res_resource
*bin_to_res_string
57 PARAMS ((const unsigned char *, unsigned long, int));
58 static struct res_resource
*bin_to_res_fontdir
59 PARAMS ((const unsigned char *, unsigned long, int));
60 static struct res_resource
*bin_to_res_accelerators
61 PARAMS ((const unsigned char *, unsigned long, int));
62 static struct res_resource
*bin_to_res_rcdata
63 PARAMS ((const unsigned char *, unsigned long, int));
64 static struct res_resource
*bin_to_res_group_cursor
65 PARAMS ((const unsigned char *, unsigned long, int));
66 static struct res_resource
*bin_to_res_group_icon
67 PARAMS ((const unsigned char *, unsigned long, int));
68 static struct res_resource
*bin_to_res_version
69 PARAMS ((const unsigned char *, unsigned long, int));
70 static struct res_resource
*bin_to_res_userdata
71 PARAMS ((const unsigned char *, unsigned long, int));
72 static void get_version_header
73 PARAMS ((const unsigned char *, unsigned long, int, const char *,
74 unichar
**, int *, int *, int *, int *));
76 /* Given a resource type ID, a pointer to data, a length, return a
77 res_resource structure which represents that resource. The caller
78 is responsible for initializing the res_info and coff_info fields
79 of the returned structure. */
82 bin_to_res (type
, data
, length
, big_endian
)
84 const unsigned char *data
;
89 return bin_to_res_userdata (data
, length
, big_endian
);
95 return bin_to_res_userdata (data
, length
, big_endian
);
97 return bin_to_res_cursor (data
, length
, big_endian
);
99 return bin_to_res_generic (RES_TYPE_BITMAP
, data
, length
);
101 return bin_to_res_generic (RES_TYPE_ICON
, data
, length
);
103 return bin_to_res_menu (data
, length
, big_endian
);
105 return bin_to_res_dialog (data
, length
, big_endian
);
107 return bin_to_res_string (data
, length
, big_endian
);
109 return bin_to_res_fontdir (data
, length
, big_endian
);
111 return bin_to_res_generic (RES_TYPE_FONT
, data
, length
);
113 return bin_to_res_accelerators (data
, length
, big_endian
);
115 return bin_to_res_rcdata (data
, length
, big_endian
);
116 case RT_MESSAGETABLE
:
117 return bin_to_res_generic (RES_TYPE_MESSAGETABLE
, data
, length
);
118 case RT_GROUP_CURSOR
:
119 return bin_to_res_group_cursor (data
, length
, big_endian
);
121 return bin_to_res_group_icon (data
, length
, big_endian
);
123 return bin_to_res_version (data
, length
, big_endian
);
128 /* Give an error if the binary data is too small. */
134 fatal (_("%s: not enough binary data"), msg
);
137 /* Swap in a NULL terminated unicode string. */
140 get_unicode (data
, length
, big_endian
, retlen
)
141 const unsigned char *data
;
142 unsigned long length
;
152 if (length
< (unsigned long) c
* 2 + 2)
153 toosmall (_("null terminated unicode string"));
154 if (get_16 (big_endian
, data
+ c
* 2) == 0)
159 ret
= (unichar
*) res_alloc ((c
+ 1) * sizeof (unichar
));
161 for (i
= 0; i
< c
; i
++)
162 ret
[i
] = get_16 (big_endian
, data
+ i
* 2);
171 /* Get a resource identifier. This returns the number of bytes used. */
174 get_resid (id
, data
, length
, big_endian
)
176 const unsigned char *data
;
177 unsigned long length
;
183 toosmall (_("resource ID"));
185 first
= get_16 (big_endian
, data
);
189 toosmall (_("resource ID"));
191 id
->u
.id
= get_16 (big_endian
, data
+ 2);
197 id
->u
.n
.name
= get_unicode (data
, length
, big_endian
, &id
->u
.n
.length
);
198 return id
->u
.n
.length
* 2 + 2;
202 /* Convert a resource which just stores uninterpreted data from
205 struct res_resource
*
206 bin_to_res_generic (type
, data
, length
)
208 const unsigned char *data
;
209 unsigned long length
;
211 struct res_resource
*r
;
213 r
= (struct res_resource
*) res_alloc (sizeof *r
);
215 r
->u
.data
.data
= data
;
216 r
->u
.data
.length
= length
;
221 /* Convert a cursor resource from binary. */
223 struct res_resource
*
224 bin_to_res_cursor (data
, length
, big_endian
)
225 const unsigned char *data
;
226 unsigned long length
;
230 struct res_resource
*r
;
233 toosmall (_("cursor"));
235 c
= (struct cursor
*) res_alloc (sizeof *c
);
236 c
->xhotspot
= get_16 (big_endian
, data
);
237 c
->yhotspot
= get_16 (big_endian
, data
+ 2);
238 c
->length
= length
- 4;
241 r
= (struct res_resource
*) res_alloc (sizeof *r
);
242 r
->type
= RES_TYPE_CURSOR
;
248 /* Convert a menu resource from binary. */
250 struct res_resource
*
251 bin_to_res_menu (data
, length
, big_endian
)
252 const unsigned char *data
;
253 unsigned long length
;
256 struct res_resource
*r
;
260 r
= (struct res_resource
*) res_alloc (sizeof *r
);
261 r
->type
= RES_TYPE_MENU
;
263 m
= (struct menu
*) res_alloc (sizeof *m
);
267 toosmall (_("menu header"));
269 version
= get_16 (big_endian
, data
);
274 toosmall (_("menu header"));
276 m
->items
= bin_to_res_menuitems (data
+ 4, length
- 4, big_endian
,
279 else if (version
== 1)
284 toosmall (_("menuex header"));
285 m
->help
= get_32 (big_endian
, data
+ 4);
286 offset
= get_16 (big_endian
, data
+ 2);
287 if (offset
+ 4 >= length
)
288 toosmall (_("menuex offset"));
289 m
->items
= bin_to_res_menuexitems (data
+ 4 + offset
,
290 length
- (4 + offset
),
295 fatal (_("unsupported menu version %d"), version
);
300 /* Convert menu items from binary. */
302 static struct menuitem
*
303 bin_to_res_menuitems (data
, length
, big_endian
, read
)
304 const unsigned char *data
;
305 unsigned long length
;
309 struct menuitem
*first
, **pp
;
318 int flags
, slen
, itemlen
;
323 toosmall (_("menuitem header"));
325 mi
= (struct menuitem
*) res_alloc (sizeof *mi
);
329 flags
= get_16 (big_endian
, data
);
330 mi
->type
= flags
&~ (MENUITEM_POPUP
| MENUITEM_ENDMENU
);
332 if ((flags
& MENUITEM_POPUP
) == 0)
337 if (length
< stroff
+ 2)
338 toosmall (_("menuitem header"));
340 if (get_16 (big_endian
, data
+ stroff
) == 0)
346 mi
->text
= get_unicode (data
+ stroff
, length
- stroff
, big_endian
,
349 itemlen
= stroff
+ slen
* 2 + 2;
351 if ((flags
& MENUITEM_POPUP
) == 0)
354 mi
->id
= get_16 (big_endian
, data
+ 2);
361 mi
->popup
= bin_to_res_menuitems (data
+ itemlen
, length
- itemlen
,
362 big_endian
, &subread
);
374 if ((flags
& MENUITEM_ENDMENU
) != 0)
381 /* Convert menuex items from binary. */
383 static struct menuitem
*
384 bin_to_res_menuexitems (data
, length
, big_endian
, read
)
385 const unsigned char *data
;
386 unsigned long length
;
390 struct menuitem
*first
, **pp
;
400 unsigned int itemlen
;
404 toosmall (_("menuitem header"));
406 mi
= (struct menuitem
*) res_alloc (sizeof *mi
);
407 mi
->type
= get_32 (big_endian
, data
);
408 mi
->state
= get_32 (big_endian
, data
+ 4);
409 mi
->id
= get_16 (big_endian
, data
+ 8);
411 flags
= get_16 (big_endian
, data
+ 10);
413 if (get_16 (big_endian
, data
+ 12) == 0)
419 mi
->text
= get_unicode (data
+ 12, length
- 12, big_endian
, &slen
);
421 itemlen
= 12 + slen
* 2 + 2;
422 itemlen
= (itemlen
+ 3) &~ 3;
424 if ((flags
& 1) == 0)
433 if (length
< itemlen
+ 4)
434 toosmall (_("menuitem"));
435 mi
->help
= get_32 (big_endian
, data
+ itemlen
);
438 mi
->popup
= bin_to_res_menuexitems (data
+ itemlen
,
440 big_endian
, &subread
);
452 if ((flags
& 0x80) != 0)
459 /* Convert a dialog resource from binary. */
461 static struct res_resource
*
462 bin_to_res_dialog (data
, length
, big_endian
)
463 const unsigned char *data
;
464 unsigned long length
;
471 struct dialog_control
**pp
;
472 struct res_resource
*r
;
475 toosmall (_("dialog header"));
477 d
= (struct dialog
*) res_alloc (sizeof *d
);
479 signature
= get_16 (big_endian
, data
+ 2);
480 if (signature
!= 0xffff)
483 d
->style
= get_32 (big_endian
, data
);
484 d
->exstyle
= get_32 (big_endian
, data
+ 4);
491 version
= get_16 (big_endian
, data
);
493 fatal (_("unexpected DIALOGEX version %d"), version
);
495 d
->ex
= (struct dialog_ex
*) res_alloc (sizeof (struct dialog_ex
));
496 d
->ex
->help
= get_32 (big_endian
, data
+ 4);
497 d
->exstyle
= get_32 (big_endian
, data
+ 8);
498 d
->style
= get_32 (big_endian
, data
+ 12);
502 if (length
< off
+ 10)
503 toosmall (_("dialog header"));
505 c
= get_16 (big_endian
, data
+ off
);
506 d
->x
= get_16 (big_endian
, data
+ off
+ 2);
507 d
->y
= get_16 (big_endian
, data
+ off
+ 4);
508 d
->width
= get_16 (big_endian
, data
+ off
+ 6);
509 d
->height
= get_16 (big_endian
, data
+ off
+ 8);
513 sublen
= get_resid (&d
->menu
, data
+ off
, length
- off
, big_endian
);
516 sublen
= get_resid (&d
->class, data
+ off
, length
- off
, big_endian
);
519 d
->caption
= get_unicode (data
+ off
, length
- off
, big_endian
, &sublen
);
520 off
+= sublen
* 2 + 2;
524 if ((d
->style
& DS_SETFONT
) == 0)
532 d
->ex
->charset
= 1; /* Default charset. */
537 if (length
< off
+ 2)
538 toosmall (_("dialog font point size"));
540 d
->pointsize
= get_16 (big_endian
, data
+ off
);
545 if (length
< off
+ 4)
546 toosmall (_("dialogex font information"));
547 d
->ex
->weight
= get_16 (big_endian
, data
+ off
);
548 d
->ex
->italic
= get_8 (data
+ off
+ 2);
549 d
->ex
->charset
= get_8 (data
+ off
+ 3);
553 d
->font
= get_unicode (data
+ off
, length
- off
, big_endian
, &sublen
);
554 off
+= sublen
* 2 + 2;
560 for (i
= 0; i
< c
; i
++)
562 struct dialog_control
*dc
;
565 off
= (off
+ 3) &~ 3;
567 dc
= (struct dialog_control
*) res_alloc (sizeof *dc
);
571 if (length
< off
+ 8)
572 toosmall (_("dialog control"));
574 dc
->style
= get_32 (big_endian
, data
+ off
);
575 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
581 if (length
< off
+ 12)
582 toosmall (_("dialogex control"));
583 dc
->help
= get_32 (big_endian
, data
+ off
);
584 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
585 dc
->style
= get_32 (big_endian
, data
+ off
+ 8);
589 if (length
< off
+ 10)
590 toosmall (_("dialog control"));
592 dc
->x
= get_16 (big_endian
, data
+ off
);
593 dc
->y
= get_16 (big_endian
, data
+ off
+ 2);
594 dc
->width
= get_16 (big_endian
, data
+ off
+ 4);
595 dc
->height
= get_16 (big_endian
, data
+ off
+ 6);
598 dc
->id
= get_32 (big_endian
, data
+ off
+ 8);
600 dc
->id
= get_16 (big_endian
, data
+ off
+ 8);
602 off
+= 10 + (d
->ex
!= NULL
? 2 : 0);
604 sublen
= get_resid (&dc
->class, data
+ off
, length
- off
, big_endian
);
607 sublen
= get_resid (&dc
->text
, data
+ off
, length
- off
, big_endian
);
610 if (length
< off
+ 2)
611 toosmall (_("dialog control end"));
613 datalen
= get_16 (big_endian
, data
+ off
);
620 off
= (off
+ 3) &~ 3;
622 if (length
< off
+ datalen
)
623 toosmall (_("dialog control data"));
625 dc
->data
= ((struct rcdata_item
*)
626 res_alloc (sizeof (struct rcdata_item
)));
627 dc
->data
->next
= NULL
;
628 dc
->data
->type
= RCDATA_BUFFER
;
629 dc
->data
->u
.buffer
.length
= datalen
;
630 dc
->data
->u
.buffer
.data
= data
+ off
;
640 r
= (struct res_resource
*) res_alloc (sizeof *r
);
641 r
->type
= RES_TYPE_DIALOG
;
647 /* Convert a stringtable resource from binary. */
649 static struct res_resource
*
650 bin_to_res_string (data
, length
, big_endian
)
651 const unsigned char *data
;
652 unsigned long length
;
655 struct stringtable
*st
;
657 struct res_resource
*r
;
659 st
= (struct stringtable
*) res_alloc (sizeof *st
);
661 for (i
= 0; i
< 16; i
++)
666 toosmall (_("stringtable string length"));
667 slen
= get_16 (big_endian
, data
);
668 st
->strings
[i
].length
= slen
;
675 if (length
< 2 + 2 * slen
)
676 toosmall (_("stringtable string"));
678 s
= (unichar
*) res_alloc (slen
* sizeof (unichar
));
679 st
->strings
[i
].string
= s
;
681 for (j
= 0; j
< slen
; j
++)
682 s
[j
] = get_16 (big_endian
, data
+ 2 + j
* 2);
685 data
+= 2 + 2 * slen
;
686 length
-= 2 + 2 * slen
;
689 r
= (struct res_resource
*) res_alloc (sizeof *r
);
690 r
->type
= RES_TYPE_STRINGTABLE
;
691 r
->u
.stringtable
= st
;
696 /* Convert a fontdir resource from binary. */
698 static struct res_resource
*
699 bin_to_res_fontdir (data
, length
, big_endian
)
700 const unsigned char *data
;
701 unsigned long length
;
705 struct fontdir
*first
, **pp
;
706 struct res_resource
*r
;
709 toosmall (_("fontdir header"));
711 c
= get_16 (big_endian
, data
);
716 for (i
= 0; i
< c
; i
++)
722 toosmall (_("fontdir"));
724 fd
= (struct fontdir
*) res_alloc (sizeof *fd
);
725 fd
->index
= get_16 (big_endian
, data
);
727 /* To work out the length of the fontdir data, we must get the
728 length of the device name and face name strings, even though
729 we don't store them in the fontdir structure. The
730 documentation says that these are NULL terminated char
731 strings, not Unicode strings. */
735 while (off
< length
&& data
[off
] != '\0')
738 toosmall (_("fontdir device name"));
741 while (off
< length
&& data
[off
] != '\0')
744 toosmall (_("fontdir face name"));
754 /* The documentation does not indicate that any rounding is
761 r
= (struct res_resource
*) res_alloc (sizeof *r
);
762 r
->type
= RES_TYPE_FONTDIR
;
763 r
->u
.fontdir
= first
;
768 /* Convert an accelerators resource from binary. */
770 static struct res_resource
*
771 bin_to_res_accelerators (data
, length
, big_endian
)
772 const unsigned char *data
;
773 unsigned long length
;
776 struct accelerator
*first
, **pp
;
777 struct res_resource
*r
;
784 struct accelerator
*a
;
787 toosmall (_("accelerator"));
789 a
= (struct accelerator
*) res_alloc (sizeof *a
);
791 a
->flags
= get_16 (big_endian
, data
);
792 a
->key
= get_16 (big_endian
, data
+ 2);
793 a
->id
= get_16 (big_endian
, data
+ 4);
799 if ((a
->flags
& ACC_LAST
) != 0)
806 r
= (struct res_resource
*) res_alloc (sizeof *r
);
807 r
->type
= RES_TYPE_ACCELERATOR
;
813 /* Convert an rcdata resource from binary. */
815 static struct res_resource
*
816 bin_to_res_rcdata (data
, length
, big_endian
)
817 const unsigned char *data
;
818 unsigned long length
;
819 int big_endian ATTRIBUTE_UNUSED
;
821 struct rcdata_item
*ri
;
822 struct res_resource
*r
;
824 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
827 ri
->type
= RCDATA_BUFFER
;
828 ri
->u
.buffer
.length
= length
;
829 ri
->u
.buffer
.data
= data
;
831 r
= (struct res_resource
*) res_alloc (sizeof *r
);
832 r
->type
= RES_TYPE_RCDATA
;
838 /* Convert a group cursor resource from binary. */
840 static struct res_resource
*
841 bin_to_res_group_cursor (data
, length
, big_endian
)
842 const unsigned char *data
;
843 unsigned long length
;
847 struct group_cursor
*first
, **pp
;
848 struct res_resource
*r
;
851 toosmall (_("group cursor header"));
853 type
= get_16 (big_endian
, data
+ 2);
855 fatal (_("unexpected group cursor type %d"), type
);
857 c
= get_16 (big_endian
, data
+ 4);
865 for (i
= 0; i
< c
; i
++)
867 struct group_cursor
*gc
;
870 toosmall (_("group cursor"));
872 gc
= (struct group_cursor
*) res_alloc (sizeof *gc
);
874 gc
->width
= get_16 (big_endian
, data
);
875 gc
->height
= get_16 (big_endian
, data
+ 2);
876 gc
->planes
= get_16 (big_endian
, data
+ 4);
877 gc
->bits
= get_16 (big_endian
, data
+ 6);
878 gc
->bytes
= get_32 (big_endian
, data
+ 8);
879 gc
->index
= get_16 (big_endian
, data
+ 12);
889 r
= (struct res_resource
*) res_alloc (sizeof *r
);
890 r
->type
= RES_TYPE_GROUP_CURSOR
;
891 r
->u
.group_cursor
= first
;
896 /* Convert a group icon resource from binary. */
898 static struct res_resource
*
899 bin_to_res_group_icon (data
, length
, big_endian
)
900 const unsigned char *data
;
901 unsigned long length
;
905 struct group_icon
*first
, **pp
;
906 struct res_resource
*r
;
909 toosmall (_("group icon header"));
911 type
= get_16 (big_endian
, data
+ 2);
913 fatal (_("unexpected group icon type %d"), type
);
915 c
= get_16 (big_endian
, data
+ 4);
923 for (i
= 0; i
< c
; i
++)
925 struct group_icon
*gi
;
928 toosmall (_("group icon"));
930 gi
= (struct group_icon
*) res_alloc (sizeof *gi
);
933 gi
->height
= data
[1];
934 gi
->colors
= data
[2];
935 gi
->planes
= get_16 (big_endian
, data
+ 4);
936 gi
->bits
= get_16 (big_endian
, data
+ 6);
937 gi
->bytes
= get_32 (big_endian
, data
+ 8);
938 gi
->index
= get_16 (big_endian
, data
+ 12);
948 r
= (struct res_resource
*) res_alloc (sizeof *r
);
949 r
->type
= RES_TYPE_GROUP_ICON
;
950 r
->u
.group_icon
= first
;
955 /* Extract data from a version header. If KEY is not NULL, then the
956 key must be KEY; otherwise, the key is returned in *PKEY. This
957 sets *LEN to the total length, *VALLEN to the value length, *TYPE
958 to the type, and *OFF to the offset to the children. */
961 get_version_header (data
, length
, big_endian
, key
, pkey
, len
, vallen
, type
,
963 const unsigned char *data
;
964 unsigned long length
;
976 *len
= get_16 (big_endian
, data
);
977 *vallen
= get_16 (big_endian
, data
+ 2);
978 *type
= get_16 (big_endian
, data
+ 4);
989 *pkey
= get_unicode (data
, length
, big_endian
, &sublen
);
990 *off
+= sublen
* 2 + 2;
998 if (get_16 (big_endian
, data
) != (unsigned char) *key
)
999 fatal (_("unexpected version string"));
1012 *off
= (*off
+ 3) &~ 3;
1015 /* Convert a version resource from binary. */
1017 static struct res_resource
*
1018 bin_to_res_version (data
, length
, big_endian
)
1019 const unsigned char *data
;
1020 unsigned long length
;
1023 int verlen
, vallen
, type
, off
;
1024 struct fixed_versioninfo
*fi
;
1025 struct ver_info
*first
, **pp
;
1026 struct versioninfo
*v
;
1027 struct res_resource
*r
;
1029 get_version_header (data
, length
, big_endian
, "VS_VERSION_INFO",
1030 (unichar
**) NULL
, &verlen
, &vallen
, &type
, &off
);
1032 if ((unsigned int) verlen
!= length
)
1033 fatal (_("version length %d does not match resource length %lu"),
1037 fatal (_("unexpected version type %d"), type
);
1046 unsigned long signature
, fiv
;
1049 fatal (_("unexpected fixed version information length %d"), vallen
);
1052 toosmall (_("fixed version info"));
1054 signature
= get_32 (big_endian
, data
);
1055 if (signature
!= 0xfeef04bd)
1056 fatal (_("unexpected fixed version signature %lu"), signature
);
1058 fiv
= get_32 (big_endian
, data
+ 4);
1059 if (fiv
!= 0 && fiv
!= 0x10000)
1060 fatal (_("unexpected fixed version info version %lu"), fiv
);
1062 fi
= (struct fixed_versioninfo
*) res_alloc (sizeof *fi
);
1064 fi
->file_version_ms
= get_32 (big_endian
, data
+ 8);
1065 fi
->file_version_ls
= get_32 (big_endian
, data
+ 12);
1066 fi
->product_version_ms
= get_32 (big_endian
, data
+ 16);
1067 fi
->product_version_ls
= get_32 (big_endian
, data
+ 20);
1068 fi
->file_flags_mask
= get_32 (big_endian
, data
+ 24);
1069 fi
->file_flags
= get_32 (big_endian
, data
+ 28);
1070 fi
->file_os
= get_32 (big_endian
, data
+ 32);
1071 fi
->file_type
= get_32 (big_endian
, data
+ 36);
1072 fi
->file_subtype
= get_32 (big_endian
, data
+ 40);
1073 fi
->file_date_ms
= get_32 (big_endian
, data
+ 44);
1074 fi
->file_date_ls
= get_32 (big_endian
, data
+ 48);
1085 struct ver_info
*vi
;
1089 toosmall (_("version var info"));
1091 vi
= (struct ver_info
*) res_alloc (sizeof *vi
);
1093 ch
= get_16 (big_endian
, data
+ 6);
1097 struct ver_stringinfo
**ppvs
;
1099 vi
->type
= VERINFO_STRING
;
1101 get_version_header (data
, length
, big_endian
, "StringFileInfo",
1102 (unichar
**) NULL
, &verlen
, &vallen
, &type
,
1106 fatal (_("unexpected stringfileinfo value length %d"), vallen
);
1111 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1112 &vi
->u
.string
.language
, &verlen
, &vallen
,
1116 fatal (_("unexpected version stringtable value length %d"), vallen
);
1122 vi
->u
.string
.strings
= NULL
;
1123 ppvs
= &vi
->u
.string
.strings
;
1125 /* It's convenient to round verlen to a 4 byte alignment,
1126 since we round the subvariables in the loop. */
1127 verlen
= (verlen
+ 3) &~ 3;
1131 struct ver_stringinfo
*vs
;
1132 int subverlen
, vslen
, valoff
;
1134 vs
= (struct ver_stringinfo
*) res_alloc (sizeof *vs
);
1136 get_version_header (data
, length
, big_endian
,
1137 (const char *) NULL
, &vs
->key
, &subverlen
,
1138 &vallen
, &type
, &off
);
1140 subverlen
= (subverlen
+ 3) &~ 3;
1145 vs
->value
= get_unicode (data
, length
, big_endian
, &vslen
);
1146 valoff
= vslen
* 2 + 2;
1147 valoff
= (valoff
+ 3) &~ 3;
1149 if (off
+ valoff
!= subverlen
)
1150 fatal (_("unexpected version string length %d != %d + %d"),
1151 subverlen
, off
, valoff
);
1160 if (verlen
< subverlen
)
1161 fatal (_("unexpected version string length %d < %d"),
1164 verlen
-= subverlen
;
1169 struct ver_varinfo
**ppvv
;
1171 vi
->type
= VERINFO_VAR
;
1173 get_version_header (data
, length
, big_endian
, "VarFileInfo",
1174 (unichar
**) NULL
, &verlen
, &vallen
, &type
,
1178 fatal (_("unexpected varfileinfo value length %d"), vallen
);
1183 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1184 &vi
->u
.var
.key
, &verlen
, &vallen
, &type
, &off
);
1189 vi
->u
.var
.var
= NULL
;
1190 ppvv
= &vi
->u
.var
.var
;
1194 struct ver_varinfo
*vv
;
1197 toosmall (_("version varfileinfo"));
1199 vv
= (struct ver_varinfo
*) res_alloc (sizeof *vv
);
1201 vv
->language
= get_16 (big_endian
, data
);
1202 vv
->charset
= get_16 (big_endian
, data
+ 2);
1212 fatal (_("unexpected version value length %d"), vallen
);
1218 fatal (_("unexpected version string"));
1225 v
= (struct versioninfo
*) res_alloc (sizeof *v
);
1229 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1230 r
->type
= RES_TYPE_VERSIONINFO
;
1231 r
->u
.versioninfo
= v
;
1236 /* Convert an arbitrary user defined resource from binary. */
1238 static struct res_resource
*
1239 bin_to_res_userdata (data
, length
, big_endian
)
1240 const unsigned char *data
;
1241 unsigned long length
;
1242 int big_endian ATTRIBUTE_UNUSED
;
1244 struct rcdata_item
*ri
;
1245 struct res_resource
*r
;
1247 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
1250 ri
->type
= RCDATA_BUFFER
;
1251 ri
->u
.buffer
.length
= length
;
1252 ri
->u
.buffer
.data
= data
;
1254 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1255 r
->type
= RES_TYPE_USERDATA
;
1261 /* Macros to swap out values. */
1263 #define put_8(v, s) (*((unsigned char *) (s)) = (unsigned char) (v))
1264 #define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
1265 #define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
1267 /* Local functions used to convert resources to binary format. */
1269 static void dword_align_bin
PARAMS ((struct bindata
***, unsigned long *));
1270 static struct bindata
*resid_to_bin
PARAMS ((struct res_id
, int));
1271 static struct bindata
*unicode_to_bin
PARAMS ((const unichar
*, int));
1272 static struct bindata
*res_to_bin_accelerator
1273 PARAMS ((const struct accelerator
*, int));
1274 static struct bindata
*res_to_bin_cursor
1275 PARAMS ((const struct cursor
*, int));
1276 static struct bindata
*res_to_bin_group_cursor
1277 PARAMS ((const struct group_cursor
*, int));
1278 static struct bindata
*res_to_bin_dialog
1279 PARAMS ((const struct dialog
*, int));
1280 static struct bindata
*res_to_bin_fontdir
1281 PARAMS ((const struct fontdir
*, int));
1282 static struct bindata
*res_to_bin_group_icon
1283 PARAMS ((const struct group_icon
*, int));
1284 static struct bindata
*res_to_bin_menu
1285 PARAMS ((const struct menu
*, int));
1286 static struct bindata
*res_to_bin_menuitems
1287 PARAMS ((const struct menuitem
*, int));
1288 static struct bindata
*res_to_bin_menuexitems
1289 PARAMS ((const struct menuitem
*, int));
1290 static struct bindata
*res_to_bin_rcdata
1291 PARAMS ((const struct rcdata_item
*, int));
1292 static struct bindata
*res_to_bin_stringtable
1293 PARAMS ((const struct stringtable
*, int));
1294 static struct bindata
*string_to_unicode_bin
PARAMS ((const char *, int));
1295 static struct bindata
*res_to_bin_versioninfo
1296 PARAMS ((const struct versioninfo
*, int));
1297 static struct bindata
*res_to_bin_generic
1298 PARAMS ((unsigned long, const unsigned char *));
1300 /* Convert a resource to binary. */
1303 res_to_bin (res
, big_endian
)
1304 const struct res_resource
*res
;
1311 case RES_TYPE_BITMAP
:
1314 case RES_TYPE_MESSAGETABLE
:
1315 return res_to_bin_generic (res
->u
.data
.length
, res
->u
.data
.data
);
1316 case RES_TYPE_ACCELERATOR
:
1317 return res_to_bin_accelerator (res
->u
.acc
, big_endian
);
1318 case RES_TYPE_CURSOR
:
1319 return res_to_bin_cursor (res
->u
.cursor
, big_endian
);
1320 case RES_TYPE_GROUP_CURSOR
:
1321 return res_to_bin_group_cursor (res
->u
.group_cursor
, big_endian
);
1322 case RES_TYPE_DIALOG
:
1323 return res_to_bin_dialog (res
->u
.dialog
, big_endian
);
1324 case RES_TYPE_FONTDIR
:
1325 return res_to_bin_fontdir (res
->u
.fontdir
, big_endian
);
1326 case RES_TYPE_GROUP_ICON
:
1327 return res_to_bin_group_icon (res
->u
.group_icon
, big_endian
);
1329 return res_to_bin_menu (res
->u
.menu
, big_endian
);
1330 case RES_TYPE_RCDATA
:
1331 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1332 case RES_TYPE_STRINGTABLE
:
1333 return res_to_bin_stringtable (res
->u
.stringtable
, big_endian
);
1334 case RES_TYPE_USERDATA
:
1335 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1336 case RES_TYPE_VERSIONINFO
:
1337 return res_to_bin_versioninfo (res
->u
.versioninfo
, big_endian
);
1341 /* Align to a 32 bit boundary. PPP points to the of a list of bindata
1342 structures. LENGTH points to the length of the structures. If
1343 necessary, this adds a new bindata to bring length up to a 32 bit
1344 boundary. It updates *PPP and *LENGTH. */
1347 dword_align_bin (ppp
, length
)
1348 struct bindata
***ppp
;
1349 unsigned long *length
;
1354 if ((*length
& 3) == 0)
1357 add
= 4 - (*length
& 3);
1359 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1361 d
->data
= (unsigned char *) reswr_alloc (add
);
1362 memset (d
->data
, 0, add
);
1366 *ppp
= &(**ppp
)->next
;
1371 /* Convert a resource ID to binary. This always returns exactly one
1372 bindata structure. */
1374 static struct bindata
*
1375 resid_to_bin (id
, big_endian
)
1381 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1386 d
->data
= (unsigned char *) reswr_alloc (4);
1387 put_16 (big_endian
, 0xffff, d
->data
);
1388 put_16 (big_endian
, id
.u
.id
, d
->data
+ 2);
1394 d
->length
= id
.u
.n
.length
* 2 + 2;
1395 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1396 for (i
= 0; i
< id
.u
.n
.length
; i
++)
1397 put_16 (big_endian
, id
.u
.n
.name
[i
], d
->data
+ i
* 2);
1398 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1406 /* Convert a null terminated unicode string to binary. This always
1407 returns exactly one bindata structure. */
1409 static struct bindata
*
1410 unicode_to_bin (str
, big_endian
)
1422 for (s
= str
; *s
!= 0; s
++)
1426 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1427 d
->length
= len
* 2 + 2;
1428 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1431 put_16 (big_endian
, 0, d
->data
);
1437 for (s
= str
, i
= 0; *s
!= 0; s
++, i
++)
1438 put_16 (big_endian
, *s
, d
->data
+ i
* 2);
1439 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1447 /* Convert an accelerator resource to binary. */
1449 static struct bindata
*
1450 res_to_bin_accelerator (accelerators
, big_endian
)
1451 const struct accelerator
*accelerators
;
1454 struct bindata
*first
, **pp
;
1455 const struct accelerator
*a
;
1460 for (a
= accelerators
; a
!= NULL
; a
= a
->next
)
1464 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1466 d
->data
= (unsigned char *) reswr_alloc (8);
1469 a
->flags
| (a
->next
!= NULL
? 0 : ACC_LAST
),
1471 put_16 (big_endian
, a
->key
, d
->data
+ 2);
1472 put_16 (big_endian
, a
->id
, d
->data
+ 4);
1473 put_16 (big_endian
, 0, d
->data
+ 8);
1483 /* Convert a cursor resource to binary. */
1485 static struct bindata
*
1486 res_to_bin_cursor (c
, big_endian
)
1487 const struct cursor
*c
;
1492 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1494 d
->data
= (unsigned char *) reswr_alloc (4);
1496 put_16 (big_endian
, c
->xhotspot
, d
->data
);
1497 put_16 (big_endian
, c
->yhotspot
, d
->data
+ 2);
1499 d
->next
= (struct bindata
*) reswr_alloc (sizeof *d
);
1500 d
->next
->length
= c
->length
;
1501 d
->next
->data
= (unsigned char *) c
->data
;
1502 d
->next
->next
= NULL
;
1507 /* Convert a group cursor resource to binary. */
1509 static struct bindata
*
1510 res_to_bin_group_cursor (group_cursors
, big_endian
)
1511 const struct group_cursor
*group_cursors
;
1514 struct bindata
*first
, **pp
;
1516 const struct group_cursor
*gc
;
1518 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1520 first
->data
= (unsigned char *) reswr_alloc (6);
1522 put_16 (big_endian
, 0, first
->data
);
1523 put_16 (big_endian
, 2, first
->data
+ 2);
1529 for (gc
= group_cursors
; gc
!= NULL
; gc
= gc
->next
)
1535 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1537 d
->data
= (unsigned char *) reswr_alloc (14);
1539 put_16 (big_endian
, gc
->width
, d
->data
);
1540 put_16 (big_endian
, gc
->height
, d
->data
+ 2);
1541 put_16 (big_endian
, gc
->planes
, d
->data
+ 4);
1542 put_16 (big_endian
, gc
->bits
, d
->data
+ 6);
1543 put_32 (big_endian
, gc
->bytes
, d
->data
+ 8);
1544 put_16 (big_endian
, gc
->index
, d
->data
+ 12);
1551 put_16 (big_endian
, c
, first
->data
+ 4);
1556 /* Convert a dialog resource to binary. */
1558 static struct bindata
*
1559 res_to_bin_dialog (dialog
, big_endian
)
1560 const struct dialog
*dialog
;
1564 struct bindata
*first
, **pp
;
1565 unsigned long length
;
1567 struct dialog_control
*dc
;
1569 dialogex
= extended_dialog (dialog
);
1571 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1572 first
->length
= dialogex
? 26 : 18;
1573 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1575 length
= first
->length
;
1579 put_32 (big_endian
, dialog
->style
, first
->data
);
1580 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 4);
1585 put_16 (big_endian
, 1, first
->data
);
1586 put_16 (big_endian
, 0xffff, first
->data
+ 2);
1588 if (dialog
->ex
== NULL
)
1589 put_32 (big_endian
, 0, first
->data
+ 4);
1591 put_32 (big_endian
, dialog
->ex
->help
, first
->data
+ 4);
1592 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 8);
1593 put_32 (big_endian
, dialog
->style
, first
->data
+ 12);
1597 put_16 (big_endian
, dialog
->x
, first
->data
+ off
+ 2);
1598 put_16 (big_endian
, dialog
->y
, first
->data
+ off
+ 4);
1599 put_16 (big_endian
, dialog
->width
, first
->data
+ off
+ 6);
1600 put_16 (big_endian
, dialog
->height
, first
->data
+ off
+ 8);
1604 *pp
= resid_to_bin (dialog
->menu
, big_endian
);
1605 length
+= (*pp
)->length
;
1608 *pp
= resid_to_bin (dialog
->class, big_endian
);
1609 length
+= (*pp
)->length
;
1612 *pp
= unicode_to_bin (dialog
->caption
, big_endian
);
1613 length
+= (*pp
)->length
;
1616 if ((dialog
->style
& DS_SETFONT
) != 0)
1620 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1621 d
->length
= dialogex
? 6 : 2;
1622 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1624 length
+= d
->length
;
1626 put_16 (big_endian
, dialog
->pointsize
, d
->data
);
1630 if (dialog
->ex
== NULL
)
1632 put_16 (big_endian
, 0, d
->data
+ 2);
1633 put_8 (0, d
->data
+ 4);
1634 put_8 (1, d
->data
+ 5);
1638 put_16 (big_endian
, dialog
->ex
->weight
, d
->data
+ 2);
1639 put_8 (dialog
->ex
->italic
, d
->data
+ 4);
1640 put_8 (dialog
->ex
->charset
, d
->data
+ 5);
1647 *pp
= unicode_to_bin (dialog
->font
, big_endian
);
1648 length
+= (*pp
)->length
;
1653 for (dc
= dialog
->controls
; dc
!= NULL
; dc
= dc
->next
)
1660 dword_align_bin (&pp
, &length
);
1662 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1663 d
->length
= dialogex
? 24 : 18;
1664 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1666 length
+= d
->length
;
1670 put_32 (big_endian
, dc
->style
, d
->data
);
1671 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1676 put_32 (big_endian
, dc
->help
, d
->data
);
1677 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1678 put_32 (big_endian
, dc
->style
, d
->data
+ 8);
1682 put_16 (big_endian
, dc
->x
, d
->data
+ dcoff
);
1683 put_16 (big_endian
, dc
->y
, d
->data
+ dcoff
+ 2);
1684 put_16 (big_endian
, dc
->width
, d
->data
+ dcoff
+ 4);
1685 put_16 (big_endian
, dc
->height
, d
->data
+ dcoff
+ 6);
1688 put_32 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1690 put_16 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1695 *pp
= resid_to_bin (dc
->class, big_endian
);
1696 length
+= (*pp
)->length
;
1699 *pp
= resid_to_bin (dc
->text
, big_endian
);
1700 length
+= (*pp
)->length
;
1703 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1705 d
->data
= (unsigned char *) reswr_alloc (2);
1713 if (dc
->data
== NULL
)
1714 put_16 (big_endian
, 0, d
->data
);
1717 unsigned long sublen
;
1719 dword_align_bin (&pp
, &length
);
1721 *pp
= res_to_bin_rcdata (dc
->data
, big_endian
);
1725 sublen
+= (*pp
)->length
;
1729 put_16 (big_endian
, sublen
, d
->data
);
1734 put_16 (big_endian
, c
, first
->data
+ off
);
1739 /* Convert a fontdir resource to binary. */
1741 static struct bindata
*
1742 res_to_bin_fontdir (fontdirs
, big_endian
)
1743 const struct fontdir
*fontdirs
;
1746 struct bindata
*first
, **pp
;
1748 const struct fontdir
*fd
;
1750 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1752 first
->data
= (unsigned char *) reswr_alloc (2);
1758 for (fd
= fontdirs
; fd
!= NULL
; fd
= fd
->next
)
1764 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1766 d
->data
= (unsigned char *) reswr_alloc (2);
1768 put_16 (big_endian
, fd
->index
, d
->data
);
1773 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1774 d
->length
= fd
->length
;
1775 d
->data
= (unsigned char *) fd
->data
;
1782 put_16 (big_endian
, c
, first
->data
);
1787 /* Convert a group icon resource to binary. */
1789 static struct bindata
*
1790 res_to_bin_group_icon (group_icons
, big_endian
)
1791 const struct group_icon
*group_icons
;
1794 struct bindata
*first
, **pp
;
1796 const struct group_icon
*gi
;
1798 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1800 first
->data
= (unsigned char *) reswr_alloc (6);
1802 put_16 (big_endian
, 0, first
->data
);
1803 put_16 (big_endian
, 1, first
->data
+ 2);
1809 for (gi
= group_icons
; gi
!= NULL
; gi
= gi
->next
)
1815 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1817 d
->data
= (unsigned char *) reswr_alloc (14);
1819 d
->data
[0] = gi
->width
;
1820 d
->data
[1] = gi
->height
;
1821 d
->data
[2] = gi
->colors
;
1823 put_16 (big_endian
, gi
->planes
, d
->data
+ 4);
1824 put_16 (big_endian
, gi
->bits
, d
->data
+ 6);
1825 put_32 (big_endian
, gi
->bytes
, d
->data
+ 8);
1826 put_16 (big_endian
, gi
->index
, d
->data
+ 12);
1833 put_16 (big_endian
, c
, first
->data
+ 4);
1838 /* Convert a menu resource to binary. */
1840 static struct bindata
*
1841 res_to_bin_menu (menu
, big_endian
)
1842 const struct menu
*menu
;
1848 menuex
= extended_menu (menu
);
1850 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1851 d
->length
= menuex
? 8 : 4;
1852 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1856 put_16 (big_endian
, 0, d
->data
);
1857 put_16 (big_endian
, 0, d
->data
+ 2);
1859 d
->next
= res_to_bin_menuitems (menu
->items
, big_endian
);
1863 put_16 (big_endian
, 1, d
->data
);
1864 put_16 (big_endian
, 4, d
->data
+ 2);
1865 put_32 (big_endian
, menu
->help
, d
->data
+ 4);
1867 d
->next
= res_to_bin_menuexitems (menu
->items
, big_endian
);
1873 /* Convert menu items to binary. */
1875 static struct bindata
*
1876 res_to_bin_menuitems (items
, big_endian
)
1877 const struct menuitem
*items
;
1880 struct bindata
*first
, **pp
;
1881 const struct menuitem
*mi
;
1886 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1891 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1892 d
->length
= mi
->popup
== NULL
? 4 : 2;
1893 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1896 if (mi
->next
== NULL
)
1897 flags
|= MENUITEM_ENDMENU
;
1898 if (mi
->popup
!= NULL
)
1899 flags
|= MENUITEM_POPUP
;
1901 put_16 (big_endian
, flags
, d
->data
);
1903 if (mi
->popup
== NULL
)
1904 put_16 (big_endian
, mi
->id
, d
->data
+ 2);
1909 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1912 if (mi
->popup
!= NULL
)
1914 *pp
= res_to_bin_menuitems (mi
->popup
, big_endian
);
1923 /* Convert menuex items to binary. */
1925 static struct bindata
*
1926 res_to_bin_menuexitems (items
, big_endian
)
1927 const struct menuitem
*items
;
1930 struct bindata
*first
, **pp
;
1931 unsigned long length
;
1932 const struct menuitem
*mi
;
1939 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1944 dword_align_bin (&pp
, &length
);
1946 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1948 d
->data
= (unsigned char *) reswr_alloc (12);
1952 put_32 (big_endian
, mi
->type
, d
->data
);
1953 put_32 (big_endian
, mi
->state
, d
->data
+ 4);
1954 put_16 (big_endian
, mi
->id
, d
->data
+ 8);
1957 if (mi
->next
== NULL
)
1959 if (mi
->popup
!= NULL
)
1961 put_16 (big_endian
, flags
, d
->data
+ 10);
1966 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1967 length
+= (*pp
)->length
;
1970 if (mi
->popup
!= NULL
)
1972 dword_align_bin (&pp
, &length
);
1974 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1976 d
->data
= (unsigned char *) reswr_alloc (4);
1978 put_32 (big_endian
, mi
->help
, d
->data
);
1983 *pp
= res_to_bin_menuexitems (mi
->popup
, big_endian
);
1986 length
+= (*pp
)->length
;
1995 /* Convert an rcdata resource to binary. This is also used to convert
1996 other information which happens to be stored in rcdata_item lists
1999 static struct bindata
*
2000 res_to_bin_rcdata (items
, big_endian
)
2001 const struct rcdata_item
*items
;
2004 struct bindata
*first
, **pp
;
2005 const struct rcdata_item
*ri
;
2010 for (ri
= items
; ri
!= NULL
; ri
= ri
->next
)
2014 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2023 d
->data
= (unsigned char *) reswr_alloc (2);
2024 put_16 (big_endian
, ri
->u
.word
, d
->data
);
2029 d
->data
= (unsigned char *) reswr_alloc (4);
2030 put_32 (big_endian
, ri
->u
.dword
, d
->data
);
2034 d
->length
= ri
->u
.string
.length
;
2035 d
->data
= (unsigned char *) ri
->u
.string
.s
;
2038 case RCDATA_WSTRING
:
2042 d
->length
= ri
->u
.wstring
.length
* 2;
2043 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2044 for (i
= 0; i
< ri
->u
.wstring
.length
; i
++)
2045 put_16 (big_endian
, ri
->u
.wstring
.w
[i
], d
->data
+ i
* 2);
2050 d
->length
= ri
->u
.buffer
.length
;
2051 d
->data
= (unsigned char *) ri
->u
.buffer
.data
;
2063 /* Convert a stringtable resource to binary. */
2065 static struct bindata
*
2066 res_to_bin_stringtable (st
, big_endian
)
2067 const struct stringtable
*st
;
2070 struct bindata
*first
, **pp
;
2076 for (i
= 0; i
< 16; i
++)
2082 slen
= st
->strings
[i
].length
;
2083 s
= st
->strings
[i
].string
;
2085 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2086 d
->length
= 2 + slen
* 2;
2087 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2089 put_16 (big_endian
, slen
, d
->data
);
2091 for (j
= 0; j
< slen
; j
++)
2092 put_16 (big_endian
, s
[j
], d
->data
+ 2 + j
* 2);
2102 /* Convert an ASCII string to a unicode binary string. This always
2103 returns exactly one bindata structure. */
2105 static struct bindata
*
2106 string_to_unicode_bin (s
, big_endian
)
2115 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2116 d
->length
= len
* 2 + 2;
2117 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2119 for (i
= 0; i
< len
; i
++)
2120 put_16 (big_endian
, s
[i
], d
->data
+ i
* 2);
2121 put_16 (big_endian
, 0, d
->data
+ i
* 2);
2128 /* Convert a versioninfo resource to binary. */
2130 static struct bindata
*
2131 res_to_bin_versioninfo (versioninfo
, big_endian
)
2132 const struct versioninfo
*versioninfo
;
2135 struct bindata
*first
, **pp
;
2136 unsigned long length
;
2137 struct ver_info
*vi
;
2139 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
2141 first
->data
= (unsigned char *) reswr_alloc (6);
2145 if (versioninfo
->fixed
== NULL
)
2146 put_16 (big_endian
, 0, first
->data
+ 2);
2148 put_16 (big_endian
, 52, first
->data
+ 2);
2150 put_16 (big_endian
, 0, first
->data
+ 4);
2154 *pp
= string_to_unicode_bin ("VS_VERSION_INFO", big_endian
);
2155 length
+= (*pp
)->length
;
2158 dword_align_bin (&pp
, &length
);
2160 if (versioninfo
->fixed
!= NULL
)
2162 const struct fixed_versioninfo
*fi
;
2165 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2167 d
->data
= (unsigned char *) reswr_alloc (52);
2171 fi
= versioninfo
->fixed
;
2173 put_32 (big_endian
, 0xfeef04bd, d
->data
);
2174 put_32 (big_endian
, 0x10000, d
->data
+ 4);
2175 put_32 (big_endian
, fi
->file_version_ms
, d
->data
+ 8);
2176 put_32 (big_endian
, fi
->file_version_ls
, d
->data
+ 12);
2177 put_32 (big_endian
, fi
->product_version_ms
, d
->data
+ 16);
2178 put_32 (big_endian
, fi
->product_version_ls
, d
->data
+ 20);
2179 put_32 (big_endian
, fi
->file_flags_mask
, d
->data
+ 24);
2180 put_32 (big_endian
, fi
->file_flags
, d
->data
+ 28);
2181 put_32 (big_endian
, fi
->file_os
, d
->data
+ 32);
2182 put_32 (big_endian
, fi
->file_type
, d
->data
+ 36);
2183 put_32 (big_endian
, fi
->file_subtype
, d
->data
+ 40);
2184 put_32 (big_endian
, fi
->file_date_ms
, d
->data
+ 44);
2185 put_32 (big_endian
, fi
->file_date_ls
, d
->data
+ 48);
2192 for (vi
= versioninfo
->var
; vi
!= NULL
; vi
= vi
->next
)
2194 struct bindata
*vid
;
2195 unsigned long vilen
;
2197 dword_align_bin (&pp
, &length
);
2199 vid
= (struct bindata
*) reswr_alloc (sizeof *vid
);
2201 vid
->data
= (unsigned char *) reswr_alloc (6);
2206 put_16 (big_endian
, 0, vid
->data
+ 2);
2207 put_16 (big_endian
, 0, vid
->data
+ 4);
2217 case VERINFO_STRING
:
2219 unsigned long hold
, vslen
;
2220 struct bindata
*vsd
;
2221 const struct ver_stringinfo
*vs
;
2223 *pp
= string_to_unicode_bin ("StringFileInfo", big_endian
);
2224 length
+= (*pp
)->length
;
2225 vilen
+= (*pp
)->length
;
2229 dword_align_bin (&pp
, &length
);
2230 vilen
+= length
- hold
;
2232 vsd
= (struct bindata
*) reswr_alloc (sizeof *vsd
);
2234 vsd
->data
= (unsigned char *) reswr_alloc (6);
2240 put_16 (big_endian
, 0, vsd
->data
+ 2);
2241 put_16 (big_endian
, 0, vsd
->data
+ 4);
2246 *pp
= unicode_to_bin (vi
->u
.string
.language
, big_endian
);
2247 length
+= (*pp
)->length
;
2248 vilen
+= (*pp
)->length
;
2249 vslen
+= (*pp
)->length
;
2252 for (vs
= vi
->u
.string
.strings
; vs
!= NULL
; vs
= vs
->next
)
2254 struct bindata
*vssd
;
2255 unsigned long vsslen
;
2258 dword_align_bin (&pp
, &length
);
2259 vilen
+= length
- hold
;
2260 vslen
+= length
- hold
;
2262 vssd
= (struct bindata
*) reswr_alloc (sizeof *vssd
);
2264 vssd
->data
= (unsigned char *) reswr_alloc (6);
2271 put_16 (big_endian
, 1, vssd
->data
+ 4);
2276 *pp
= unicode_to_bin (vs
->key
, big_endian
);
2277 length
+= (*pp
)->length
;
2278 vilen
+= (*pp
)->length
;
2279 vslen
+= (*pp
)->length
;
2280 vsslen
+= (*pp
)->length
;
2284 dword_align_bin (&pp
, &length
);
2285 vilen
+= length
- hold
;
2286 vslen
+= length
- hold
;
2287 vsslen
+= length
- hold
;
2289 *pp
= unicode_to_bin (vs
->value
, big_endian
);
2290 put_16 (big_endian
, (*pp
)->length
/ 2, vssd
->data
+ 2);
2291 length
+= (*pp
)->length
;
2292 vilen
+= (*pp
)->length
;
2293 vslen
+= (*pp
)->length
;
2294 vsslen
+= (*pp
)->length
;
2297 put_16 (big_endian
, vsslen
, vssd
->data
);
2300 put_16 (big_endian
, vslen
, vsd
->data
);
2307 unsigned long hold
, vvlen
, vvvlen
;
2308 struct bindata
*vvd
;
2309 const struct ver_varinfo
*vv
;
2311 *pp
= string_to_unicode_bin ("VarFileInfo", big_endian
);
2312 length
+= (*pp
)->length
;
2313 vilen
+= (*pp
)->length
;
2317 dword_align_bin (&pp
, &length
);
2318 vilen
+= length
- hold
;
2320 vvd
= (struct bindata
*) reswr_alloc (sizeof *vvd
);
2322 vvd
->data
= (unsigned char *) reswr_alloc (6);
2328 put_16 (big_endian
, 0, vvd
->data
+ 4);
2333 *pp
= unicode_to_bin (vi
->u
.var
.key
, big_endian
);
2334 length
+= (*pp
)->length
;
2335 vilen
+= (*pp
)->length
;
2336 vvlen
+= (*pp
)->length
;
2340 dword_align_bin (&pp
, &length
);
2341 vilen
+= length
- hold
;
2342 vvlen
+= length
- hold
;
2346 for (vv
= vi
->u
.var
.var
; vv
!= NULL
; vv
= vv
->next
)
2348 struct bindata
*vvsd
;
2350 vvsd
= (struct bindata
*) reswr_alloc (sizeof *vvsd
);
2352 vvsd
->data
= (unsigned char *) reswr_alloc (4);
2359 put_16 (big_endian
, vv
->language
, vvsd
->data
);
2360 put_16 (big_endian
, vv
->charset
, vvsd
->data
+ 2);
2367 put_16 (big_endian
, vvlen
, vvd
->data
);
2368 put_16 (big_endian
, vvvlen
, vvd
->data
+ 2);
2374 put_16 (big_endian
, vilen
, vid
->data
);
2377 put_16 (big_endian
, length
, first
->data
);
2382 /* Convert a generic resource to binary. */
2384 static struct bindata
*
2385 res_to_bin_generic (length
, data
)
2386 unsigned long length
;
2387 const unsigned char *data
;
2391 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2393 d
->data
= (unsigned char *) data
;