1 /* resbin.c -- manipulate the Windows binary resource format.
2 Copyright 1997, 1998, 1999, 2002, 2003
3 Free Software Foundation, Inc.
4 Written by Ian Lance Taylor, Cygnus Support.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
23 /* This file contains functions to convert between the binary resource
24 format and the internal structures that we want to use. The same
25 binary resource format is used in both res and COFF files. */
29 #include "libiberty.h"
32 /* Macros to swap in values. */
34 #define get_8(s) (*((unsigned char *)(s)))
35 #define get_16(be, s) ((be) ? bfd_getb16 (s) : bfd_getl16 (s))
36 #define get_32(be, s) ((be) ? bfd_getb32 (s) : bfd_getl32 (s))
38 /* Local functions. */
40 static void toosmall (const char *);
42 static unichar
*get_unicode
43 (const unsigned char *, unsigned long, int, int *);
45 (struct res_id
*, const unsigned char *, unsigned long, int);
46 static struct res_resource
*bin_to_res_generic
47 (enum res_type
, const unsigned char *, unsigned long);
48 static struct res_resource
*bin_to_res_cursor
49 (const unsigned char *, unsigned long, int);
50 static struct res_resource
*bin_to_res_menu
51 (const unsigned char *, unsigned long, int);
52 static struct menuitem
*bin_to_res_menuitems
53 (const unsigned char *, unsigned long, int, int *);
54 static struct menuitem
*bin_to_res_menuexitems
55 (const unsigned char *, unsigned long, int, int *);
56 static struct res_resource
*bin_to_res_dialog
57 (const unsigned char *, unsigned long, int);
58 static struct res_resource
*bin_to_res_string
59 (const unsigned char *, unsigned long, int);
60 static struct res_resource
*bin_to_res_fontdir
61 (const unsigned char *, unsigned long, int);
62 static struct res_resource
*bin_to_res_accelerators
63 (const unsigned char *, unsigned long, int);
64 static struct res_resource
*bin_to_res_rcdata
65 (const unsigned char *, unsigned long, int);
66 static struct res_resource
*bin_to_res_group_cursor
67 (const unsigned char *, unsigned long, int);
68 static struct res_resource
*bin_to_res_group_icon
69 (const unsigned char *, unsigned long, int);
70 static struct res_resource
*bin_to_res_version
71 (const unsigned char *, unsigned long, int);
72 static struct res_resource
*bin_to_res_userdata
73 (const unsigned char *, unsigned long, int);
74 static void get_version_header
75 (const unsigned char *, unsigned long, int, const char *,
76 unichar
**, int *, int *, int *, int *);
78 /* Given a resource type ID, a pointer to data, a length, return a
79 res_resource structure which represents that resource. The caller
80 is responsible for initializing the res_info and coff_info fields
81 of the returned structure. */
84 bin_to_res (struct res_id type
, const unsigned char *data
,
85 unsigned long length
, int big_endian
)
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. */
130 toosmall (const char *msg
)
132 fatal (_("%s: not enough binary data"), msg
);
135 /* Swap in a NULL terminated unicode string. */
138 get_unicode (const unsigned char *data
, unsigned long length
,
139 int big_endian
, int *retlen
)
147 if (length
< (unsigned long) c
* 2 + 2)
148 toosmall (_("null terminated unicode string"));
149 if (get_16 (big_endian
, data
+ c
* 2) == 0)
154 ret
= (unichar
*) res_alloc ((c
+ 1) * sizeof (unichar
));
156 for (i
= 0; i
< c
; i
++)
157 ret
[i
] = get_16 (big_endian
, data
+ i
* 2);
166 /* Get a resource identifier. This returns the number of bytes used. */
169 get_resid (struct res_id
*id
, const unsigned char *data
,
170 unsigned long length
, int big_endian
)
175 toosmall (_("resource ID"));
177 first
= get_16 (big_endian
, data
);
181 toosmall (_("resource ID"));
183 id
->u
.id
= get_16 (big_endian
, data
+ 2);
189 id
->u
.n
.name
= get_unicode (data
, length
, big_endian
, &id
->u
.n
.length
);
190 return id
->u
.n
.length
* 2 + 2;
194 /* Convert a resource which just stores uninterpreted data from
197 struct res_resource
*
198 bin_to_res_generic (enum res_type type
, const unsigned char *data
,
199 unsigned long length
)
201 struct res_resource
*r
;
203 r
= (struct res_resource
*) res_alloc (sizeof *r
);
205 r
->u
.data
.data
= data
;
206 r
->u
.data
.length
= length
;
211 /* Convert a cursor resource from binary. */
213 struct res_resource
*
214 bin_to_res_cursor (const unsigned char *data
, unsigned long length
,
218 struct res_resource
*r
;
221 toosmall (_("cursor"));
223 c
= (struct cursor
*) res_alloc (sizeof *c
);
224 c
->xhotspot
= get_16 (big_endian
, data
);
225 c
->yhotspot
= get_16 (big_endian
, data
+ 2);
226 c
->length
= length
- 4;
229 r
= (struct res_resource
*) res_alloc (sizeof *r
);
230 r
->type
= RES_TYPE_CURSOR
;
236 /* Convert a menu resource from binary. */
238 struct res_resource
*
239 bin_to_res_menu (const unsigned char *data
, unsigned long length
,
242 struct res_resource
*r
;
246 r
= (struct res_resource
*) res_alloc (sizeof *r
);
247 r
->type
= RES_TYPE_MENU
;
249 m
= (struct menu
*) res_alloc (sizeof *m
);
253 toosmall (_("menu header"));
255 version
= get_16 (big_endian
, data
);
260 toosmall (_("menu header"));
262 m
->items
= bin_to_res_menuitems (data
+ 4, length
- 4, big_endian
,
265 else if (version
== 1)
270 toosmall (_("menuex header"));
271 m
->help
= get_32 (big_endian
, data
+ 4);
272 offset
= get_16 (big_endian
, data
+ 2);
273 if (offset
+ 4 >= length
)
274 toosmall (_("menuex offset"));
275 m
->items
= bin_to_res_menuexitems (data
+ 4 + offset
,
276 length
- (4 + offset
),
281 fatal (_("unsupported menu version %d"), version
);
286 /* Convert menu items from binary. */
288 static struct menuitem
*
289 bin_to_res_menuitems (const unsigned char *data
, unsigned long length
,
290 int big_endian
, int *read
)
292 struct menuitem
*first
, **pp
;
301 int flags
, slen
, itemlen
;
306 toosmall (_("menuitem header"));
308 mi
= (struct menuitem
*) res_alloc (sizeof *mi
);
312 flags
= get_16 (big_endian
, data
);
313 mi
->type
= flags
&~ (MENUITEM_POPUP
| MENUITEM_ENDMENU
);
315 if ((flags
& MENUITEM_POPUP
) == 0)
320 if (length
< stroff
+ 2)
321 toosmall (_("menuitem header"));
323 if (get_16 (big_endian
, data
+ stroff
) == 0)
329 mi
->text
= get_unicode (data
+ stroff
, length
- stroff
, big_endian
,
332 itemlen
= stroff
+ slen
* 2 + 2;
334 if ((flags
& MENUITEM_POPUP
) == 0)
337 mi
->id
= get_16 (big_endian
, data
+ 2);
344 mi
->popup
= bin_to_res_menuitems (data
+ itemlen
, length
- itemlen
,
345 big_endian
, &subread
);
357 if ((flags
& MENUITEM_ENDMENU
) != 0)
364 /* Convert menuex items from binary. */
366 static struct menuitem
*
367 bin_to_res_menuexitems (const unsigned char *data
, unsigned long length
,
368 int big_endian
, int *read
)
370 struct menuitem
*first
, **pp
;
380 unsigned int itemlen
;
384 toosmall (_("menuitem header"));
386 mi
= (struct menuitem
*) res_alloc (sizeof *mi
);
387 mi
->type
= get_32 (big_endian
, data
);
388 mi
->state
= get_32 (big_endian
, data
+ 4);
389 mi
->id
= get_16 (big_endian
, data
+ 8);
391 flags
= get_16 (big_endian
, data
+ 10);
393 if (get_16 (big_endian
, data
+ 12) == 0)
399 mi
->text
= get_unicode (data
+ 12, length
- 12, big_endian
, &slen
);
401 itemlen
= 12 + slen
* 2 + 2;
402 itemlen
= (itemlen
+ 3) &~ 3;
404 if ((flags
& 1) == 0)
413 if (length
< itemlen
+ 4)
414 toosmall (_("menuitem"));
415 mi
->help
= get_32 (big_endian
, data
+ itemlen
);
418 mi
->popup
= bin_to_res_menuexitems (data
+ itemlen
,
420 big_endian
, &subread
);
432 if ((flags
& 0x80) != 0)
439 /* Convert a dialog resource from binary. */
441 static struct res_resource
*
442 bin_to_res_dialog (const unsigned char *data
, unsigned long length
,
449 struct dialog_control
**pp
;
450 struct res_resource
*r
;
453 toosmall (_("dialog header"));
455 d
= (struct dialog
*) res_alloc (sizeof *d
);
457 signature
= get_16 (big_endian
, data
+ 2);
458 if (signature
!= 0xffff)
461 d
->style
= get_32 (big_endian
, data
);
462 d
->exstyle
= get_32 (big_endian
, data
+ 4);
469 version
= get_16 (big_endian
, data
);
471 fatal (_("unexpected DIALOGEX version %d"), version
);
473 d
->ex
= (struct dialog_ex
*) res_alloc (sizeof (struct dialog_ex
));
474 d
->ex
->help
= get_32 (big_endian
, data
+ 4);
475 d
->exstyle
= get_32 (big_endian
, data
+ 8);
476 d
->style
= get_32 (big_endian
, data
+ 12);
480 if (length
< off
+ 10)
481 toosmall (_("dialog header"));
483 c
= get_16 (big_endian
, data
+ off
);
484 d
->x
= get_16 (big_endian
, data
+ off
+ 2);
485 d
->y
= get_16 (big_endian
, data
+ off
+ 4);
486 d
->width
= get_16 (big_endian
, data
+ off
+ 6);
487 d
->height
= get_16 (big_endian
, data
+ off
+ 8);
491 sublen
= get_resid (&d
->menu
, data
+ off
, length
- off
, big_endian
);
494 sublen
= get_resid (&d
->class, data
+ off
, length
- off
, big_endian
);
497 d
->caption
= get_unicode (data
+ off
, length
- off
, big_endian
, &sublen
);
498 off
+= sublen
* 2 + 2;
502 if ((d
->style
& DS_SETFONT
) == 0)
510 d
->ex
->charset
= 1; /* Default charset. */
515 if (length
< off
+ 2)
516 toosmall (_("dialog font point size"));
518 d
->pointsize
= get_16 (big_endian
, data
+ off
);
523 if (length
< off
+ 4)
524 toosmall (_("dialogex font information"));
525 d
->ex
->weight
= get_16 (big_endian
, data
+ off
);
526 d
->ex
->italic
= get_8 (data
+ off
+ 2);
527 d
->ex
->charset
= get_8 (data
+ off
+ 3);
531 d
->font
= get_unicode (data
+ off
, length
- off
, big_endian
, &sublen
);
532 off
+= sublen
* 2 + 2;
538 for (i
= 0; i
< c
; i
++)
540 struct dialog_control
*dc
;
543 off
= (off
+ 3) &~ 3;
545 dc
= (struct dialog_control
*) res_alloc (sizeof *dc
);
549 if (length
< off
+ 8)
550 toosmall (_("dialog control"));
552 dc
->style
= get_32 (big_endian
, data
+ off
);
553 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
559 if (length
< off
+ 12)
560 toosmall (_("dialogex control"));
561 dc
->help
= get_32 (big_endian
, data
+ off
);
562 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
563 dc
->style
= get_32 (big_endian
, data
+ off
+ 8);
567 if (length
< off
+ 10)
568 toosmall (_("dialog control"));
570 dc
->x
= get_16 (big_endian
, data
+ off
);
571 dc
->y
= get_16 (big_endian
, data
+ off
+ 2);
572 dc
->width
= get_16 (big_endian
, data
+ off
+ 4);
573 dc
->height
= get_16 (big_endian
, data
+ off
+ 6);
576 dc
->id
= get_32 (big_endian
, data
+ off
+ 8);
578 dc
->id
= get_16 (big_endian
, data
+ off
+ 8);
580 off
+= 10 + (d
->ex
!= NULL
? 2 : 0);
582 sublen
= get_resid (&dc
->class, data
+ off
, length
- off
, big_endian
);
585 sublen
= get_resid (&dc
->text
, data
+ off
, length
- off
, big_endian
);
588 if (length
< off
+ 2)
589 toosmall (_("dialog control end"));
591 datalen
= get_16 (big_endian
, data
+ off
);
598 off
= (off
+ 3) &~ 3;
600 if (length
< off
+ datalen
)
601 toosmall (_("dialog control data"));
603 dc
->data
= ((struct rcdata_item
*)
604 res_alloc (sizeof (struct rcdata_item
)));
605 dc
->data
->next
= NULL
;
606 dc
->data
->type
= RCDATA_BUFFER
;
607 dc
->data
->u
.buffer
.length
= datalen
;
608 dc
->data
->u
.buffer
.data
= data
+ off
;
618 r
= (struct res_resource
*) res_alloc (sizeof *r
);
619 r
->type
= RES_TYPE_DIALOG
;
625 /* Convert a stringtable resource from binary. */
627 static struct res_resource
*
628 bin_to_res_string (const unsigned char *data
, unsigned long length
,
631 struct stringtable
*st
;
633 struct res_resource
*r
;
635 st
= (struct stringtable
*) res_alloc (sizeof *st
);
637 for (i
= 0; i
< 16; i
++)
642 toosmall (_("stringtable string length"));
643 slen
= get_16 (big_endian
, data
);
644 st
->strings
[i
].length
= slen
;
651 if (length
< 2 + 2 * slen
)
652 toosmall (_("stringtable string"));
654 s
= (unichar
*) res_alloc (slen
* sizeof (unichar
));
655 st
->strings
[i
].string
= s
;
657 for (j
= 0; j
< slen
; j
++)
658 s
[j
] = get_16 (big_endian
, data
+ 2 + j
* 2);
661 data
+= 2 + 2 * slen
;
662 length
-= 2 + 2 * slen
;
665 r
= (struct res_resource
*) res_alloc (sizeof *r
);
666 r
->type
= RES_TYPE_STRINGTABLE
;
667 r
->u
.stringtable
= st
;
672 /* Convert a fontdir resource from binary. */
674 static struct res_resource
*
675 bin_to_res_fontdir (const unsigned char *data
, unsigned long length
,
679 struct fontdir
*first
, **pp
;
680 struct res_resource
*r
;
683 toosmall (_("fontdir header"));
685 c
= get_16 (big_endian
, data
);
690 for (i
= 0; i
< c
; i
++)
696 toosmall (_("fontdir"));
698 fd
= (struct fontdir
*) res_alloc (sizeof *fd
);
699 fd
->index
= get_16 (big_endian
, data
);
701 /* To work out the length of the fontdir data, we must get the
702 length of the device name and face name strings, even though
703 we don't store them in the fontdir structure. The
704 documentation says that these are NULL terminated char
705 strings, not Unicode strings. */
709 while (off
< length
&& data
[off
] != '\0')
712 toosmall (_("fontdir device name"));
715 while (off
< length
&& data
[off
] != '\0')
718 toosmall (_("fontdir face name"));
728 /* The documentation does not indicate that any rounding is
735 r
= (struct res_resource
*) res_alloc (sizeof *r
);
736 r
->type
= RES_TYPE_FONTDIR
;
737 r
->u
.fontdir
= first
;
742 /* Convert an accelerators resource from binary. */
744 static struct res_resource
*
745 bin_to_res_accelerators (const unsigned char *data
, unsigned long length
,
748 struct accelerator
*first
, **pp
;
749 struct res_resource
*r
;
756 struct accelerator
*a
;
759 toosmall (_("accelerator"));
761 a
= (struct accelerator
*) res_alloc (sizeof *a
);
763 a
->flags
= get_16 (big_endian
, data
);
764 a
->key
= get_16 (big_endian
, data
+ 2);
765 a
->id
= get_16 (big_endian
, data
+ 4);
771 if ((a
->flags
& ACC_LAST
) != 0)
778 r
= (struct res_resource
*) res_alloc (sizeof *r
);
779 r
->type
= RES_TYPE_ACCELERATOR
;
785 /* Convert an rcdata resource from binary. */
787 static struct res_resource
*
788 bin_to_res_rcdata (const unsigned char *data
, unsigned long length
,
789 int big_endian ATTRIBUTE_UNUSED
)
791 struct rcdata_item
*ri
;
792 struct res_resource
*r
;
794 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
797 ri
->type
= RCDATA_BUFFER
;
798 ri
->u
.buffer
.length
= length
;
799 ri
->u
.buffer
.data
= data
;
801 r
= (struct res_resource
*) res_alloc (sizeof *r
);
802 r
->type
= RES_TYPE_RCDATA
;
808 /* Convert a group cursor resource from binary. */
810 static struct res_resource
*
811 bin_to_res_group_cursor (const unsigned char *data
, unsigned long length
,
815 struct group_cursor
*first
, **pp
;
816 struct res_resource
*r
;
819 toosmall (_("group cursor header"));
821 type
= get_16 (big_endian
, data
+ 2);
823 fatal (_("unexpected group cursor type %d"), type
);
825 c
= get_16 (big_endian
, data
+ 4);
833 for (i
= 0; i
< c
; i
++)
835 struct group_cursor
*gc
;
838 toosmall (_("group cursor"));
840 gc
= (struct group_cursor
*) res_alloc (sizeof *gc
);
842 gc
->width
= get_16 (big_endian
, data
);
843 gc
->height
= get_16 (big_endian
, data
+ 2);
844 gc
->planes
= get_16 (big_endian
, data
+ 4);
845 gc
->bits
= get_16 (big_endian
, data
+ 6);
846 gc
->bytes
= get_32 (big_endian
, data
+ 8);
847 gc
->index
= get_16 (big_endian
, data
+ 12);
857 r
= (struct res_resource
*) res_alloc (sizeof *r
);
858 r
->type
= RES_TYPE_GROUP_CURSOR
;
859 r
->u
.group_cursor
= first
;
864 /* Convert a group icon resource from binary. */
866 static struct res_resource
*
867 bin_to_res_group_icon (const unsigned char *data
, unsigned long length
,
871 struct group_icon
*first
, **pp
;
872 struct res_resource
*r
;
875 toosmall (_("group icon header"));
877 type
= get_16 (big_endian
, data
+ 2);
879 fatal (_("unexpected group icon type %d"), type
);
881 c
= get_16 (big_endian
, data
+ 4);
889 for (i
= 0; i
< c
; i
++)
891 struct group_icon
*gi
;
894 toosmall (_("group icon"));
896 gi
= (struct group_icon
*) res_alloc (sizeof *gi
);
899 gi
->height
= data
[1];
900 gi
->colors
= data
[2];
901 gi
->planes
= get_16 (big_endian
, data
+ 4);
902 gi
->bits
= get_16 (big_endian
, data
+ 6);
903 gi
->bytes
= get_32 (big_endian
, data
+ 8);
904 gi
->index
= get_16 (big_endian
, data
+ 12);
914 r
= (struct res_resource
*) res_alloc (sizeof *r
);
915 r
->type
= RES_TYPE_GROUP_ICON
;
916 r
->u
.group_icon
= first
;
921 /* Extract data from a version header. If KEY is not NULL, then the
922 key must be KEY; otherwise, the key is returned in *PKEY. This
923 sets *LEN to the total length, *VALLEN to the value length, *TYPE
924 to the type, and *OFF to the offset to the children. */
927 get_version_header (const unsigned char *data
, unsigned long length
,
928 int big_endian
, const char *key
, unichar
**pkey
,
929 int *len
, int *vallen
, int *type
, int *off
)
934 *len
= get_16 (big_endian
, data
);
935 *vallen
= get_16 (big_endian
, data
+ 2);
936 *type
= get_16 (big_endian
, data
+ 4);
947 *pkey
= get_unicode (data
, length
, big_endian
, &sublen
);
948 *off
+= sublen
* 2 + 2;
956 if (get_16 (big_endian
, data
) != (unsigned char) *key
)
957 fatal (_("unexpected version string"));
970 *off
= (*off
+ 3) &~ 3;
973 /* Convert a version resource from binary. */
975 static struct res_resource
*
976 bin_to_res_version (const unsigned char *data
, unsigned long length
,
979 int verlen
, vallen
, type
, off
;
980 struct fixed_versioninfo
*fi
;
981 struct ver_info
*first
, **pp
;
982 struct versioninfo
*v
;
983 struct res_resource
*r
;
985 get_version_header (data
, length
, big_endian
, "VS_VERSION_INFO",
986 (unichar
**) NULL
, &verlen
, &vallen
, &type
, &off
);
988 if ((unsigned int) verlen
!= length
)
989 fatal (_("version length %d does not match resource length %lu"),
993 fatal (_("unexpected version type %d"), type
);
1002 unsigned long signature
, fiv
;
1005 fatal (_("unexpected fixed version information length %d"), vallen
);
1008 toosmall (_("fixed version info"));
1010 signature
= get_32 (big_endian
, data
);
1011 if (signature
!= 0xfeef04bd)
1012 fatal (_("unexpected fixed version signature %lu"), signature
);
1014 fiv
= get_32 (big_endian
, data
+ 4);
1015 if (fiv
!= 0 && fiv
!= 0x10000)
1016 fatal (_("unexpected fixed version info version %lu"), fiv
);
1018 fi
= (struct fixed_versioninfo
*) res_alloc (sizeof *fi
);
1020 fi
->file_version_ms
= get_32 (big_endian
, data
+ 8);
1021 fi
->file_version_ls
= get_32 (big_endian
, data
+ 12);
1022 fi
->product_version_ms
= get_32 (big_endian
, data
+ 16);
1023 fi
->product_version_ls
= get_32 (big_endian
, data
+ 20);
1024 fi
->file_flags_mask
= get_32 (big_endian
, data
+ 24);
1025 fi
->file_flags
= get_32 (big_endian
, data
+ 28);
1026 fi
->file_os
= get_32 (big_endian
, data
+ 32);
1027 fi
->file_type
= get_32 (big_endian
, data
+ 36);
1028 fi
->file_subtype
= get_32 (big_endian
, data
+ 40);
1029 fi
->file_date_ms
= get_32 (big_endian
, data
+ 44);
1030 fi
->file_date_ls
= get_32 (big_endian
, data
+ 48);
1041 struct ver_info
*vi
;
1045 toosmall (_("version var info"));
1047 vi
= (struct ver_info
*) res_alloc (sizeof *vi
);
1049 ch
= get_16 (big_endian
, data
+ 6);
1053 struct ver_stringinfo
**ppvs
;
1055 vi
->type
= VERINFO_STRING
;
1057 get_version_header (data
, length
, big_endian
, "StringFileInfo",
1058 (unichar
**) NULL
, &verlen
, &vallen
, &type
,
1062 fatal (_("unexpected stringfileinfo value length %d"), vallen
);
1067 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1068 &vi
->u
.string
.language
, &verlen
, &vallen
,
1072 fatal (_("unexpected version stringtable value length %d"), vallen
);
1078 vi
->u
.string
.strings
= NULL
;
1079 ppvs
= &vi
->u
.string
.strings
;
1081 /* It's convenient to round verlen to a 4 byte alignment,
1082 since we round the subvariables in the loop. */
1083 verlen
= (verlen
+ 3) &~ 3;
1087 struct ver_stringinfo
*vs
;
1088 int subverlen
, vslen
, valoff
;
1090 vs
= (struct ver_stringinfo
*) res_alloc (sizeof *vs
);
1092 get_version_header (data
, length
, big_endian
,
1093 (const char *) NULL
, &vs
->key
, &subverlen
,
1094 &vallen
, &type
, &off
);
1096 subverlen
= (subverlen
+ 3) &~ 3;
1101 vs
->value
= get_unicode (data
, length
, big_endian
, &vslen
);
1102 valoff
= vslen
* 2 + 2;
1103 valoff
= (valoff
+ 3) &~ 3;
1105 if (off
+ valoff
!= subverlen
)
1106 fatal (_("unexpected version string length %d != %d + %d"),
1107 subverlen
, off
, valoff
);
1116 if (verlen
< subverlen
)
1117 fatal (_("unexpected version string length %d < %d"),
1120 verlen
-= subverlen
;
1125 struct ver_varinfo
**ppvv
;
1127 vi
->type
= VERINFO_VAR
;
1129 get_version_header (data
, length
, big_endian
, "VarFileInfo",
1130 (unichar
**) NULL
, &verlen
, &vallen
, &type
,
1134 fatal (_("unexpected varfileinfo value length %d"), vallen
);
1139 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1140 &vi
->u
.var
.key
, &verlen
, &vallen
, &type
, &off
);
1145 vi
->u
.var
.var
= NULL
;
1146 ppvv
= &vi
->u
.var
.var
;
1150 struct ver_varinfo
*vv
;
1153 toosmall (_("version varfileinfo"));
1155 vv
= (struct ver_varinfo
*) res_alloc (sizeof *vv
);
1157 vv
->language
= get_16 (big_endian
, data
);
1158 vv
->charset
= get_16 (big_endian
, data
+ 2);
1168 fatal (_("unexpected version value length %d"), vallen
);
1174 fatal (_("unexpected version string"));
1181 v
= (struct versioninfo
*) res_alloc (sizeof *v
);
1185 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1186 r
->type
= RES_TYPE_VERSIONINFO
;
1187 r
->u
.versioninfo
= v
;
1192 /* Convert an arbitrary user defined resource from binary. */
1194 static struct res_resource
*
1195 bin_to_res_userdata (const unsigned char *data
, unsigned long length
,
1196 int big_endian ATTRIBUTE_UNUSED
)
1198 struct rcdata_item
*ri
;
1199 struct res_resource
*r
;
1201 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
1204 ri
->type
= RCDATA_BUFFER
;
1205 ri
->u
.buffer
.length
= length
;
1206 ri
->u
.buffer
.data
= data
;
1208 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1209 r
->type
= RES_TYPE_USERDATA
;
1215 /* Macros to swap out values. */
1217 #define put_8(v, s) (*((unsigned char *) (s)) = (unsigned char) (v))
1218 #define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
1219 #define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
1221 /* Local functions used to convert resources to binary format. */
1223 static void dword_align_bin (struct bindata
***, unsigned long *);
1224 static struct bindata
*resid_to_bin (struct res_id
, int);
1225 static struct bindata
*unicode_to_bin (const unichar
*, int);
1226 static struct bindata
*res_to_bin_accelerator
1227 (const struct accelerator
*, int);
1228 static struct bindata
*res_to_bin_cursor
1229 (const struct cursor
*, int);
1230 static struct bindata
*res_to_bin_group_cursor
1231 (const struct group_cursor
*, int);
1232 static struct bindata
*res_to_bin_dialog
1233 (const struct dialog
*, int);
1234 static struct bindata
*res_to_bin_fontdir
1235 (const struct fontdir
*, int);
1236 static struct bindata
*res_to_bin_group_icon
1237 (const struct group_icon
*, int);
1238 static struct bindata
*res_to_bin_menu
1239 (const struct menu
*, int);
1240 static struct bindata
*res_to_bin_menuitems
1241 (const struct menuitem
*, int);
1242 static struct bindata
*res_to_bin_menuexitems
1243 (const struct menuitem
*, int);
1244 static struct bindata
*res_to_bin_rcdata
1245 (const struct rcdata_item
*, int);
1246 static struct bindata
*res_to_bin_stringtable
1247 (const struct stringtable
*, int);
1248 static struct bindata
*string_to_unicode_bin (const char *, int);
1249 static struct bindata
*res_to_bin_versioninfo
1250 (const struct versioninfo
*, int);
1251 static struct bindata
*res_to_bin_generic
1252 (unsigned long, const unsigned char *);
1254 /* Convert a resource to binary. */
1257 res_to_bin (const struct res_resource
*res
, int big_endian
)
1263 case RES_TYPE_BITMAP
:
1266 case RES_TYPE_MESSAGETABLE
:
1267 return res_to_bin_generic (res
->u
.data
.length
, res
->u
.data
.data
);
1268 case RES_TYPE_ACCELERATOR
:
1269 return res_to_bin_accelerator (res
->u
.acc
, big_endian
);
1270 case RES_TYPE_CURSOR
:
1271 return res_to_bin_cursor (res
->u
.cursor
, big_endian
);
1272 case RES_TYPE_GROUP_CURSOR
:
1273 return res_to_bin_group_cursor (res
->u
.group_cursor
, big_endian
);
1274 case RES_TYPE_DIALOG
:
1275 return res_to_bin_dialog (res
->u
.dialog
, big_endian
);
1276 case RES_TYPE_FONTDIR
:
1277 return res_to_bin_fontdir (res
->u
.fontdir
, big_endian
);
1278 case RES_TYPE_GROUP_ICON
:
1279 return res_to_bin_group_icon (res
->u
.group_icon
, big_endian
);
1281 return res_to_bin_menu (res
->u
.menu
, big_endian
);
1282 case RES_TYPE_RCDATA
:
1283 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1284 case RES_TYPE_STRINGTABLE
:
1285 return res_to_bin_stringtable (res
->u
.stringtable
, big_endian
);
1286 case RES_TYPE_USERDATA
:
1287 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1288 case RES_TYPE_VERSIONINFO
:
1289 return res_to_bin_versioninfo (res
->u
.versioninfo
, big_endian
);
1293 /* Align to a 32 bit boundary. PPP points to the of a list of bindata
1294 structures. LENGTH points to the length of the structures. If
1295 necessary, this adds a new bindata to bring length up to a 32 bit
1296 boundary. It updates *PPP and *LENGTH. */
1299 dword_align_bin (struct bindata
***ppp
, unsigned long *length
)
1304 if ((*length
& 3) == 0)
1307 add
= 4 - (*length
& 3);
1309 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1311 d
->data
= (unsigned char *) reswr_alloc (add
);
1312 memset (d
->data
, 0, add
);
1316 *ppp
= &(**ppp
)->next
;
1321 /* Convert a resource ID to binary. This always returns exactly one
1322 bindata structure. */
1324 static struct bindata
*
1325 resid_to_bin (struct res_id id
, int big_endian
)
1329 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1334 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1335 put_16 (big_endian
, 0xffff, d
->data
);
1336 put_16 (big_endian
, id
.u
.id
, d
->data
+ 2);
1342 d
->length
= id
.u
.n
.length
* 2 + 2;
1343 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1344 for (i
= 0; i
< id
.u
.n
.length
; i
++)
1345 put_16 (big_endian
, id
.u
.n
.name
[i
], d
->data
+ i
* 2);
1346 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1354 /* Convert a null terminated unicode string to binary. This always
1355 returns exactly one bindata structure. */
1357 static struct bindata
*
1358 unicode_to_bin (const unichar
*str
, int big_endian
)
1368 for (s
= str
; *s
!= 0; s
++)
1372 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1373 d
->length
= len
* 2 + 2;
1374 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1377 put_16 (big_endian
, 0, d
->data
);
1383 for (s
= str
, i
= 0; *s
!= 0; s
++, i
++)
1384 put_16 (big_endian
, *s
, d
->data
+ i
* 2);
1385 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1393 /* Convert an accelerator resource to binary. */
1395 static struct bindata
*
1396 res_to_bin_accelerator (const struct accelerator
*accelerators
,
1399 struct bindata
*first
, **pp
;
1400 const struct accelerator
*a
;
1405 for (a
= accelerators
; a
!= NULL
; a
= a
->next
)
1409 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1411 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1414 a
->flags
| (a
->next
!= NULL
? 0 : ACC_LAST
),
1416 put_16 (big_endian
, a
->key
, d
->data
+ 2);
1417 put_16 (big_endian
, a
->id
, d
->data
+ 4);
1418 put_16 (big_endian
, 0, d
->data
+ 6);
1428 /* Convert a cursor resource to binary. */
1430 static struct bindata
*
1431 res_to_bin_cursor (const struct cursor
*c
, int big_endian
)
1435 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1437 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1439 put_16 (big_endian
, c
->xhotspot
, d
->data
);
1440 put_16 (big_endian
, c
->yhotspot
, d
->data
+ 2);
1442 d
->next
= (struct bindata
*) reswr_alloc (sizeof *d
);
1443 d
->next
->length
= c
->length
;
1444 d
->next
->data
= (unsigned char *) c
->data
;
1445 d
->next
->next
= NULL
;
1450 /* Convert a group cursor resource to binary. */
1452 static struct bindata
*
1453 res_to_bin_group_cursor (const struct group_cursor
*group_cursors
,
1456 struct bindata
*first
, **pp
;
1458 const struct group_cursor
*gc
;
1460 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1462 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1464 put_16 (big_endian
, 0, first
->data
);
1465 put_16 (big_endian
, 2, first
->data
+ 2);
1471 for (gc
= group_cursors
; gc
!= NULL
; gc
= gc
->next
)
1477 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1479 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1481 put_16 (big_endian
, gc
->width
, d
->data
);
1482 put_16 (big_endian
, gc
->height
, d
->data
+ 2);
1483 put_16 (big_endian
, gc
->planes
, d
->data
+ 4);
1484 put_16 (big_endian
, gc
->bits
, d
->data
+ 6);
1485 put_32 (big_endian
, gc
->bytes
, d
->data
+ 8);
1486 put_16 (big_endian
, gc
->index
, d
->data
+ 12);
1493 put_16 (big_endian
, c
, first
->data
+ 4);
1498 /* Convert a dialog resource to binary. */
1500 static struct bindata
*
1501 res_to_bin_dialog (const struct dialog
*dialog
, int big_endian
)
1504 struct bindata
*first
, **pp
;
1505 unsigned long length
;
1507 struct dialog_control
*dc
;
1509 dialogex
= extended_dialog (dialog
);
1511 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1512 first
->length
= dialogex
? 26 : 18;
1513 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1515 length
= first
->length
;
1519 put_32 (big_endian
, dialog
->style
, first
->data
);
1520 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 4);
1525 put_16 (big_endian
, 1, first
->data
);
1526 put_16 (big_endian
, 0xffff, first
->data
+ 2);
1528 if (dialog
->ex
== NULL
)
1529 put_32 (big_endian
, 0, first
->data
+ 4);
1531 put_32 (big_endian
, dialog
->ex
->help
, first
->data
+ 4);
1532 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 8);
1533 put_32 (big_endian
, dialog
->style
, first
->data
+ 12);
1537 put_16 (big_endian
, dialog
->x
, first
->data
+ off
+ 2);
1538 put_16 (big_endian
, dialog
->y
, first
->data
+ off
+ 4);
1539 put_16 (big_endian
, dialog
->width
, first
->data
+ off
+ 6);
1540 put_16 (big_endian
, dialog
->height
, first
->data
+ off
+ 8);
1544 *pp
= resid_to_bin (dialog
->menu
, big_endian
);
1545 length
+= (*pp
)->length
;
1548 *pp
= resid_to_bin (dialog
->class, big_endian
);
1549 length
+= (*pp
)->length
;
1552 *pp
= unicode_to_bin (dialog
->caption
, big_endian
);
1553 length
+= (*pp
)->length
;
1556 if ((dialog
->style
& DS_SETFONT
) != 0)
1560 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1561 d
->length
= dialogex
? 6 : 2;
1562 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1564 length
+= d
->length
;
1566 put_16 (big_endian
, dialog
->pointsize
, d
->data
);
1570 if (dialog
->ex
== NULL
)
1572 put_16 (big_endian
, 0, d
->data
+ 2);
1573 put_8 (0, d
->data
+ 4);
1574 put_8 (1, d
->data
+ 5);
1578 put_16 (big_endian
, dialog
->ex
->weight
, d
->data
+ 2);
1579 put_8 (dialog
->ex
->italic
, d
->data
+ 4);
1580 put_8 (dialog
->ex
->charset
, d
->data
+ 5);
1587 *pp
= unicode_to_bin (dialog
->font
, big_endian
);
1588 length
+= (*pp
)->length
;
1593 for (dc
= dialog
->controls
; dc
!= NULL
; dc
= dc
->next
)
1600 dword_align_bin (&pp
, &length
);
1602 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1603 d
->length
= dialogex
? 24 : 18;
1604 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1606 length
+= d
->length
;
1610 put_32 (big_endian
, dc
->style
, d
->data
);
1611 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1616 put_32 (big_endian
, dc
->help
, d
->data
);
1617 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1618 put_32 (big_endian
, dc
->style
, d
->data
+ 8);
1622 put_16 (big_endian
, dc
->x
, d
->data
+ dcoff
);
1623 put_16 (big_endian
, dc
->y
, d
->data
+ dcoff
+ 2);
1624 put_16 (big_endian
, dc
->width
, d
->data
+ dcoff
+ 4);
1625 put_16 (big_endian
, dc
->height
, d
->data
+ dcoff
+ 6);
1628 put_32 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1630 put_16 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1635 *pp
= resid_to_bin (dc
->class, big_endian
);
1636 length
+= (*pp
)->length
;
1639 *pp
= resid_to_bin (dc
->text
, big_endian
);
1640 length
+= (*pp
)->length
;
1643 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1645 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1653 if (dc
->data
== NULL
)
1654 put_16 (big_endian
, 0, d
->data
);
1657 unsigned long sublen
;
1659 dword_align_bin (&pp
, &length
);
1661 *pp
= res_to_bin_rcdata (dc
->data
, big_endian
);
1665 sublen
+= (*pp
)->length
;
1669 put_16 (big_endian
, sublen
, d
->data
);
1674 put_16 (big_endian
, c
, first
->data
+ off
);
1679 /* Convert a fontdir resource to binary. */
1681 static struct bindata
*
1682 res_to_bin_fontdir (const struct fontdir
*fontdirs
, int big_endian
)
1684 struct bindata
*first
, **pp
;
1686 const struct fontdir
*fd
;
1688 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1690 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1696 for (fd
= fontdirs
; fd
!= NULL
; fd
= fd
->next
)
1702 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1704 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1706 put_16 (big_endian
, fd
->index
, d
->data
);
1711 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1712 d
->length
= fd
->length
;
1713 d
->data
= (unsigned char *) fd
->data
;
1720 put_16 (big_endian
, c
, first
->data
);
1725 /* Convert a group icon resource to binary. */
1727 static struct bindata
*
1728 res_to_bin_group_icon (const struct group_icon
*group_icons
, int big_endian
)
1730 struct bindata
*first
, **pp
;
1732 const struct group_icon
*gi
;
1734 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1736 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1738 put_16 (big_endian
, 0, first
->data
);
1739 put_16 (big_endian
, 1, first
->data
+ 2);
1745 for (gi
= group_icons
; gi
!= NULL
; gi
= gi
->next
)
1751 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1753 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1755 d
->data
[0] = gi
->width
;
1756 d
->data
[1] = gi
->height
;
1757 d
->data
[2] = gi
->colors
;
1759 put_16 (big_endian
, gi
->planes
, d
->data
+ 4);
1760 put_16 (big_endian
, gi
->bits
, d
->data
+ 6);
1761 put_32 (big_endian
, gi
->bytes
, d
->data
+ 8);
1762 put_16 (big_endian
, gi
->index
, d
->data
+ 12);
1769 put_16 (big_endian
, c
, first
->data
+ 4);
1774 /* Convert a menu resource to binary. */
1776 static struct bindata
*
1777 res_to_bin_menu (const struct menu
*menu
, int big_endian
)
1782 menuex
= extended_menu (menu
);
1784 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1785 d
->length
= menuex
? 8 : 4;
1786 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1790 put_16 (big_endian
, 0, d
->data
);
1791 put_16 (big_endian
, 0, d
->data
+ 2);
1793 d
->next
= res_to_bin_menuitems (menu
->items
, big_endian
);
1797 put_16 (big_endian
, 1, d
->data
);
1798 put_16 (big_endian
, 4, d
->data
+ 2);
1799 put_32 (big_endian
, menu
->help
, d
->data
+ 4);
1801 d
->next
= res_to_bin_menuexitems (menu
->items
, big_endian
);
1807 /* Convert menu items to binary. */
1809 static struct bindata
*
1810 res_to_bin_menuitems (const struct menuitem
*items
, int big_endian
)
1812 struct bindata
*first
, **pp
;
1813 const struct menuitem
*mi
;
1818 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1823 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1824 d
->length
= mi
->popup
== NULL
? 4 : 2;
1825 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1828 if (mi
->next
== NULL
)
1829 flags
|= MENUITEM_ENDMENU
;
1830 if (mi
->popup
!= NULL
)
1831 flags
|= MENUITEM_POPUP
;
1833 put_16 (big_endian
, flags
, d
->data
);
1835 if (mi
->popup
== NULL
)
1836 put_16 (big_endian
, mi
->id
, d
->data
+ 2);
1841 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1844 if (mi
->popup
!= NULL
)
1846 *pp
= res_to_bin_menuitems (mi
->popup
, big_endian
);
1855 /* Convert menuex items to binary. */
1857 static struct bindata
*
1858 res_to_bin_menuexitems (const struct menuitem
*items
, int big_endian
)
1860 struct bindata
*first
, **pp
;
1861 unsigned long length
;
1862 const struct menuitem
*mi
;
1869 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1874 dword_align_bin (&pp
, &length
);
1876 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1878 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1882 put_32 (big_endian
, mi
->type
, d
->data
);
1883 put_32 (big_endian
, mi
->state
, d
->data
+ 4);
1884 put_16 (big_endian
, mi
->id
, d
->data
+ 8);
1887 if (mi
->next
== NULL
)
1889 if (mi
->popup
!= NULL
)
1891 put_16 (big_endian
, flags
, d
->data
+ 10);
1896 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1897 length
+= (*pp
)->length
;
1900 if (mi
->popup
!= NULL
)
1902 dword_align_bin (&pp
, &length
);
1904 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1906 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1908 put_32 (big_endian
, mi
->help
, d
->data
);
1913 *pp
= res_to_bin_menuexitems (mi
->popup
, big_endian
);
1916 length
+= (*pp
)->length
;
1925 /* Convert an rcdata resource to binary. This is also used to convert
1926 other information which happens to be stored in rcdata_item lists
1929 static struct bindata
*
1930 res_to_bin_rcdata (const struct rcdata_item
*items
, int big_endian
)
1932 struct bindata
*first
, **pp
;
1933 const struct rcdata_item
*ri
;
1938 for (ri
= items
; ri
!= NULL
; ri
= ri
->next
)
1942 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1951 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1952 put_16 (big_endian
, ri
->u
.word
, d
->data
);
1957 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1958 put_32 (big_endian
, ri
->u
.dword
, d
->data
);
1962 d
->length
= ri
->u
.string
.length
;
1963 d
->data
= (unsigned char *) ri
->u
.string
.s
;
1966 case RCDATA_WSTRING
:
1970 d
->length
= ri
->u
.wstring
.length
* 2;
1971 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1972 for (i
= 0; i
< ri
->u
.wstring
.length
; i
++)
1973 put_16 (big_endian
, ri
->u
.wstring
.w
[i
], d
->data
+ i
* 2);
1978 d
->length
= ri
->u
.buffer
.length
;
1979 d
->data
= (unsigned char *) ri
->u
.buffer
.data
;
1991 /* Convert a stringtable resource to binary. */
1993 static struct bindata
*
1994 res_to_bin_stringtable (const struct stringtable
*st
, int big_endian
)
1996 struct bindata
*first
, **pp
;
2002 for (i
= 0; i
< 16; i
++)
2008 slen
= st
->strings
[i
].length
;
2009 s
= st
->strings
[i
].string
;
2011 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2012 d
->length
= 2 + slen
* 2;
2013 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2015 put_16 (big_endian
, slen
, d
->data
);
2017 for (j
= 0; j
< slen
; j
++)
2018 put_16 (big_endian
, s
[j
], d
->data
+ 2 + j
* 2);
2028 /* Convert an ASCII string to a unicode binary string. This always
2029 returns exactly one bindata structure. */
2031 static struct bindata
*
2032 string_to_unicode_bin (const char *s
, int big_endian
)
2039 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2040 d
->length
= len
* 2 + 2;
2041 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2043 for (i
= 0; i
< len
; i
++)
2044 put_16 (big_endian
, s
[i
], d
->data
+ i
* 2);
2045 put_16 (big_endian
, 0, d
->data
+ i
* 2);
2052 /* Convert a versioninfo resource to binary. */
2054 static struct bindata
*
2055 res_to_bin_versioninfo (const struct versioninfo
*versioninfo
, int big_endian
)
2057 struct bindata
*first
, **pp
;
2058 unsigned long length
;
2059 struct ver_info
*vi
;
2061 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
2063 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
2067 if (versioninfo
->fixed
== NULL
)
2068 put_16 (big_endian
, 0, first
->data
+ 2);
2070 put_16 (big_endian
, 52, first
->data
+ 2);
2072 put_16 (big_endian
, 0, first
->data
+ 4);
2076 *pp
= string_to_unicode_bin ("VS_VERSION_INFO", big_endian
);
2077 length
+= (*pp
)->length
;
2080 dword_align_bin (&pp
, &length
);
2082 if (versioninfo
->fixed
!= NULL
)
2084 const struct fixed_versioninfo
*fi
;
2087 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2089 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2093 fi
= versioninfo
->fixed
;
2095 put_32 (big_endian
, 0xfeef04bd, d
->data
);
2096 put_32 (big_endian
, 0x10000, d
->data
+ 4);
2097 put_32 (big_endian
, fi
->file_version_ms
, d
->data
+ 8);
2098 put_32 (big_endian
, fi
->file_version_ls
, d
->data
+ 12);
2099 put_32 (big_endian
, fi
->product_version_ms
, d
->data
+ 16);
2100 put_32 (big_endian
, fi
->product_version_ls
, d
->data
+ 20);
2101 put_32 (big_endian
, fi
->file_flags_mask
, d
->data
+ 24);
2102 put_32 (big_endian
, fi
->file_flags
, d
->data
+ 28);
2103 put_32 (big_endian
, fi
->file_os
, d
->data
+ 32);
2104 put_32 (big_endian
, fi
->file_type
, d
->data
+ 36);
2105 put_32 (big_endian
, fi
->file_subtype
, d
->data
+ 40);
2106 put_32 (big_endian
, fi
->file_date_ms
, d
->data
+ 44);
2107 put_32 (big_endian
, fi
->file_date_ls
, d
->data
+ 48);
2114 for (vi
= versioninfo
->var
; vi
!= NULL
; vi
= vi
->next
)
2116 struct bindata
*vid
;
2117 unsigned long vilen
;
2119 dword_align_bin (&pp
, &length
);
2121 vid
= (struct bindata
*) reswr_alloc (sizeof *vid
);
2123 vid
->data
= (unsigned char *) reswr_alloc (vid
->length
);
2128 put_16 (big_endian
, 0, vid
->data
+ 2);
2129 put_16 (big_endian
, 0, vid
->data
+ 4);
2139 case VERINFO_STRING
:
2141 unsigned long hold
, vslen
;
2142 struct bindata
*vsd
;
2143 const struct ver_stringinfo
*vs
;
2145 *pp
= string_to_unicode_bin ("StringFileInfo", big_endian
);
2146 length
+= (*pp
)->length
;
2147 vilen
+= (*pp
)->length
;
2151 dword_align_bin (&pp
, &length
);
2152 vilen
+= length
- hold
;
2154 vsd
= (struct bindata
*) reswr_alloc (sizeof *vsd
);
2156 vsd
->data
= (unsigned char *) reswr_alloc (vsd
->length
);
2162 put_16 (big_endian
, 0, vsd
->data
+ 2);
2163 put_16 (big_endian
, 0, vsd
->data
+ 4);
2168 *pp
= unicode_to_bin (vi
->u
.string
.language
, big_endian
);
2169 length
+= (*pp
)->length
;
2170 vilen
+= (*pp
)->length
;
2171 vslen
+= (*pp
)->length
;
2174 for (vs
= vi
->u
.string
.strings
; vs
!= NULL
; vs
= vs
->next
)
2176 struct bindata
*vssd
;
2177 unsigned long vsslen
;
2180 dword_align_bin (&pp
, &length
);
2181 vilen
+= length
- hold
;
2182 vslen
+= length
- hold
;
2184 vssd
= (struct bindata
*) reswr_alloc (sizeof *vssd
);
2186 vssd
->data
= (unsigned char *) reswr_alloc (vssd
->length
);
2193 put_16 (big_endian
, 1, vssd
->data
+ 4);
2198 *pp
= unicode_to_bin (vs
->key
, big_endian
);
2199 length
+= (*pp
)->length
;
2200 vilen
+= (*pp
)->length
;
2201 vslen
+= (*pp
)->length
;
2202 vsslen
+= (*pp
)->length
;
2206 dword_align_bin (&pp
, &length
);
2207 vilen
+= length
- hold
;
2208 vslen
+= length
- hold
;
2209 vsslen
+= length
- hold
;
2211 *pp
= unicode_to_bin (vs
->value
, big_endian
);
2212 put_16 (big_endian
, (*pp
)->length
/ 2, vssd
->data
+ 2);
2213 length
+= (*pp
)->length
;
2214 vilen
+= (*pp
)->length
;
2215 vslen
+= (*pp
)->length
;
2216 vsslen
+= (*pp
)->length
;
2219 put_16 (big_endian
, vsslen
, vssd
->data
);
2222 put_16 (big_endian
, vslen
, vsd
->data
);
2229 unsigned long hold
, vvlen
, vvvlen
;
2230 struct bindata
*vvd
;
2231 const struct ver_varinfo
*vv
;
2233 *pp
= string_to_unicode_bin ("VarFileInfo", big_endian
);
2234 length
+= (*pp
)->length
;
2235 vilen
+= (*pp
)->length
;
2239 dword_align_bin (&pp
, &length
);
2240 vilen
+= length
- hold
;
2242 vvd
= (struct bindata
*) reswr_alloc (sizeof *vvd
);
2244 vvd
->data
= (unsigned char *) reswr_alloc (vvd
->length
);
2250 put_16 (big_endian
, 0, vvd
->data
+ 4);
2255 *pp
= unicode_to_bin (vi
->u
.var
.key
, big_endian
);
2256 length
+= (*pp
)->length
;
2257 vilen
+= (*pp
)->length
;
2258 vvlen
+= (*pp
)->length
;
2262 dword_align_bin (&pp
, &length
);
2263 vilen
+= length
- hold
;
2264 vvlen
+= length
- hold
;
2268 for (vv
= vi
->u
.var
.var
; vv
!= NULL
; vv
= vv
->next
)
2270 struct bindata
*vvsd
;
2272 vvsd
= (struct bindata
*) reswr_alloc (sizeof *vvsd
);
2274 vvsd
->data
= (unsigned char *) reswr_alloc (vvsd
->length
);
2281 put_16 (big_endian
, vv
->language
, vvsd
->data
);
2282 put_16 (big_endian
, vv
->charset
, vvsd
->data
+ 2);
2289 put_16 (big_endian
, vvlen
, vvd
->data
);
2290 put_16 (big_endian
, vvvlen
, vvd
->data
+ 2);
2296 put_16 (big_endian
, vilen
, vid
->data
);
2299 put_16 (big_endian
, length
, first
->data
);
2304 /* Convert a generic resource to binary. */
2306 static struct bindata
*
2307 res_to_bin_generic (unsigned long length
, const unsigned char *data
)
2311 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2313 d
->data
= (unsigned char *) data
;