1 /* resbin.c -- manipulate the Windows binary resource format.
2 Copyright 1997, 1998, 1999, 2002, 2003, 2007
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"
33 /* Macros to swap in values. */
35 #define get_8(s) (*((unsigned char *)(s)))
36 #define get_16(be, s) ((be) ? bfd_getb16 (s) : bfd_getl16 (s))
37 #define get_32(be, s) ((be) ? bfd_getb32 (s) : bfd_getl32 (s))
39 /* Local functions. */
41 static void toosmall (const char *);
43 static unichar
*get_unicode
44 (const unsigned char *, unsigned long, int, int *);
46 (struct res_id
*, const unsigned char *, unsigned long, int);
47 static struct res_resource
*bin_to_res_generic
48 (enum res_type
, const unsigned char *, unsigned long);
49 static struct res_resource
*bin_to_res_cursor
50 (const unsigned char *, unsigned long, int);
51 static struct res_resource
*bin_to_res_menu
52 (const unsigned char *, unsigned long, int);
53 static struct menuitem
*bin_to_res_menuitems
54 (const unsigned char *, unsigned long, int, int *);
55 static struct menuitem
*bin_to_res_menuexitems
56 (const unsigned char *, unsigned long, int, int *);
57 static struct res_resource
*bin_to_res_dialog
58 (const unsigned char *, unsigned long, int);
59 static struct res_resource
*bin_to_res_string
60 (const unsigned char *, unsigned long, int);
61 static struct res_resource
*bin_to_res_fontdir
62 (const unsigned char *, unsigned long, int);
63 static struct res_resource
*bin_to_res_accelerators
64 (const unsigned char *, unsigned long, int);
65 static struct res_resource
*bin_to_res_rcdata
66 (const unsigned char *, unsigned long, int);
67 static struct res_resource
*bin_to_res_group_cursor
68 (const unsigned char *, unsigned long, int);
69 static struct res_resource
*bin_to_res_group_icon
70 (const unsigned char *, unsigned long, int);
71 static struct res_resource
*bin_to_res_version
72 (const unsigned char *, unsigned long, int);
73 static struct res_resource
*bin_to_res_userdata
74 (const unsigned char *, unsigned long, int);
75 static void get_version_header
76 (const unsigned char *, unsigned long, int, const char *,
77 unichar
**, int *, int *, int *, int *);
79 /* Given a resource type ID, a pointer to data, a length, return a
80 res_resource structure which represents that resource. The caller
81 is responsible for initializing the res_info and coff_info fields
82 of the returned structure. */
85 bin_to_res (struct res_id type
, const unsigned char *data
,
86 unsigned long length
, int big_endian
)
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. */
131 toosmall (const char *msg
)
133 fatal (_("%s: not enough binary data"), msg
);
136 /* Swap in a NULL terminated unicode string. */
139 get_unicode (const unsigned char *data
, unsigned long length
,
140 int big_endian
, int *retlen
)
148 if (length
< (unsigned long) c
* 2 + 2)
149 toosmall (_("null terminated unicode string"));
150 if (get_16 (big_endian
, data
+ c
* 2) == 0)
155 ret
= (unichar
*) res_alloc ((c
+ 1) * sizeof (unichar
));
157 for (i
= 0; i
< c
; i
++)
158 ret
[i
] = get_16 (big_endian
, data
+ i
* 2);
167 /* Get a resource identifier. This returns the number of bytes used. */
170 get_resid (struct res_id
*id
, const unsigned char *data
,
171 unsigned long length
, int big_endian
)
176 toosmall (_("resource ID"));
178 first
= get_16 (big_endian
, data
);
182 toosmall (_("resource ID"));
184 id
->u
.id
= get_16 (big_endian
, data
+ 2);
190 id
->u
.n
.name
= get_unicode (data
, length
, big_endian
, &id
->u
.n
.length
);
191 return id
->u
.n
.length
* 2 + 2;
195 /* Convert a resource which just stores uninterpreted data from
198 struct res_resource
*
199 bin_to_res_generic (enum res_type type
, const unsigned char *data
,
200 unsigned long length
)
202 struct res_resource
*r
;
204 r
= (struct res_resource
*) res_alloc (sizeof *r
);
206 r
->u
.data
.data
= data
;
207 r
->u
.data
.length
= length
;
212 /* Convert a cursor resource from binary. */
214 struct res_resource
*
215 bin_to_res_cursor (const unsigned char *data
, unsigned long length
,
219 struct res_resource
*r
;
222 toosmall (_("cursor"));
224 c
= (struct cursor
*) res_alloc (sizeof *c
);
225 c
->xhotspot
= get_16 (big_endian
, data
);
226 c
->yhotspot
= get_16 (big_endian
, data
+ 2);
227 c
->length
= length
- 4;
230 r
= (struct res_resource
*) res_alloc (sizeof *r
);
231 r
->type
= RES_TYPE_CURSOR
;
237 /* Convert a menu resource from binary. */
239 struct res_resource
*
240 bin_to_res_menu (const unsigned char *data
, unsigned long length
,
243 struct res_resource
*r
;
247 r
= (struct res_resource
*) res_alloc (sizeof *r
);
248 r
->type
= RES_TYPE_MENU
;
250 m
= (struct menu
*) res_alloc (sizeof *m
);
254 toosmall (_("menu header"));
256 version
= get_16 (big_endian
, data
);
261 toosmall (_("menu header"));
263 m
->items
= bin_to_res_menuitems (data
+ 4, length
- 4, big_endian
,
266 else if (version
== 1)
271 toosmall (_("menuex header"));
272 m
->help
= get_32 (big_endian
, data
+ 4);
273 offset
= get_16 (big_endian
, data
+ 2);
274 if (offset
+ 4 >= length
)
275 toosmall (_("menuex offset"));
276 m
->items
= bin_to_res_menuexitems (data
+ 4 + offset
,
277 length
- (4 + offset
),
282 fatal (_("unsupported menu version %d"), version
);
287 /* Convert menu items from binary. */
289 static struct menuitem
*
290 bin_to_res_menuitems (const unsigned char *data
, unsigned long length
,
291 int big_endian
, int *read
)
293 struct menuitem
*first
, **pp
;
302 int flags
, slen
, itemlen
;
307 toosmall (_("menuitem header"));
309 mi
= (struct menuitem
*) res_alloc (sizeof *mi
);
313 flags
= get_16 (big_endian
, data
);
314 mi
->type
= flags
&~ (MENUITEM_POPUP
| MENUITEM_ENDMENU
);
316 if ((flags
& MENUITEM_POPUP
) == 0)
321 if (length
< stroff
+ 2)
322 toosmall (_("menuitem header"));
324 if (get_16 (big_endian
, data
+ stroff
) == 0)
330 mi
->text
= get_unicode (data
+ stroff
, length
- stroff
, big_endian
,
333 itemlen
= stroff
+ slen
* 2 + 2;
335 if ((flags
& MENUITEM_POPUP
) == 0)
338 mi
->id
= get_16 (big_endian
, data
+ 2);
345 mi
->popup
= bin_to_res_menuitems (data
+ itemlen
, length
- itemlen
,
346 big_endian
, &subread
);
358 if ((flags
& MENUITEM_ENDMENU
) != 0)
365 /* Convert menuex items from binary. */
367 static struct menuitem
*
368 bin_to_res_menuexitems (const unsigned char *data
, unsigned long length
,
369 int big_endian
, int *read
)
371 struct menuitem
*first
, **pp
;
381 unsigned int itemlen
;
385 toosmall (_("menuitem header"));
387 mi
= (struct menuitem
*) res_alloc (sizeof *mi
);
388 mi
->type
= get_32 (big_endian
, data
);
389 mi
->state
= get_32 (big_endian
, data
+ 4);
390 mi
->id
= get_16 (big_endian
, data
+ 8);
392 flags
= get_16 (big_endian
, data
+ 10);
394 if (get_16 (big_endian
, data
+ 12) == 0)
400 mi
->text
= get_unicode (data
+ 12, length
- 12, big_endian
, &slen
);
402 itemlen
= 12 + slen
* 2 + 2;
403 itemlen
= (itemlen
+ 3) &~ 3;
405 if ((flags
& 1) == 0)
414 if (length
< itemlen
+ 4)
415 toosmall (_("menuitem"));
416 mi
->help
= get_32 (big_endian
, data
+ itemlen
);
419 mi
->popup
= bin_to_res_menuexitems (data
+ itemlen
,
421 big_endian
, &subread
);
433 if ((flags
& 0x80) != 0)
440 /* Convert a dialog resource from binary. */
442 static struct res_resource
*
443 bin_to_res_dialog (const unsigned char *data
, unsigned long length
,
450 struct dialog_control
**pp
;
451 struct res_resource
*r
;
454 toosmall (_("dialog header"));
456 d
= (struct dialog
*) res_alloc (sizeof *d
);
458 signature
= get_16 (big_endian
, data
+ 2);
459 if (signature
!= 0xffff)
462 d
->style
= get_32 (big_endian
, data
);
463 d
->exstyle
= get_32 (big_endian
, data
+ 4);
470 version
= get_16 (big_endian
, data
);
472 fatal (_("unexpected DIALOGEX version %d"), version
);
474 d
->ex
= (struct dialog_ex
*) res_alloc (sizeof (struct dialog_ex
));
475 d
->ex
->help
= get_32 (big_endian
, data
+ 4);
476 d
->exstyle
= get_32 (big_endian
, data
+ 8);
477 d
->style
= get_32 (big_endian
, data
+ 12);
481 if (length
< off
+ 10)
482 toosmall (_("dialog header"));
484 c
= get_16 (big_endian
, data
+ off
);
485 d
->x
= get_16 (big_endian
, data
+ off
+ 2);
486 d
->y
= get_16 (big_endian
, data
+ off
+ 4);
487 d
->width
= get_16 (big_endian
, data
+ off
+ 6);
488 d
->height
= get_16 (big_endian
, data
+ off
+ 8);
492 sublen
= get_resid (&d
->menu
, data
+ off
, length
- off
, big_endian
);
495 sublen
= get_resid (&d
->class, data
+ off
, length
- off
, big_endian
);
498 d
->caption
= get_unicode (data
+ off
, length
- off
, big_endian
, &sublen
);
499 off
+= sublen
* 2 + 2;
503 if ((d
->style
& DS_SETFONT
) == 0)
511 d
->ex
->charset
= 1; /* Default charset. */
516 if (length
< off
+ 2)
517 toosmall (_("dialog font point size"));
519 d
->pointsize
= get_16 (big_endian
, data
+ off
);
524 if (length
< off
+ 4)
525 toosmall (_("dialogex font information"));
526 d
->ex
->weight
= get_16 (big_endian
, data
+ off
);
527 d
->ex
->italic
= get_8 (data
+ off
+ 2);
528 d
->ex
->charset
= get_8 (data
+ off
+ 3);
532 d
->font
= get_unicode (data
+ off
, length
- off
, big_endian
, &sublen
);
533 off
+= sublen
* 2 + 2;
539 for (i
= 0; i
< c
; i
++)
541 struct dialog_control
*dc
;
544 off
= (off
+ 3) &~ 3;
546 dc
= (struct dialog_control
*) res_alloc (sizeof *dc
);
550 if (length
< off
+ 8)
551 toosmall (_("dialog control"));
553 dc
->style
= get_32 (big_endian
, data
+ off
);
554 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
560 if (length
< off
+ 12)
561 toosmall (_("dialogex control"));
562 dc
->help
= get_32 (big_endian
, data
+ off
);
563 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
564 dc
->style
= get_32 (big_endian
, data
+ off
+ 8);
568 if (length
< off
+ 10)
569 toosmall (_("dialog control"));
571 dc
->x
= get_16 (big_endian
, data
+ off
);
572 dc
->y
= get_16 (big_endian
, data
+ off
+ 2);
573 dc
->width
= get_16 (big_endian
, data
+ off
+ 4);
574 dc
->height
= get_16 (big_endian
, data
+ off
+ 6);
577 dc
->id
= get_32 (big_endian
, data
+ off
+ 8);
579 dc
->id
= get_16 (big_endian
, data
+ off
+ 8);
581 off
+= 10 + (d
->ex
!= NULL
? 2 : 0);
583 sublen
= get_resid (&dc
->class, data
+ off
, length
- off
, big_endian
);
586 sublen
= get_resid (&dc
->text
, data
+ off
, length
- off
, big_endian
);
589 if (length
< off
+ 2)
590 toosmall (_("dialog control end"));
592 datalen
= get_16 (big_endian
, data
+ off
);
599 off
= (off
+ 3) &~ 3;
601 if (length
< off
+ datalen
)
602 toosmall (_("dialog control data"));
604 dc
->data
= ((struct rcdata_item
*)
605 res_alloc (sizeof (struct rcdata_item
)));
606 dc
->data
->next
= NULL
;
607 dc
->data
->type
= RCDATA_BUFFER
;
608 dc
->data
->u
.buffer
.length
= datalen
;
609 dc
->data
->u
.buffer
.data
= data
+ off
;
619 r
= (struct res_resource
*) res_alloc (sizeof *r
);
620 r
->type
= RES_TYPE_DIALOG
;
626 /* Convert a stringtable resource from binary. */
628 static struct res_resource
*
629 bin_to_res_string (const unsigned char *data
, unsigned long length
,
632 struct stringtable
*st
;
634 struct res_resource
*r
;
636 st
= (struct stringtable
*) res_alloc (sizeof *st
);
638 for (i
= 0; i
< 16; i
++)
643 toosmall (_("stringtable string length"));
644 slen
= get_16 (big_endian
, data
);
645 st
->strings
[i
].length
= slen
;
652 if (length
< 2 + 2 * slen
)
653 toosmall (_("stringtable string"));
655 s
= (unichar
*) res_alloc (slen
* sizeof (unichar
));
656 st
->strings
[i
].string
= s
;
658 for (j
= 0; j
< slen
; j
++)
659 s
[j
] = get_16 (big_endian
, data
+ 2 + j
* 2);
662 data
+= 2 + 2 * slen
;
663 length
-= 2 + 2 * slen
;
666 r
= (struct res_resource
*) res_alloc (sizeof *r
);
667 r
->type
= RES_TYPE_STRINGTABLE
;
668 r
->u
.stringtable
= st
;
673 /* Convert a fontdir resource from binary. */
675 static struct res_resource
*
676 bin_to_res_fontdir (const unsigned char *data
, unsigned long length
,
680 struct fontdir
*first
, **pp
;
681 struct res_resource
*r
;
684 toosmall (_("fontdir header"));
686 c
= get_16 (big_endian
, data
);
691 for (i
= 0; i
< c
; i
++)
697 toosmall (_("fontdir"));
699 fd
= (struct fontdir
*) res_alloc (sizeof *fd
);
700 fd
->index
= get_16 (big_endian
, data
);
702 /* To work out the length of the fontdir data, we must get the
703 length of the device name and face name strings, even though
704 we don't store them in the fontdir structure. The
705 documentation says that these are NULL terminated char
706 strings, not Unicode strings. */
710 while (off
< length
&& data
[off
] != '\0')
713 toosmall (_("fontdir device name"));
716 while (off
< length
&& data
[off
] != '\0')
719 toosmall (_("fontdir face name"));
729 /* The documentation does not indicate that any rounding is
736 r
= (struct res_resource
*) res_alloc (sizeof *r
);
737 r
->type
= RES_TYPE_FONTDIR
;
738 r
->u
.fontdir
= first
;
743 /* Convert an accelerators resource from binary. */
745 static struct res_resource
*
746 bin_to_res_accelerators (const unsigned char *data
, unsigned long length
,
749 struct accelerator
*first
, **pp
;
750 struct res_resource
*r
;
757 struct accelerator
*a
;
760 toosmall (_("accelerator"));
762 a
= (struct accelerator
*) res_alloc (sizeof *a
);
764 a
->flags
= get_16 (big_endian
, data
);
765 a
->key
= get_16 (big_endian
, data
+ 2);
766 a
->id
= get_16 (big_endian
, data
+ 4);
772 if ((a
->flags
& ACC_LAST
) != 0)
779 r
= (struct res_resource
*) res_alloc (sizeof *r
);
780 r
->type
= RES_TYPE_ACCELERATOR
;
786 /* Convert an rcdata resource from binary. */
788 static struct res_resource
*
789 bin_to_res_rcdata (const unsigned char *data
, unsigned long length
,
790 int big_endian ATTRIBUTE_UNUSED
)
792 struct rcdata_item
*ri
;
793 struct res_resource
*r
;
795 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
798 ri
->type
= RCDATA_BUFFER
;
799 ri
->u
.buffer
.length
= length
;
800 ri
->u
.buffer
.data
= data
;
802 r
= (struct res_resource
*) res_alloc (sizeof *r
);
803 r
->type
= RES_TYPE_RCDATA
;
809 /* Convert a group cursor resource from binary. */
811 static struct res_resource
*
812 bin_to_res_group_cursor (const unsigned char *data
, unsigned long length
,
816 struct group_cursor
*first
, **pp
;
817 struct res_resource
*r
;
820 toosmall (_("group cursor header"));
822 type
= get_16 (big_endian
, data
+ 2);
824 fatal (_("unexpected group cursor type %d"), type
);
826 c
= get_16 (big_endian
, data
+ 4);
834 for (i
= 0; i
< c
; i
++)
836 struct group_cursor
*gc
;
839 toosmall (_("group cursor"));
841 gc
= (struct group_cursor
*) res_alloc (sizeof *gc
);
843 gc
->width
= get_16 (big_endian
, data
);
844 gc
->height
= get_16 (big_endian
, data
+ 2);
845 gc
->planes
= get_16 (big_endian
, data
+ 4);
846 gc
->bits
= get_16 (big_endian
, data
+ 6);
847 gc
->bytes
= get_32 (big_endian
, data
+ 8);
848 gc
->index
= get_16 (big_endian
, data
+ 12);
858 r
= (struct res_resource
*) res_alloc (sizeof *r
);
859 r
->type
= RES_TYPE_GROUP_CURSOR
;
860 r
->u
.group_cursor
= first
;
865 /* Convert a group icon resource from binary. */
867 static struct res_resource
*
868 bin_to_res_group_icon (const unsigned char *data
, unsigned long length
,
872 struct group_icon
*first
, **pp
;
873 struct res_resource
*r
;
876 toosmall (_("group icon header"));
878 type
= get_16 (big_endian
, data
+ 2);
880 fatal (_("unexpected group icon type %d"), type
);
882 c
= get_16 (big_endian
, data
+ 4);
890 for (i
= 0; i
< c
; i
++)
892 struct group_icon
*gi
;
895 toosmall (_("group icon"));
897 gi
= (struct group_icon
*) res_alloc (sizeof *gi
);
900 gi
->height
= data
[1];
901 gi
->colors
= data
[2];
902 gi
->planes
= get_16 (big_endian
, data
+ 4);
903 gi
->bits
= get_16 (big_endian
, data
+ 6);
904 gi
->bytes
= get_32 (big_endian
, data
+ 8);
905 gi
->index
= get_16 (big_endian
, data
+ 12);
915 r
= (struct res_resource
*) res_alloc (sizeof *r
);
916 r
->type
= RES_TYPE_GROUP_ICON
;
917 r
->u
.group_icon
= first
;
922 /* Extract data from a version header. If KEY is not NULL, then the
923 key must be KEY; otherwise, the key is returned in *PKEY. This
924 sets *LEN to the total length, *VALLEN to the value length, *TYPE
925 to the type, and *OFF to the offset to the children. */
928 get_version_header (const unsigned char *data
, unsigned long length
,
929 int big_endian
, const char *key
, unichar
**pkey
,
930 int *len
, int *vallen
, int *type
, int *off
)
935 *len
= get_16 (big_endian
, data
);
936 *vallen
= get_16 (big_endian
, data
+ 2);
937 *type
= get_16 (big_endian
, data
+ 4);
948 *pkey
= get_unicode (data
, length
, big_endian
, &sublen
);
949 *off
+= sublen
* 2 + 2;
957 if (get_16 (big_endian
, data
) != (unsigned char) *key
)
958 fatal (_("unexpected version string"));
971 *off
= (*off
+ 3) &~ 3;
974 /* Convert a version resource from binary. */
976 static struct res_resource
*
977 bin_to_res_version (const unsigned char *data
, unsigned long length
,
980 int verlen
, vallen
, type
, off
;
981 struct fixed_versioninfo
*fi
;
982 struct ver_info
*first
, **pp
;
983 struct versioninfo
*v
;
984 struct res_resource
*r
;
986 get_version_header (data
, length
, big_endian
, "VS_VERSION_INFO",
987 (unichar
**) NULL
, &verlen
, &vallen
, &type
, &off
);
989 if ((unsigned int) verlen
!= length
)
990 fatal (_("version length %d does not match resource length %lu"),
994 fatal (_("unexpected version type %d"), type
);
1003 unsigned long signature
, fiv
;
1006 fatal (_("unexpected fixed version information length %d"), vallen
);
1009 toosmall (_("fixed version info"));
1011 signature
= get_32 (big_endian
, data
);
1012 if (signature
!= 0xfeef04bd)
1013 fatal (_("unexpected fixed version signature %lu"), signature
);
1015 fiv
= get_32 (big_endian
, data
+ 4);
1016 if (fiv
!= 0 && fiv
!= 0x10000)
1017 fatal (_("unexpected fixed version info version %lu"), fiv
);
1019 fi
= (struct fixed_versioninfo
*) res_alloc (sizeof *fi
);
1021 fi
->file_version_ms
= get_32 (big_endian
, data
+ 8);
1022 fi
->file_version_ls
= get_32 (big_endian
, data
+ 12);
1023 fi
->product_version_ms
= get_32 (big_endian
, data
+ 16);
1024 fi
->product_version_ls
= get_32 (big_endian
, data
+ 20);
1025 fi
->file_flags_mask
= get_32 (big_endian
, data
+ 24);
1026 fi
->file_flags
= get_32 (big_endian
, data
+ 28);
1027 fi
->file_os
= get_32 (big_endian
, data
+ 32);
1028 fi
->file_type
= get_32 (big_endian
, data
+ 36);
1029 fi
->file_subtype
= get_32 (big_endian
, data
+ 40);
1030 fi
->file_date_ms
= get_32 (big_endian
, data
+ 44);
1031 fi
->file_date_ls
= get_32 (big_endian
, data
+ 48);
1042 struct ver_info
*vi
;
1046 toosmall (_("version var info"));
1048 vi
= (struct ver_info
*) res_alloc (sizeof *vi
);
1050 ch
= get_16 (big_endian
, data
+ 6);
1054 struct ver_stringinfo
**ppvs
;
1056 vi
->type
= VERINFO_STRING
;
1058 get_version_header (data
, length
, big_endian
, "StringFileInfo",
1059 (unichar
**) NULL
, &verlen
, &vallen
, &type
,
1063 fatal (_("unexpected stringfileinfo value length %d"), vallen
);
1068 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1069 &vi
->u
.string
.language
, &verlen
, &vallen
,
1073 fatal (_("unexpected version stringtable value length %d"), vallen
);
1079 vi
->u
.string
.strings
= NULL
;
1080 ppvs
= &vi
->u
.string
.strings
;
1082 /* It's convenient to round verlen to a 4 byte alignment,
1083 since we round the subvariables in the loop. */
1084 verlen
= (verlen
+ 3) &~ 3;
1088 struct ver_stringinfo
*vs
;
1089 int subverlen
, vslen
, valoff
;
1091 vs
= (struct ver_stringinfo
*) res_alloc (sizeof *vs
);
1093 get_version_header (data
, length
, big_endian
,
1094 (const char *) NULL
, &vs
->key
, &subverlen
,
1095 &vallen
, &type
, &off
);
1097 subverlen
= (subverlen
+ 3) &~ 3;
1102 vs
->value
= get_unicode (data
, length
, big_endian
, &vslen
);
1103 valoff
= vslen
* 2 + 2;
1104 valoff
= (valoff
+ 3) &~ 3;
1106 if (off
+ valoff
!= subverlen
)
1107 fatal (_("unexpected version string length %d != %d + %d"),
1108 subverlen
, off
, valoff
);
1117 if (verlen
< subverlen
)
1118 fatal (_("unexpected version string length %d < %d"),
1121 verlen
-= subverlen
;
1126 struct ver_varinfo
**ppvv
;
1128 vi
->type
= VERINFO_VAR
;
1130 get_version_header (data
, length
, big_endian
, "VarFileInfo",
1131 (unichar
**) NULL
, &verlen
, &vallen
, &type
,
1135 fatal (_("unexpected varfileinfo value length %d"), vallen
);
1140 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1141 &vi
->u
.var
.key
, &verlen
, &vallen
, &type
, &off
);
1146 vi
->u
.var
.var
= NULL
;
1147 ppvv
= &vi
->u
.var
.var
;
1151 struct ver_varinfo
*vv
;
1154 toosmall (_("version varfileinfo"));
1156 vv
= (struct ver_varinfo
*) res_alloc (sizeof *vv
);
1158 vv
->language
= get_16 (big_endian
, data
);
1159 vv
->charset
= get_16 (big_endian
, data
+ 2);
1169 fatal (_("unexpected version value length %d"), vallen
);
1175 fatal (_("unexpected version string"));
1182 v
= (struct versioninfo
*) res_alloc (sizeof *v
);
1186 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1187 r
->type
= RES_TYPE_VERSIONINFO
;
1188 r
->u
.versioninfo
= v
;
1193 /* Convert an arbitrary user defined resource from binary. */
1195 static struct res_resource
*
1196 bin_to_res_userdata (const unsigned char *data
, unsigned long length
,
1197 int big_endian ATTRIBUTE_UNUSED
)
1199 struct rcdata_item
*ri
;
1200 struct res_resource
*r
;
1202 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
1205 ri
->type
= RCDATA_BUFFER
;
1206 ri
->u
.buffer
.length
= length
;
1207 ri
->u
.buffer
.data
= data
;
1209 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1210 r
->type
= RES_TYPE_USERDATA
;
1216 /* Macros to swap out values. */
1218 #define put_8(v, s) (*((unsigned char *) (s)) = (unsigned char) (v))
1219 #define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
1220 #define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
1222 /* Local functions used to convert resources to binary format. */
1224 static void dword_align_bin (struct bindata
***, unsigned long *);
1225 static struct bindata
*resid_to_bin (struct res_id
, int);
1226 static struct bindata
*unicode_to_bin (const unichar
*, int);
1227 static struct bindata
*res_to_bin_accelerator
1228 (const struct accelerator
*, int);
1229 static struct bindata
*res_to_bin_cursor
1230 (const struct cursor
*, int);
1231 static struct bindata
*res_to_bin_group_cursor
1232 (const struct group_cursor
*, int);
1233 static struct bindata
*res_to_bin_dialog
1234 (const struct dialog
*, int);
1235 static struct bindata
*res_to_bin_fontdir
1236 (const struct fontdir
*, int);
1237 static struct bindata
*res_to_bin_group_icon
1238 (const struct group_icon
*, int);
1239 static struct bindata
*res_to_bin_menu
1240 (const struct menu
*, int);
1241 static struct bindata
*res_to_bin_menuitems
1242 (const struct menuitem
*, int);
1243 static struct bindata
*res_to_bin_menuexitems
1244 (const struct menuitem
*, int);
1245 static struct bindata
*res_to_bin_rcdata
1246 (const struct rcdata_item
*, int);
1247 static struct bindata
*res_to_bin_stringtable
1248 (const struct stringtable
*, int);
1249 static struct bindata
*string_to_unicode_bin (const char *, int);
1250 static struct bindata
*res_to_bin_versioninfo
1251 (const struct versioninfo
*, int);
1252 static struct bindata
*res_to_bin_generic
1253 (unsigned long, const unsigned char *);
1255 /* Convert a resource to binary. */
1258 res_to_bin (const struct res_resource
*res
, int big_endian
)
1264 case RES_TYPE_BITMAP
:
1267 case RES_TYPE_MESSAGETABLE
:
1268 return res_to_bin_generic (res
->u
.data
.length
, res
->u
.data
.data
);
1269 case RES_TYPE_ACCELERATOR
:
1270 return res_to_bin_accelerator (res
->u
.acc
, big_endian
);
1271 case RES_TYPE_CURSOR
:
1272 return res_to_bin_cursor (res
->u
.cursor
, big_endian
);
1273 case RES_TYPE_GROUP_CURSOR
:
1274 return res_to_bin_group_cursor (res
->u
.group_cursor
, big_endian
);
1275 case RES_TYPE_DIALOG
:
1276 return res_to_bin_dialog (res
->u
.dialog
, big_endian
);
1277 case RES_TYPE_FONTDIR
:
1278 return res_to_bin_fontdir (res
->u
.fontdir
, big_endian
);
1279 case RES_TYPE_GROUP_ICON
:
1280 return res_to_bin_group_icon (res
->u
.group_icon
, big_endian
);
1282 return res_to_bin_menu (res
->u
.menu
, big_endian
);
1283 case RES_TYPE_RCDATA
:
1284 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1285 case RES_TYPE_STRINGTABLE
:
1286 return res_to_bin_stringtable (res
->u
.stringtable
, big_endian
);
1287 case RES_TYPE_USERDATA
:
1288 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1289 case RES_TYPE_VERSIONINFO
:
1290 return res_to_bin_versioninfo (res
->u
.versioninfo
, big_endian
);
1294 /* Align to a 32 bit boundary. PPP points to the of a list of bindata
1295 structures. LENGTH points to the length of the structures. If
1296 necessary, this adds a new bindata to bring length up to a 32 bit
1297 boundary. It updates *PPP and *LENGTH. */
1300 dword_align_bin (struct bindata
***ppp
, unsigned long *length
)
1305 if ((*length
& 3) == 0)
1308 add
= 4 - (*length
& 3);
1310 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1312 d
->data
= (unsigned char *) reswr_alloc (add
);
1313 memset (d
->data
, 0, add
);
1317 *ppp
= &(**ppp
)->next
;
1322 /* Convert a resource ID to binary. This always returns exactly one
1323 bindata structure. */
1325 static struct bindata
*
1326 resid_to_bin (struct res_id id
, int big_endian
)
1330 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1335 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1336 put_16 (big_endian
, 0xffff, d
->data
);
1337 put_16 (big_endian
, id
.u
.id
, d
->data
+ 2);
1343 d
->length
= id
.u
.n
.length
* 2 + 2;
1344 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1345 for (i
= 0; i
< id
.u
.n
.length
; i
++)
1346 put_16 (big_endian
, id
.u
.n
.name
[i
], d
->data
+ i
* 2);
1347 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1355 /* Convert a null terminated unicode string to binary. This always
1356 returns exactly one bindata structure. */
1358 static struct bindata
*
1359 unicode_to_bin (const unichar
*str
, int big_endian
)
1369 for (s
= str
; *s
!= 0; s
++)
1373 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1374 d
->length
= len
* 2 + 2;
1375 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1378 put_16 (big_endian
, 0, d
->data
);
1384 for (s
= str
, i
= 0; *s
!= 0; s
++, i
++)
1385 put_16 (big_endian
, *s
, d
->data
+ i
* 2);
1386 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1394 /* Convert an accelerator resource to binary. */
1396 static struct bindata
*
1397 res_to_bin_accelerator (const struct accelerator
*accelerators
,
1400 struct bindata
*first
, **pp
;
1401 const struct accelerator
*a
;
1406 for (a
= accelerators
; a
!= NULL
; a
= a
->next
)
1410 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1412 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1415 a
->flags
| (a
->next
!= NULL
? 0 : ACC_LAST
),
1417 put_16 (big_endian
, a
->key
, d
->data
+ 2);
1418 put_16 (big_endian
, a
->id
, d
->data
+ 4);
1419 put_16 (big_endian
, 0, d
->data
+ 6);
1429 /* Convert a cursor resource to binary. */
1431 static struct bindata
*
1432 res_to_bin_cursor (const struct cursor
*c
, int big_endian
)
1436 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1438 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1440 put_16 (big_endian
, c
->xhotspot
, d
->data
);
1441 put_16 (big_endian
, c
->yhotspot
, d
->data
+ 2);
1443 d
->next
= (struct bindata
*) reswr_alloc (sizeof *d
);
1444 d
->next
->length
= c
->length
;
1445 d
->next
->data
= (unsigned char *) c
->data
;
1446 d
->next
->next
= NULL
;
1451 /* Convert a group cursor resource to binary. */
1453 static struct bindata
*
1454 res_to_bin_group_cursor (const struct group_cursor
*group_cursors
,
1457 struct bindata
*first
, **pp
;
1459 const struct group_cursor
*gc
;
1461 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1463 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1465 put_16 (big_endian
, 0, first
->data
);
1466 put_16 (big_endian
, 2, first
->data
+ 2);
1472 for (gc
= group_cursors
; gc
!= NULL
; gc
= gc
->next
)
1478 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1480 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1482 put_16 (big_endian
, gc
->width
, d
->data
);
1483 put_16 (big_endian
, gc
->height
, d
->data
+ 2);
1484 put_16 (big_endian
, gc
->planes
, d
->data
+ 4);
1485 put_16 (big_endian
, gc
->bits
, d
->data
+ 6);
1486 put_32 (big_endian
, gc
->bytes
, d
->data
+ 8);
1487 put_16 (big_endian
, gc
->index
, d
->data
+ 12);
1494 put_16 (big_endian
, c
, first
->data
+ 4);
1499 /* Convert a dialog resource to binary. */
1501 static struct bindata
*
1502 res_to_bin_dialog (const struct dialog
*dialog
, int big_endian
)
1505 struct bindata
*first
, **pp
;
1506 unsigned long length
;
1508 struct dialog_control
*dc
;
1510 dialogex
= extended_dialog (dialog
);
1512 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1513 first
->length
= dialogex
? 26 : 18;
1514 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1516 length
= first
->length
;
1520 put_32 (big_endian
, dialog
->style
, first
->data
);
1521 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 4);
1526 put_16 (big_endian
, 1, first
->data
);
1527 put_16 (big_endian
, 0xffff, first
->data
+ 2);
1529 if (dialog
->ex
== NULL
)
1530 put_32 (big_endian
, 0, first
->data
+ 4);
1532 put_32 (big_endian
, dialog
->ex
->help
, first
->data
+ 4);
1533 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 8);
1534 put_32 (big_endian
, dialog
->style
, first
->data
+ 12);
1538 put_16 (big_endian
, dialog
->x
, first
->data
+ off
+ 2);
1539 put_16 (big_endian
, dialog
->y
, first
->data
+ off
+ 4);
1540 put_16 (big_endian
, dialog
->width
, first
->data
+ off
+ 6);
1541 put_16 (big_endian
, dialog
->height
, first
->data
+ off
+ 8);
1545 *pp
= resid_to_bin (dialog
->menu
, big_endian
);
1546 length
+= (*pp
)->length
;
1549 *pp
= resid_to_bin (dialog
->class, big_endian
);
1550 length
+= (*pp
)->length
;
1553 *pp
= unicode_to_bin (dialog
->caption
, big_endian
);
1554 length
+= (*pp
)->length
;
1557 if ((dialog
->style
& DS_SETFONT
) != 0)
1561 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1562 d
->length
= dialogex
? 6 : 2;
1563 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1565 length
+= d
->length
;
1567 put_16 (big_endian
, dialog
->pointsize
, d
->data
);
1571 if (dialog
->ex
== NULL
)
1573 put_16 (big_endian
, 0, d
->data
+ 2);
1574 put_8 (0, d
->data
+ 4);
1575 put_8 (1, d
->data
+ 5);
1579 put_16 (big_endian
, dialog
->ex
->weight
, d
->data
+ 2);
1580 put_8 (dialog
->ex
->italic
, d
->data
+ 4);
1581 put_8 (dialog
->ex
->charset
, d
->data
+ 5);
1588 *pp
= unicode_to_bin (dialog
->font
, big_endian
);
1589 length
+= (*pp
)->length
;
1594 for (dc
= dialog
->controls
; dc
!= NULL
; dc
= dc
->next
)
1601 dword_align_bin (&pp
, &length
);
1603 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1604 d
->length
= dialogex
? 24 : 18;
1605 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1607 length
+= d
->length
;
1611 put_32 (big_endian
, dc
->style
, d
->data
);
1612 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1617 put_32 (big_endian
, dc
->help
, d
->data
);
1618 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1619 put_32 (big_endian
, dc
->style
, d
->data
+ 8);
1623 put_16 (big_endian
, dc
->x
, d
->data
+ dcoff
);
1624 put_16 (big_endian
, dc
->y
, d
->data
+ dcoff
+ 2);
1625 put_16 (big_endian
, dc
->width
, d
->data
+ dcoff
+ 4);
1626 put_16 (big_endian
, dc
->height
, d
->data
+ dcoff
+ 6);
1629 put_32 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1631 put_16 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1636 *pp
= resid_to_bin (dc
->class, big_endian
);
1637 length
+= (*pp
)->length
;
1640 *pp
= resid_to_bin (dc
->text
, big_endian
);
1641 length
+= (*pp
)->length
;
1644 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1646 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1654 if (dc
->data
== NULL
)
1655 put_16 (big_endian
, 0, d
->data
);
1658 unsigned long sublen
;
1660 dword_align_bin (&pp
, &length
);
1662 *pp
= res_to_bin_rcdata (dc
->data
, big_endian
);
1666 sublen
+= (*pp
)->length
;
1670 put_16 (big_endian
, sublen
, d
->data
);
1675 put_16 (big_endian
, c
, first
->data
+ off
);
1680 /* Convert a fontdir resource to binary. */
1682 static struct bindata
*
1683 res_to_bin_fontdir (const struct fontdir
*fontdirs
, int big_endian
)
1685 struct bindata
*first
, **pp
;
1687 const struct fontdir
*fd
;
1689 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1691 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1697 for (fd
= fontdirs
; fd
!= NULL
; fd
= fd
->next
)
1703 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1705 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1707 put_16 (big_endian
, fd
->index
, d
->data
);
1712 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1713 d
->length
= fd
->length
;
1714 d
->data
= (unsigned char *) fd
->data
;
1721 put_16 (big_endian
, c
, first
->data
);
1726 /* Convert a group icon resource to binary. */
1728 static struct bindata
*
1729 res_to_bin_group_icon (const struct group_icon
*group_icons
, int big_endian
)
1731 struct bindata
*first
, **pp
;
1733 const struct group_icon
*gi
;
1735 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1737 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1739 put_16 (big_endian
, 0, first
->data
);
1740 put_16 (big_endian
, 1, first
->data
+ 2);
1746 for (gi
= group_icons
; gi
!= NULL
; gi
= gi
->next
)
1752 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1754 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1756 d
->data
[0] = gi
->width
;
1757 d
->data
[1] = gi
->height
;
1758 d
->data
[2] = gi
->colors
;
1760 put_16 (big_endian
, gi
->planes
, d
->data
+ 4);
1761 put_16 (big_endian
, gi
->bits
, d
->data
+ 6);
1762 put_32 (big_endian
, gi
->bytes
, d
->data
+ 8);
1763 put_16 (big_endian
, gi
->index
, d
->data
+ 12);
1770 put_16 (big_endian
, c
, first
->data
+ 4);
1775 /* Convert a menu resource to binary. */
1777 static struct bindata
*
1778 res_to_bin_menu (const struct menu
*menu
, int big_endian
)
1783 menuex
= extended_menu (menu
);
1785 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1786 d
->length
= menuex
? 8 : 4;
1787 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1791 put_16 (big_endian
, 0, d
->data
);
1792 put_16 (big_endian
, 0, d
->data
+ 2);
1794 d
->next
= res_to_bin_menuitems (menu
->items
, big_endian
);
1798 put_16 (big_endian
, 1, d
->data
);
1799 put_16 (big_endian
, 4, d
->data
+ 2);
1800 put_32 (big_endian
, menu
->help
, d
->data
+ 4);
1802 d
->next
= res_to_bin_menuexitems (menu
->items
, big_endian
);
1808 /* Convert menu items to binary. */
1810 static struct bindata
*
1811 res_to_bin_menuitems (const struct menuitem
*items
, int big_endian
)
1813 struct bindata
*first
, **pp
;
1814 const struct menuitem
*mi
;
1819 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1824 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1825 d
->length
= mi
->popup
== NULL
? 4 : 2;
1826 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1829 if (mi
->next
== NULL
)
1830 flags
|= MENUITEM_ENDMENU
;
1831 if (mi
->popup
!= NULL
)
1832 flags
|= MENUITEM_POPUP
;
1834 put_16 (big_endian
, flags
, d
->data
);
1836 if (mi
->popup
== NULL
)
1837 put_16 (big_endian
, mi
->id
, d
->data
+ 2);
1842 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1845 if (mi
->popup
!= NULL
)
1847 *pp
= res_to_bin_menuitems (mi
->popup
, big_endian
);
1856 /* Convert menuex items to binary. */
1858 static struct bindata
*
1859 res_to_bin_menuexitems (const struct menuitem
*items
, int big_endian
)
1861 struct bindata
*first
, **pp
;
1862 unsigned long length
;
1863 const struct menuitem
*mi
;
1870 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1875 dword_align_bin (&pp
, &length
);
1877 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1879 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1883 put_32 (big_endian
, mi
->type
, d
->data
);
1884 put_32 (big_endian
, mi
->state
, d
->data
+ 4);
1885 put_16 (big_endian
, mi
->id
, d
->data
+ 8);
1888 if (mi
->next
== NULL
)
1890 if (mi
->popup
!= NULL
)
1892 put_16 (big_endian
, flags
, d
->data
+ 10);
1897 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1898 length
+= (*pp
)->length
;
1901 if (mi
->popup
!= NULL
)
1903 dword_align_bin (&pp
, &length
);
1905 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1907 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1909 put_32 (big_endian
, mi
->help
, d
->data
);
1914 *pp
= res_to_bin_menuexitems (mi
->popup
, big_endian
);
1917 length
+= (*pp
)->length
;
1926 /* Convert an rcdata resource to binary. This is also used to convert
1927 other information which happens to be stored in rcdata_item lists
1930 static struct bindata
*
1931 res_to_bin_rcdata (const struct rcdata_item
*items
, int big_endian
)
1933 struct bindata
*first
, **pp
;
1934 const struct rcdata_item
*ri
;
1939 for (ri
= items
; ri
!= NULL
; ri
= ri
->next
)
1943 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1952 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1953 put_16 (big_endian
, ri
->u
.word
, d
->data
);
1958 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1959 put_32 (big_endian
, ri
->u
.dword
, d
->data
);
1963 d
->length
= ri
->u
.string
.length
;
1964 d
->data
= (unsigned char *) ri
->u
.string
.s
;
1967 case RCDATA_WSTRING
:
1971 d
->length
= ri
->u
.wstring
.length
* 2;
1972 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1973 for (i
= 0; i
< ri
->u
.wstring
.length
; i
++)
1974 put_16 (big_endian
, ri
->u
.wstring
.w
[i
], d
->data
+ i
* 2);
1979 d
->length
= ri
->u
.buffer
.length
;
1980 d
->data
= (unsigned char *) ri
->u
.buffer
.data
;
1992 /* Convert a stringtable resource to binary. */
1994 static struct bindata
*
1995 res_to_bin_stringtable (const struct stringtable
*st
, int big_endian
)
1997 struct bindata
*first
, **pp
;
2003 for (i
= 0; i
< 16; i
++)
2009 slen
= st
->strings
[i
].length
;
2010 s
= st
->strings
[i
].string
;
2012 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2013 d
->length
= 2 + slen
* 2;
2014 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2016 put_16 (big_endian
, slen
, d
->data
);
2018 for (j
= 0; j
< slen
; j
++)
2019 put_16 (big_endian
, s
[j
], d
->data
+ 2 + j
* 2);
2029 /* Convert an ASCII string to a unicode binary string. This always
2030 returns exactly one bindata structure. */
2032 static struct bindata
*
2033 string_to_unicode_bin (const char *s
, int big_endian
)
2040 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2041 d
->length
= len
* 2 + 2;
2042 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2044 for (i
= 0; i
< len
; i
++)
2045 put_16 (big_endian
, s
[i
], d
->data
+ i
* 2);
2046 put_16 (big_endian
, 0, d
->data
+ i
* 2);
2053 /* Convert a versioninfo resource to binary. */
2055 static struct bindata
*
2056 res_to_bin_versioninfo (const struct versioninfo
*versioninfo
, int big_endian
)
2058 struct bindata
*first
, **pp
;
2059 unsigned long length
;
2060 struct ver_info
*vi
;
2062 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
2064 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
2068 if (versioninfo
->fixed
== NULL
)
2069 put_16 (big_endian
, 0, first
->data
+ 2);
2071 put_16 (big_endian
, 52, first
->data
+ 2);
2073 put_16 (big_endian
, 0, first
->data
+ 4);
2077 *pp
= string_to_unicode_bin ("VS_VERSION_INFO", big_endian
);
2078 length
+= (*pp
)->length
;
2081 dword_align_bin (&pp
, &length
);
2083 if (versioninfo
->fixed
!= NULL
)
2085 const struct fixed_versioninfo
*fi
;
2088 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2090 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2094 fi
= versioninfo
->fixed
;
2096 put_32 (big_endian
, 0xfeef04bd, d
->data
);
2097 put_32 (big_endian
, 0x10000, d
->data
+ 4);
2098 put_32 (big_endian
, fi
->file_version_ms
, d
->data
+ 8);
2099 put_32 (big_endian
, fi
->file_version_ls
, d
->data
+ 12);
2100 put_32 (big_endian
, fi
->product_version_ms
, d
->data
+ 16);
2101 put_32 (big_endian
, fi
->product_version_ls
, d
->data
+ 20);
2102 put_32 (big_endian
, fi
->file_flags_mask
, d
->data
+ 24);
2103 put_32 (big_endian
, fi
->file_flags
, d
->data
+ 28);
2104 put_32 (big_endian
, fi
->file_os
, d
->data
+ 32);
2105 put_32 (big_endian
, fi
->file_type
, d
->data
+ 36);
2106 put_32 (big_endian
, fi
->file_subtype
, d
->data
+ 40);
2107 put_32 (big_endian
, fi
->file_date_ms
, d
->data
+ 44);
2108 put_32 (big_endian
, fi
->file_date_ls
, d
->data
+ 48);
2115 for (vi
= versioninfo
->var
; vi
!= NULL
; vi
= vi
->next
)
2117 struct bindata
*vid
;
2118 unsigned long vilen
;
2120 dword_align_bin (&pp
, &length
);
2122 vid
= (struct bindata
*) reswr_alloc (sizeof *vid
);
2124 vid
->data
= (unsigned char *) reswr_alloc (vid
->length
);
2129 put_16 (big_endian
, 0, vid
->data
+ 2);
2130 put_16 (big_endian
, 0, vid
->data
+ 4);
2140 case VERINFO_STRING
:
2142 unsigned long hold
, vslen
;
2143 struct bindata
*vsd
;
2144 const struct ver_stringinfo
*vs
;
2146 *pp
= string_to_unicode_bin ("StringFileInfo", big_endian
);
2147 length
+= (*pp
)->length
;
2148 vilen
+= (*pp
)->length
;
2152 dword_align_bin (&pp
, &length
);
2153 vilen
+= length
- hold
;
2155 vsd
= (struct bindata
*) reswr_alloc (sizeof *vsd
);
2157 vsd
->data
= (unsigned char *) reswr_alloc (vsd
->length
);
2163 put_16 (big_endian
, 0, vsd
->data
+ 2);
2164 put_16 (big_endian
, 0, vsd
->data
+ 4);
2169 *pp
= unicode_to_bin (vi
->u
.string
.language
, big_endian
);
2170 length
+= (*pp
)->length
;
2171 vilen
+= (*pp
)->length
;
2172 vslen
+= (*pp
)->length
;
2175 for (vs
= vi
->u
.string
.strings
; vs
!= NULL
; vs
= vs
->next
)
2177 struct bindata
*vssd
;
2178 unsigned long vsslen
;
2181 dword_align_bin (&pp
, &length
);
2182 vilen
+= length
- hold
;
2183 vslen
+= length
- hold
;
2185 vssd
= (struct bindata
*) reswr_alloc (sizeof *vssd
);
2187 vssd
->data
= (unsigned char *) reswr_alloc (vssd
->length
);
2194 put_16 (big_endian
, 1, vssd
->data
+ 4);
2199 *pp
= unicode_to_bin (vs
->key
, big_endian
);
2200 length
+= (*pp
)->length
;
2201 vilen
+= (*pp
)->length
;
2202 vslen
+= (*pp
)->length
;
2203 vsslen
+= (*pp
)->length
;
2207 dword_align_bin (&pp
, &length
);
2208 vilen
+= length
- hold
;
2209 vslen
+= length
- hold
;
2210 vsslen
+= length
- hold
;
2212 *pp
= unicode_to_bin (vs
->value
, big_endian
);
2213 put_16 (big_endian
, (*pp
)->length
/ 2, vssd
->data
+ 2);
2214 length
+= (*pp
)->length
;
2215 vilen
+= (*pp
)->length
;
2216 vslen
+= (*pp
)->length
;
2217 vsslen
+= (*pp
)->length
;
2220 put_16 (big_endian
, vsslen
, vssd
->data
);
2223 put_16 (big_endian
, vslen
, vsd
->data
);
2230 unsigned long hold
, vvlen
, vvvlen
;
2231 struct bindata
*vvd
;
2232 const struct ver_varinfo
*vv
;
2234 *pp
= string_to_unicode_bin ("VarFileInfo", big_endian
);
2235 length
+= (*pp
)->length
;
2236 vilen
+= (*pp
)->length
;
2240 dword_align_bin (&pp
, &length
);
2241 vilen
+= length
- hold
;
2243 vvd
= (struct bindata
*) reswr_alloc (sizeof *vvd
);
2245 vvd
->data
= (unsigned char *) reswr_alloc (vvd
->length
);
2251 put_16 (big_endian
, 0, vvd
->data
+ 4);
2256 *pp
= unicode_to_bin (vi
->u
.var
.key
, big_endian
);
2257 length
+= (*pp
)->length
;
2258 vilen
+= (*pp
)->length
;
2259 vvlen
+= (*pp
)->length
;
2263 dword_align_bin (&pp
, &length
);
2264 vilen
+= length
- hold
;
2265 vvlen
+= length
- hold
;
2269 for (vv
= vi
->u
.var
.var
; vv
!= NULL
; vv
= vv
->next
)
2271 struct bindata
*vvsd
;
2273 vvsd
= (struct bindata
*) reswr_alloc (sizeof *vvsd
);
2275 vvsd
->data
= (unsigned char *) reswr_alloc (vvsd
->length
);
2282 put_16 (big_endian
, vv
->language
, vvsd
->data
);
2283 put_16 (big_endian
, vv
->charset
, vvsd
->data
+ 2);
2290 put_16 (big_endian
, vvlen
, vvd
->data
);
2291 put_16 (big_endian
, vvvlen
, vvd
->data
+ 2);
2297 put_16 (big_endian
, vilen
, vid
->data
);
2300 put_16 (big_endian
, length
, first
->data
);
2305 /* Convert a generic resource to binary. */
2307 static struct bindata
*
2308 res_to_bin_generic (unsigned long length
, const unsigned char *data
)
2312 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2314 d
->data
= (unsigned char *) data
;