1 /* resbin.c -- manipulate the Windows binary resource format.
2 Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 /* This file contains functions to convert between the binary resource
23 format and the internal structures that we want to use. The same
24 binary resource format is used in both res and COFF files. */
28 #include "libiberty.h"
31 /* Macros to swap in values. */
33 #define get_16(be, s) ((be) ? bfd_getb16 (s) : bfd_getl16 (s))
34 #define get_32(be, s) ((be) ? bfd_getb32 (s) : bfd_getl32 (s))
36 /* Local functions. */
38 static void toosmall
PARAMS ((const char *));
39 static unichar
*get_unicode
40 PARAMS ((const unsigned char *, unsigned long, int, int *));
42 PARAMS ((struct res_id
*, const unsigned char *, unsigned long, int));
43 static struct res_resource
*bin_to_res_generic
44 PARAMS ((enum res_type
, const unsigned char *, unsigned long));
45 static struct res_resource
*bin_to_res_cursor
46 PARAMS ((const unsigned char *, unsigned long, int));
47 static struct res_resource
*bin_to_res_menu
48 PARAMS ((const unsigned char *, unsigned long, int));
49 static struct menuitem
*bin_to_res_menuitems
50 PARAMS ((const unsigned char *, unsigned long, int, int *));
51 static struct menuitem
*bin_to_res_menuexitems
52 PARAMS ((const unsigned char *, unsigned long, int, int *));
53 static struct res_resource
*bin_to_res_dialog
54 PARAMS ((const unsigned char *, unsigned long, int));
55 static struct res_resource
*bin_to_res_string
56 PARAMS ((const unsigned char *, unsigned long, int));
57 static struct res_resource
*bin_to_res_fontdir
58 PARAMS ((const unsigned char *, unsigned long, int));
59 static struct res_resource
*bin_to_res_accelerators
60 PARAMS ((const unsigned char *, unsigned long, int));
61 static struct res_resource
*bin_to_res_rcdata
62 PARAMS ((const unsigned char *, unsigned long, int));
63 static struct res_resource
*bin_to_res_group_cursor
64 PARAMS ((const unsigned char *, unsigned long, int));
65 static struct res_resource
*bin_to_res_group_icon
66 PARAMS ((const unsigned char *, unsigned long, int));
67 static struct res_resource
*bin_to_res_version
68 PARAMS ((const unsigned char *, unsigned long, int));
69 static struct res_resource
*bin_to_res_userdata
70 PARAMS ((const unsigned char *, unsigned long, int));
72 /* Given a resource type ID, a pointer to data, a length, return a
73 res_resource structure which represents that resource. The caller
74 is responsible for initializing the res_info and coff_info fields
75 of the returned structure. */
78 bin_to_res (type
, data
, length
, big_endian
)
80 const unsigned char *data
;
85 return bin_to_res_userdata (data
, length
, big_endian
);
91 return bin_to_res_userdata (data
, length
, big_endian
);
93 return bin_to_res_cursor (data
, length
, big_endian
);
95 return bin_to_res_generic (RES_TYPE_BITMAP
, data
, length
);
97 return bin_to_res_generic (RES_TYPE_ICON
, data
, length
);
99 return bin_to_res_menu (data
, length
, big_endian
);
101 return bin_to_res_dialog (data
, length
, big_endian
);
103 return bin_to_res_string (data
, length
, big_endian
);
105 return bin_to_res_fontdir (data
, length
, big_endian
);
107 return bin_to_res_generic (RES_TYPE_FONT
, data
, length
);
109 return bin_to_res_accelerators (data
, length
, big_endian
);
111 return bin_to_res_rcdata (data
, length
, big_endian
);
112 case RT_MESSAGETABLE
:
113 return bin_to_res_generic (RES_TYPE_MESSAGETABLE
, data
, length
);
114 case RT_GROUP_CURSOR
:
115 return bin_to_res_group_cursor (data
, length
, big_endian
);
117 return bin_to_res_group_icon (data
, length
, big_endian
);
119 return bin_to_res_version (data
, length
, big_endian
);
124 /* Give an error if the binary data is too small. */
130 fatal (_("%s: not enough binary data"), msg
);
133 /* Swap in a NULL terminated unicode string. */
136 get_unicode (data
, length
, big_endian
, retlen
)
137 const unsigned char *data
;
138 unsigned long length
;
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 (id
, data
, length
, big_endian
)
172 const unsigned char *data
;
173 unsigned long length
;
179 toosmall (_("resource ID"));
181 first
= get_16 (big_endian
, data
);
185 toosmall (_("resource ID"));
187 id
->u
.id
= get_16 (big_endian
, data
+ 2);
193 id
->u
.n
.name
= get_unicode (data
, length
, big_endian
, &id
->u
.n
.length
);
194 return id
->u
.n
.length
* 2 + 2;
198 /* Convert a resource which just stores uninterpreted data from
201 struct res_resource
*
202 bin_to_res_generic (type
, data
, length
)
204 const unsigned char *data
;
205 unsigned long length
;
207 struct res_resource
*r
;
209 r
= (struct res_resource
*) res_alloc (sizeof *r
);
211 r
->u
.data
.data
= data
;
212 r
->u
.data
.length
= length
;
217 /* Convert a cursor resource from binary. */
219 struct res_resource
*
220 bin_to_res_cursor (data
, length
, big_endian
)
221 const unsigned char *data
;
222 unsigned long length
;
226 struct res_resource
*r
;
229 toosmall (_("cursor"));
231 c
= (struct cursor
*) res_alloc (sizeof *c
);
232 c
->xhotspot
= get_16 (big_endian
, data
);
233 c
->yhotspot
= get_16 (big_endian
, data
+ 2);
234 c
->length
= length
- 4;
237 r
= (struct res_resource
*) res_alloc (sizeof *r
);
238 r
->type
= RES_TYPE_CURSOR
;
244 /* Convert a menu resource from binary. */
246 struct res_resource
*
247 bin_to_res_menu (data
, length
, big_endian
)
248 const unsigned char *data
;
249 unsigned long length
;
252 struct res_resource
*r
;
256 r
= (struct res_resource
*) res_alloc (sizeof *r
);
257 r
->type
= RES_TYPE_MENU
;
259 m
= (struct menu
*) res_alloc (sizeof *m
);
263 toosmall (_("menu header"));
265 version
= get_16 (big_endian
, data
);
270 toosmall (_("menu header"));
272 m
->items
= bin_to_res_menuitems (data
+ 4, length
- 4, big_endian
,
275 else if (version
== 1)
280 toosmall (_("menuex header"));
281 m
->help
= get_32 (big_endian
, data
+ 4);
282 offset
= get_16 (big_endian
, data
+ 2);
283 if (offset
+ 4 >= length
)
284 toosmall (_("menuex offset"));
285 m
->items
= bin_to_res_menuexitems (data
+ 4 + offset
,
286 length
- (4 + offset
),
291 fatal (_("unsupported menu version %d"), version
);
296 /* Convert menu items from binary. */
298 static struct menuitem
*
299 bin_to_res_menuitems (data
, length
, big_endian
, read
)
300 const unsigned char *data
;
301 unsigned long length
;
305 struct menuitem
*first
, **pp
;
314 int flags
, slen
, itemlen
;
319 toosmall (_("menuitem header"));
321 mi
= (struct menuitem
*) res_alloc (sizeof *mi
);
325 flags
= get_16 (big_endian
, data
);
326 mi
->type
= flags
&~ (MENUITEM_POPUP
| MENUITEM_ENDMENU
);
328 if ((flags
& MENUITEM_POPUP
) == 0)
333 if (length
< stroff
+ 2)
334 toosmall (_("menuitem header"));
336 if (get_16 (big_endian
, data
+ stroff
) == 0)
342 mi
->text
= get_unicode (data
+ stroff
, length
- stroff
, big_endian
,
345 itemlen
= stroff
+ slen
* 2 + 2;
347 if ((flags
& MENUITEM_POPUP
) == 0)
350 mi
->id
= get_16 (big_endian
, data
+ 2);
357 mi
->popup
= bin_to_res_menuitems (data
+ itemlen
, length
- itemlen
,
358 big_endian
, &subread
);
370 if ((flags
& MENUITEM_ENDMENU
) != 0)
377 /* Convert menuex items from binary. */
379 static struct menuitem
*
380 bin_to_res_menuexitems (data
, length
, big_endian
, read
)
381 const unsigned char *data
;
382 unsigned long length
;
386 struct menuitem
*first
, **pp
;
396 unsigned int itemlen
;
400 toosmall (_("menuitem header"));
402 mi
= (struct menuitem
*) res_alloc (sizeof *mi
);
403 mi
->type
= get_32 (big_endian
, data
);
404 mi
->state
= get_32 (big_endian
, data
+ 4);
405 mi
->id
= get_16 (big_endian
, data
+ 8);
407 flags
= get_16 (big_endian
, data
+ 10);
409 if (get_16 (big_endian
, data
+ 12) == 0)
415 mi
->text
= get_unicode (data
+ 12, length
- 12, big_endian
, &slen
);
417 itemlen
= 12 + slen
* 2 + 2;
418 itemlen
= (itemlen
+ 3) &~ 3;
420 if ((flags
& 1) == 0)
429 if (length
< itemlen
+ 4)
430 toosmall (_("menuitem"));
431 mi
->help
= get_32 (big_endian
, data
+ itemlen
);
434 mi
->popup
= bin_to_res_menuexitems (data
+ itemlen
,
436 big_endian
, &subread
);
448 if ((flags
& 0x80) != 0)
455 /* Convert a dialog resource from binary. */
457 static struct res_resource
*
458 bin_to_res_dialog (data
, length
, big_endian
)
459 const unsigned char *data
;
460 unsigned long length
;
467 struct dialog_control
**pp
;
468 struct res_resource
*r
;
471 toosmall (_("dialog header"));
473 d
= (struct dialog
*) res_alloc (sizeof *d
);
475 version
= get_16 (big_endian
, data
);
479 d
->style
= get_32 (big_endian
, data
);
480 d
->exstyle
= get_32 (big_endian
, data
+ 4);
487 signature
= get_16 (big_endian
, data
+ 2);
488 if (signature
!= 0xffff)
489 fatal (_("unexpected dialog signature %d"), signature
);
491 d
->ex
= (struct dialog_ex
*) res_alloc (sizeof (struct dialog_ex
));
492 d
->ex
->help
= get_32 (big_endian
, data
+ 4);
493 d
->exstyle
= get_32 (big_endian
, data
+ 8);
494 d
->style
= get_32 (big_endian
, data
+ 12);
498 if (length
< off
+ 10)
499 toosmall (_("dialog header"));
501 c
= get_16 (big_endian
, data
+ off
);
502 d
->x
= get_16 (big_endian
, data
+ off
+ 2);
503 d
->y
= get_16 (big_endian
, data
+ off
+ 4);
504 d
->width
= get_16 (big_endian
, data
+ off
+ 6);
505 d
->height
= get_16 (big_endian
, data
+ off
+ 8);
509 sublen
= get_resid (&d
->menu
, data
+ off
, length
- off
, big_endian
);
512 sublen
= get_resid (&d
->class, data
+ off
, length
- off
, big_endian
);
515 d
->caption
= get_unicode (data
+ off
, length
- off
, big_endian
, &sublen
);
516 off
+= sublen
* 2 + 2;
518 if ((d
->style
& DS_SETFONT
) == 0)
530 if (length
< off
+ 2)
531 toosmall (_("dialog font point size"));
533 d
->pointsize
= get_16 (big_endian
, data
+ off
);
538 if (length
< off
+ 4)
539 toosmall (_("dialogex font information"));
540 d
->ex
->weight
= get_16 (big_endian
, data
+ off
);
541 d
->ex
->italic
= get_16 (big_endian
, data
+ off
+ 2);
545 d
->font
= get_unicode (data
+ off
, length
- off
, big_endian
, &sublen
);
546 off
+= sublen
* 2 + 2;
552 for (i
= 0; i
< c
; i
++)
554 struct dialog_control
*dc
;
557 off
= (off
+ 3) &~ 3;
559 dc
= (struct dialog_control
*) res_alloc (sizeof *dc
);
563 if (length
< off
+ 8)
564 toosmall (_("dialog control"));
566 dc
->style
= get_32 (big_endian
, data
+ off
);
567 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
573 if (length
< off
+ 12)
574 toosmall (_("dialogex control"));
575 dc
->help
= get_32 (big_endian
, data
+ off
);
576 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
577 dc
->style
= get_32 (big_endian
, data
+ off
+ 8);
581 if (length
< off
+ 10)
582 toosmall (_("dialog control"));
584 dc
->x
= get_16 (big_endian
, data
+ off
);
585 dc
->y
= get_16 (big_endian
, data
+ off
+ 2);
586 dc
->width
= get_16 (big_endian
, data
+ off
+ 4);
587 dc
->height
= get_16 (big_endian
, data
+ off
+ 6);
590 dc
->id
= get_32 (big_endian
, data
+ off
+ 8);
592 dc
->id
= get_16 (big_endian
, data
+ off
+ 8);
594 off
+= 10 + (d
->ex
!= NULL
? 2 : 0);
596 sublen
= get_resid (&dc
->class, data
+ off
, length
- off
, big_endian
);
599 sublen
= get_resid (&dc
->text
, data
+ off
, length
- off
, big_endian
);
602 if (length
< off
+ 2)
603 toosmall (_("dialog control end"));
605 datalen
= get_16 (big_endian
, data
+ off
);
612 off
= (off
+ 3) &~ 3;
614 if (length
< off
+ datalen
)
615 toosmall (_("dialog control data"));
617 dc
->data
= ((struct rcdata_item
*)
618 res_alloc (sizeof (struct rcdata_item
)));
619 dc
->data
->next
= NULL
;
620 dc
->data
->type
= RCDATA_BUFFER
;
621 dc
->data
->u
.buffer
.length
= datalen
;
622 dc
->data
->u
.buffer
.data
= data
+ off
;
632 r
= (struct res_resource
*) res_alloc (sizeof *r
);
633 r
->type
= RES_TYPE_DIALOG
;
639 /* Convert a stringtable resource from binary. */
641 static struct res_resource
*
642 bin_to_res_string (data
, length
, big_endian
)
643 const unsigned char *data
;
644 unsigned long length
;
647 struct stringtable
*st
;
649 struct res_resource
*r
;
651 st
= (struct stringtable
*) res_alloc (sizeof *st
);
653 for (i
= 0; i
< 16; i
++)
658 toosmall (_("stringtable string length"));
659 slen
= get_16 (big_endian
, data
);
660 st
->strings
[i
].length
= slen
;
667 if (length
< 2 + 2 * slen
)
668 toosmall (_("stringtable string"));
670 s
= (unichar
*) res_alloc (slen
* sizeof (unichar
));
671 st
->strings
[i
].string
= s
;
673 for (j
= 0; j
< slen
; j
++)
674 s
[j
] = get_16 (big_endian
, data
+ 2 + j
* 2);
677 data
+= 2 + 2 * slen
;
678 length
-= 2 + 2 * slen
;
681 r
= (struct res_resource
*) res_alloc (sizeof *r
);
682 r
->type
= RES_TYPE_STRINGTABLE
;
683 r
->u
.stringtable
= st
;
688 /* Convert a fontdir resource from binary. */
690 static struct res_resource
*
691 bin_to_res_fontdir (data
, length
, big_endian
)
692 const unsigned char *data
;
693 unsigned long length
;
697 struct fontdir
*first
, **pp
;
698 struct res_resource
*r
;
701 toosmall (_("fontdir header"));
703 c
= get_16 (big_endian
, data
);
708 for (i
= 0; i
< c
; i
++)
714 toosmall (_("fontdir"));
716 fd
= (struct fontdir
*) res_alloc (sizeof *fd
);
717 fd
->index
= get_16 (big_endian
, data
);
719 /* To work out the length of the fontdir data, we must get the
720 length of the device name and face name strings, even though
721 we don't store them in the fontdir structure. The
722 documentation says that these are NULL terminated char
723 strings, not Unicode strings. */
727 while (off
< length
&& data
[off
] != '\0')
730 toosmall (_("fontdir device name"));
733 while (off
< length
&& data
[off
] != '\0')
736 toosmall (_("fontdir face name"));
746 /* The documentation does not indicate that any rounding is
753 r
= (struct res_resource
*) res_alloc (sizeof *r
);
754 r
->type
= RES_TYPE_FONTDIR
;
755 r
->u
.fontdir
= first
;
760 /* Convert an accelerators resource from binary. */
762 static struct res_resource
*
763 bin_to_res_accelerators (data
, length
, big_endian
)
764 const unsigned char *data
;
765 unsigned long length
;
768 struct accelerator
*first
, **pp
;
769 struct res_resource
*r
;
776 struct accelerator
*a
;
779 toosmall (_("accelerator"));
781 a
= (struct accelerator
*) res_alloc (sizeof *a
);
783 a
->flags
= get_16 (big_endian
, data
);
784 a
->key
= get_16 (big_endian
, data
+ 2);
785 a
->id
= get_16 (big_endian
, data
+ 4);
791 if ((a
->flags
& ACC_LAST
) != 0)
798 r
= (struct res_resource
*) res_alloc (sizeof *r
);
799 r
->type
= RES_TYPE_ACCELERATOR
;
805 /* Convert an rcdata resource from binary. */
807 static struct res_resource
*
808 bin_to_res_rcdata (data
, length
, big_endian
)
809 const unsigned char *data
;
810 unsigned long length
;
813 struct rcdata_item
*ri
;
814 struct res_resource
*r
;
816 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
819 ri
->type
= RCDATA_BUFFER
;
820 ri
->u
.buffer
.length
= length
;
821 ri
->u
.buffer
.data
= data
;
823 r
= (struct res_resource
*) res_alloc (sizeof *r
);
824 r
->type
= RES_TYPE_RCDATA
;
830 /* Convert a group cursor resource from binary. */
832 static struct res_resource
*
833 bin_to_res_group_cursor (data
, length
, big_endian
)
834 const unsigned char *data
;
835 unsigned long length
;
839 struct group_cursor
*first
, **pp
;
840 struct res_resource
*r
;
843 toosmall (_("group cursor header"));
845 type
= get_16 (big_endian
, data
+ 2);
847 fatal (_("unexpected group cursor type %d"), type
);
849 c
= get_16 (big_endian
, data
+ 4);
857 for (i
= 0; i
< c
; i
++)
859 struct group_cursor
*gc
;
862 toosmall (_("group cursor"));
864 gc
= (struct group_cursor
*) res_alloc (sizeof *gc
);
866 gc
->width
= get_16 (big_endian
, data
);
867 gc
->height
= get_16 (big_endian
, data
+ 2);
868 gc
->planes
= get_16 (big_endian
, data
+ 4);
869 gc
->bits
= get_16 (big_endian
, data
+ 6);
870 gc
->bytes
= get_32 (big_endian
, data
+ 8);
871 gc
->index
= get_16 (big_endian
, data
+ 12);
881 r
= (struct res_resource
*) res_alloc (sizeof *r
);
882 r
->type
= RES_TYPE_GROUP_CURSOR
;
883 r
->u
.group_cursor
= first
;
888 /* Convert a group icon resource from binary. */
890 static struct res_resource
*
891 bin_to_res_group_icon (data
, length
, big_endian
)
892 const unsigned char *data
;
893 unsigned long length
;
897 struct group_icon
*first
, **pp
;
898 struct res_resource
*r
;
901 toosmall (_("group icon header"));
903 type
= get_16 (big_endian
, data
+ 2);
905 fatal (_("unexpected group icon type %d"), type
);
907 c
= get_16 (big_endian
, data
+ 4);
915 for (i
= 0; i
< c
; i
++)
917 struct group_icon
*gi
;
920 toosmall (_("group icon"));
922 gi
= (struct group_icon
*) res_alloc (sizeof *gi
);
925 gi
->height
= data
[1];
926 gi
->colors
= data
[2];
927 gi
->planes
= get_16 (big_endian
, data
+ 4);
928 gi
->bits
= get_16 (big_endian
, data
+ 6);
929 gi
->bytes
= get_32 (big_endian
, data
+ 8);
930 gi
->index
= get_16 (big_endian
, data
+ 12);
940 r
= (struct res_resource
*) res_alloc (sizeof *r
);
941 r
->type
= RES_TYPE_GROUP_ICON
;
942 r
->u
.group_icon
= first
;
947 /* Extract data from a version header. If KEY is not NULL, then the
948 key must be KEY; otherwise, the key is returned in *PKEY. This
949 sets *LEN to the total length, *VALLEN to the value length, *TYPE
950 to the type, and *OFF to the offset to the children. */
953 get_version_header (data
, length
, big_endian
, key
, pkey
, len
, vallen
, type
,
955 const unsigned char *data
;
956 unsigned long length
;
968 *len
= get_16 (big_endian
, data
);
969 *vallen
= get_16 (big_endian
, data
+ 2);
970 *type
= get_16 (big_endian
, data
+ 4);
981 *pkey
= get_unicode (data
, length
, big_endian
, &sublen
);
982 *off
+= sublen
* 2 + 2;
990 if (get_16 (big_endian
, data
) != (unsigned char) *key
)
991 fatal (_("unexpected version string"));
1004 *off
= (*off
+ 3) &~ 3;
1007 /* Convert a version resource from binary. */
1009 static struct res_resource
*
1010 bin_to_res_version (data
, length
, big_endian
)
1011 const unsigned char *data
;
1012 unsigned long length
;
1015 int verlen
, vallen
, type
, off
;
1016 struct fixed_versioninfo
*fi
;
1017 struct ver_info
*first
, **pp
;
1018 struct versioninfo
*v
;
1019 struct res_resource
*r
;
1021 get_version_header (data
, length
, big_endian
, "VS_VERSION_INFO",
1022 (unichar
*) NULL
, &verlen
, &vallen
, &type
, &off
);
1024 if ((unsigned int) verlen
!= length
)
1025 fatal (_("version length %d does not match resource length %lu"),
1029 fatal (_("unexpected version type %d"), type
);
1038 unsigned long signature
, fiv
;
1041 fatal (_("unexpected fixed version information length %d"), vallen
);
1044 toosmall (_("fixed version info"));
1046 signature
= get_32 (big_endian
, data
);
1047 if (signature
!= 0xfeef04bd)
1048 fatal (_("unexpected fixed version signature %lu"), signature
);
1050 fiv
= get_32 (big_endian
, data
+ 4);
1051 if (fiv
!= 0 && fiv
!= 0x10000)
1052 fatal (_("unexpected fixed version info version %lu"), fiv
);
1054 fi
= (struct fixed_versioninfo
*) res_alloc (sizeof *fi
);
1056 fi
->file_version_ms
= get_32 (big_endian
, data
+ 8);
1057 fi
->file_version_ls
= get_32 (big_endian
, data
+ 12);
1058 fi
->product_version_ms
= get_32 (big_endian
, data
+ 16);
1059 fi
->product_version_ls
= get_32 (big_endian
, data
+ 20);
1060 fi
->file_flags_mask
= get_32 (big_endian
, data
+ 24);
1061 fi
->file_flags
= get_32 (big_endian
, data
+ 28);
1062 fi
->file_os
= get_32 (big_endian
, data
+ 32);
1063 fi
->file_type
= get_32 (big_endian
, data
+ 36);
1064 fi
->file_subtype
= get_32 (big_endian
, data
+ 40);
1065 fi
->file_date_ms
= get_32 (big_endian
, data
+ 44);
1066 fi
->file_date_ls
= get_32 (big_endian
, data
+ 48);
1077 struct ver_info
*vi
;
1081 toosmall (_("version var info"));
1083 vi
= (struct ver_info
*) res_alloc (sizeof *vi
);
1085 ch
= get_16 (big_endian
, data
+ 6);
1089 struct ver_stringinfo
**ppvs
;
1091 vi
->type
= VERINFO_STRING
;
1093 get_version_header (data
, length
, big_endian
, "StringFileInfo",
1094 (unichar
*) NULL
, &verlen
, &vallen
, &type
,
1098 fatal (_("unexpected stringfileinfo value length %d"), vallen
);
1103 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1104 &vi
->u
.string
.language
, &verlen
, &vallen
,
1108 fatal (_("unexpected version stringtable value length %d"), vallen
);
1114 vi
->u
.string
.strings
= NULL
;
1115 ppvs
= &vi
->u
.string
.strings
;
1117 /* It's convenient to round verlen to a 4 byte alignment,
1118 since we round the subvariables in the loop. */
1119 verlen
= (verlen
+ 3) &~ 3;
1123 struct ver_stringinfo
*vs
;
1124 int subverlen
, vslen
, valoff
;
1126 vs
= (struct ver_stringinfo
*) res_alloc (sizeof *vs
);
1128 get_version_header (data
, length
, big_endian
,
1129 (const char *) NULL
, &vs
->key
, &subverlen
,
1130 &vallen
, &type
, &off
);
1132 subverlen
= (subverlen
+ 3) &~ 3;
1137 vs
->value
= get_unicode (data
, length
, big_endian
, &vslen
);
1138 valoff
= vslen
* 2 + 2;
1139 valoff
= (valoff
+ 3) &~ 3;
1141 if (off
+ valoff
!= subverlen
)
1142 fatal (_("unexpected version string length %d != %d + %d"),
1143 subverlen
, off
, valoff
);
1152 if (verlen
< subverlen
)
1153 fatal (_("unexpected version string length %d < %d"),
1156 verlen
-= subverlen
;
1161 struct ver_varinfo
**ppvv
;
1163 vi
->type
= VERINFO_VAR
;
1165 get_version_header (data
, length
, big_endian
, "VarFileInfo",
1166 (unichar
*) NULL
, &verlen
, &vallen
, &type
,
1170 fatal (_("unexpected varfileinfo value length %d"), vallen
);
1175 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1176 &vi
->u
.var
.key
, &verlen
, &vallen
, &type
, &off
);
1181 vi
->u
.var
.var
= NULL
;
1182 ppvv
= &vi
->u
.var
.var
;
1186 struct ver_varinfo
*vv
;
1189 toosmall (_("version varfileinfo"));
1191 vv
= (struct ver_varinfo
*) res_alloc (sizeof *vv
);
1193 vv
->language
= get_16 (big_endian
, data
);
1194 vv
->charset
= get_16 (big_endian
, data
+ 2);
1204 fatal (_("unexpected version value length %d"), vallen
);
1210 fatal (_("unexpected version string"));
1217 v
= (struct versioninfo
*) res_alloc (sizeof *v
);
1221 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1222 r
->type
= RES_TYPE_VERSIONINFO
;
1223 r
->u
.versioninfo
= v
;
1228 /* Convert an arbitrary user defined resource from binary. */
1230 static struct res_resource
*
1231 bin_to_res_userdata (data
, length
, big_endian
)
1232 const unsigned char *data
;
1233 unsigned long length
;
1236 struct rcdata_item
*ri
;
1237 struct res_resource
*r
;
1239 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
1242 ri
->type
= RCDATA_BUFFER
;
1243 ri
->u
.buffer
.length
= length
;
1244 ri
->u
.buffer
.data
= data
;
1246 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1247 r
->type
= RES_TYPE_USERDATA
;
1253 /* Macros to swap out values. */
1255 #define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
1256 #define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
1258 /* Local functions used to convert resources to binary format. */
1260 static void dword_align_bin
PARAMS ((struct bindata
***, unsigned long *));
1261 static struct bindata
*resid_to_bin
PARAMS ((struct res_id
, int));
1262 static struct bindata
*unicode_to_bin
PARAMS ((const unichar
*, int));
1263 static struct bindata
*res_to_bin_accelerator
1264 PARAMS ((const struct accelerator
*, int));
1265 static struct bindata
*res_to_bin_cursor
1266 PARAMS ((const struct cursor
*, int));
1267 static struct bindata
*res_to_bin_group_cursor
1268 PARAMS ((const struct group_cursor
*, int));
1269 static struct bindata
*res_to_bin_dialog
1270 PARAMS ((const struct dialog
*, int));
1271 static struct bindata
*res_to_bin_fontdir
1272 PARAMS ((const struct fontdir
*, int));
1273 static struct bindata
*res_to_bin_group_icon
1274 PARAMS ((const struct group_icon
*, int));
1275 static struct bindata
*res_to_bin_menu
1276 PARAMS ((const struct menu
*, int));
1277 static struct bindata
*res_to_bin_menuitems
1278 PARAMS ((const struct menuitem
*, int));
1279 static struct bindata
*res_to_bin_menuexitems
1280 PARAMS ((const struct menuitem
*, int));
1281 static struct bindata
*res_to_bin_rcdata
1282 PARAMS ((const struct rcdata_item
*, int));
1283 static struct bindata
*res_to_bin_stringtable
1284 PARAMS ((const struct stringtable
*, int));
1285 static struct bindata
*string_to_unicode_bin
PARAMS ((const char *, int));
1286 static struct bindata
*res_to_bin_versioninfo
1287 PARAMS ((const struct versioninfo
*, int));
1288 static struct bindata
*res_to_bin_generic
1289 PARAMS ((unsigned long, const unsigned char *));
1291 /* Convert a resource to binary. */
1294 res_to_bin (res
, big_endian
)
1295 const struct res_resource
*res
;
1302 case RES_TYPE_BITMAP
:
1305 case RES_TYPE_MESSAGETABLE
:
1306 return res_to_bin_generic (res
->u
.data
.length
, res
->u
.data
.data
);
1307 case RES_TYPE_ACCELERATOR
:
1308 return res_to_bin_accelerator (res
->u
.acc
, big_endian
);
1309 case RES_TYPE_CURSOR
:
1310 return res_to_bin_cursor (res
->u
.cursor
, big_endian
);
1311 case RES_TYPE_GROUP_CURSOR
:
1312 return res_to_bin_group_cursor (res
->u
.group_cursor
, big_endian
);
1313 case RES_TYPE_DIALOG
:
1314 return res_to_bin_dialog (res
->u
.dialog
, big_endian
);
1315 case RES_TYPE_FONTDIR
:
1316 return res_to_bin_fontdir (res
->u
.fontdir
, big_endian
);
1317 case RES_TYPE_GROUP_ICON
:
1318 return res_to_bin_group_icon (res
->u
.group_icon
, big_endian
);
1320 return res_to_bin_menu (res
->u
.menu
, big_endian
);
1321 case RES_TYPE_RCDATA
:
1322 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1323 case RES_TYPE_STRINGTABLE
:
1324 return res_to_bin_stringtable (res
->u
.stringtable
, big_endian
);
1325 case RES_TYPE_USERDATA
:
1326 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1327 case RES_TYPE_VERSIONINFO
:
1328 return res_to_bin_versioninfo (res
->u
.versioninfo
, big_endian
);
1332 /* Align to a 32 bit boundary. PPP points to the of a list of bindata
1333 structures. LENGTH points to the length of the structures. If
1334 necessary, this adds a new bindata to bring length up to a 32 bit
1335 boundary. It updates *PPP and *LENGTH. */
1338 dword_align_bin (ppp
, length
)
1339 struct bindata
***ppp
;
1340 unsigned long *length
;
1345 if ((*length
& 3) == 0)
1348 add
= 4 - (*length
& 3);
1350 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1352 d
->data
= (unsigned char *) reswr_alloc (add
);
1353 memset (d
->data
, 0, add
);
1357 *ppp
= &(**ppp
)->next
;
1362 /* Convert a resource ID to binary. This always returns exactly one
1363 bindata structure. */
1365 static struct bindata
*
1366 resid_to_bin (id
, big_endian
)
1372 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1377 d
->data
= (unsigned char *) reswr_alloc (4);
1378 put_16 (big_endian
, 0xffff, d
->data
);
1379 put_16 (big_endian
, id
.u
.id
, d
->data
+ 2);
1385 d
->length
= id
.u
.n
.length
* 2 + 2;
1386 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1387 for (i
= 0; i
< id
.u
.n
.length
; i
++)
1388 put_16 (big_endian
, id
.u
.n
.name
[i
], d
->data
+ i
* 2);
1389 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1397 /* Convert a null terminated unicode string to binary. This always
1398 returns exactly one bindata structure. */
1400 static struct bindata
*
1401 unicode_to_bin (str
, big_endian
)
1413 for (s
= str
; *s
!= 0; s
++)
1417 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1418 d
->length
= len
* 2 + 2;
1419 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1422 put_16 (big_endian
, 0, d
->data
);
1428 for (s
= str
, i
= 0; *s
!= 0; s
++, i
++)
1429 put_16 (big_endian
, *s
, d
->data
+ i
* 2);
1430 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1438 /* Convert an accelerator resource to binary. */
1440 static struct bindata
*
1441 res_to_bin_accelerator (accelerators
, big_endian
)
1442 const struct accelerator
*accelerators
;
1445 struct bindata
*first
, **pp
;
1446 const struct accelerator
*a
;
1451 for (a
= accelerators
; a
!= NULL
; a
= a
->next
)
1455 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1457 d
->data
= (unsigned char *) reswr_alloc (8);
1460 a
->flags
| (a
->next
!= NULL
? 0 : ACC_LAST
),
1462 put_16 (big_endian
, a
->key
, d
->data
+ 2);
1463 put_16 (big_endian
, a
->id
, d
->data
+ 4);
1464 put_16 (big_endian
, 0, d
->data
+ 8);
1474 /* Convert a cursor resource to binary. */
1476 static struct bindata
*
1477 res_to_bin_cursor (c
, big_endian
)
1478 const struct cursor
*c
;
1483 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1485 d
->data
= (unsigned char *) reswr_alloc (4);
1487 put_16 (big_endian
, c
->xhotspot
, d
->data
);
1488 put_16 (big_endian
, c
->yhotspot
, d
->data
+ 2);
1490 d
->next
= (struct bindata
*) reswr_alloc (sizeof *d
);
1491 d
->next
->length
= c
->length
;
1492 d
->next
->data
= (unsigned char *) c
->data
;
1493 d
->next
->next
= NULL
;
1498 /* Convert a group cursor resource to binary. */
1500 static struct bindata
*
1501 res_to_bin_group_cursor (group_cursors
, big_endian
)
1502 const struct group_cursor
*group_cursors
;
1505 struct bindata
*first
, **pp
;
1507 const struct group_cursor
*gc
;
1509 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1511 first
->data
= (unsigned char *) reswr_alloc (6);
1513 put_16 (big_endian
, 0, first
->data
);
1514 put_16 (big_endian
, 2, first
->data
+ 2);
1520 for (gc
= group_cursors
; gc
!= NULL
; gc
= gc
->next
)
1526 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1528 d
->data
= (unsigned char *) reswr_alloc (14);
1530 put_16 (big_endian
, gc
->width
, d
->data
);
1531 put_16 (big_endian
, gc
->height
, d
->data
+ 2);
1532 put_16 (big_endian
, gc
->planes
, d
->data
+ 4);
1533 put_16 (big_endian
, gc
->bits
, d
->data
+ 6);
1534 put_32 (big_endian
, gc
->bytes
, d
->data
+ 8);
1535 put_16 (big_endian
, gc
->index
, d
->data
+ 12);
1542 put_16 (big_endian
, c
, first
->data
+ 4);
1547 /* Convert a dialog resource to binary. */
1549 static struct bindata
*
1550 res_to_bin_dialog (dialog
, big_endian
)
1551 const struct dialog
*dialog
;
1555 struct bindata
*first
, **pp
;
1556 unsigned long length
;
1558 struct dialog_control
*dc
;
1560 dialogex
= extended_dialog (dialog
);
1562 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1563 first
->length
= dialogex
? 26 : 18;
1564 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1566 length
= first
->length
;
1570 put_32 (big_endian
, dialog
->style
, first
->data
);
1571 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 4);
1576 put_16 (big_endian
, 1, first
->data
);
1577 put_16 (big_endian
, 0xffff, first
->data
+ 2);
1579 if (dialog
->ex
== NULL
)
1580 put_32 (big_endian
, 0, first
->data
+ 4);
1582 put_32 (big_endian
, dialog
->ex
->help
, first
->data
+ 4);
1583 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 8);
1584 put_32 (big_endian
, dialog
->style
, first
->data
+ 12);
1588 put_16 (big_endian
, dialog
->x
, first
->data
+ off
+ 2);
1589 put_16 (big_endian
, dialog
->y
, first
->data
+ off
+ 4);
1590 put_16 (big_endian
, dialog
->width
, first
->data
+ off
+ 6);
1591 put_16 (big_endian
, dialog
->height
, first
->data
+ off
+ 8);
1595 *pp
= resid_to_bin (dialog
->menu
, big_endian
);
1596 length
+= (*pp
)->length
;
1599 *pp
= resid_to_bin (dialog
->class, big_endian
);
1600 length
+= (*pp
)->length
;
1603 *pp
= unicode_to_bin (dialog
->caption
, big_endian
);
1604 length
+= (*pp
)->length
;
1607 if ((dialog
->style
& DS_SETFONT
) != 0)
1611 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1612 d
->length
= dialogex
? 6 : 2;
1613 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1615 length
+= d
->length
;
1617 put_16 (big_endian
, dialog
->pointsize
, d
->data
);
1621 if (dialog
->ex
== NULL
)
1623 put_16 (big_endian
, 0, d
->data
+ 2);
1624 put_16 (big_endian
, 0, d
->data
+ 4);
1628 put_16 (big_endian
, dialog
->ex
->weight
, d
->data
+ 2);
1629 put_16 (big_endian
, dialog
->ex
->italic
, d
->data
+ 4);
1636 *pp
= unicode_to_bin (dialog
->font
, big_endian
);
1637 length
+= (*pp
)->length
;
1642 for (dc
= dialog
->controls
; dc
!= NULL
; dc
= dc
->next
)
1649 dword_align_bin (&pp
, &length
);
1651 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1652 d
->length
= dialogex
? 24 : 18;
1653 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1655 length
+= d
->length
;
1659 put_32 (big_endian
, dc
->style
, d
->data
);
1660 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1665 put_32 (big_endian
, dc
->help
, d
->data
);
1666 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1667 put_32 (big_endian
, dc
->style
, d
->data
+ 8);
1671 put_16 (big_endian
, dc
->x
, d
->data
+ dcoff
);
1672 put_16 (big_endian
, dc
->y
, d
->data
+ dcoff
+ 2);
1673 put_16 (big_endian
, dc
->width
, d
->data
+ dcoff
+ 4);
1674 put_16 (big_endian
, dc
->height
, d
->data
+ dcoff
+ 6);
1677 put_32 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1679 put_16 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1684 *pp
= resid_to_bin (dc
->class, big_endian
);
1685 length
+= (*pp
)->length
;
1688 *pp
= resid_to_bin (dc
->text
, big_endian
);
1689 length
+= (*pp
)->length
;
1692 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1694 d
->data
= (unsigned char *) reswr_alloc (2);
1702 if (dc
->data
== NULL
)
1703 put_16 (big_endian
, 0, d
->data
);
1706 unsigned long sublen
;
1708 dword_align_bin (&pp
, &length
);
1710 *pp
= res_to_bin_rcdata (dc
->data
, big_endian
);
1714 sublen
+= (*pp
)->length
;
1718 put_16 (big_endian
, sublen
, d
->data
);
1723 put_16 (big_endian
, c
, first
->data
+ off
);
1728 /* Convert a fontdir resource to binary. */
1730 static struct bindata
*
1731 res_to_bin_fontdir (fontdirs
, big_endian
)
1732 const struct fontdir
*fontdirs
;
1735 struct bindata
*first
, **pp
;
1737 const struct fontdir
*fd
;
1739 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1741 first
->data
= (unsigned char *) reswr_alloc (2);
1747 for (fd
= fontdirs
; fd
!= NULL
; fd
= fd
->next
)
1753 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1755 d
->data
= (unsigned char *) reswr_alloc (2);
1757 put_16 (big_endian
, fd
->index
, d
->data
);
1762 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1763 d
->length
= fd
->length
;
1764 d
->data
= (unsigned char *) fd
->data
;
1771 put_16 (big_endian
, c
, first
->data
);
1776 /* Convert a group icon resource to binary. */
1778 static struct bindata
*
1779 res_to_bin_group_icon (group_icons
, big_endian
)
1780 const struct group_icon
*group_icons
;
1783 struct bindata
*first
, **pp
;
1785 const struct group_icon
*gi
;
1787 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1789 first
->data
= (unsigned char *) reswr_alloc (6);
1791 put_16 (big_endian
, 0, first
->data
);
1792 put_16 (big_endian
, 1, first
->data
+ 2);
1798 for (gi
= group_icons
; gi
!= NULL
; gi
= gi
->next
)
1804 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1806 d
->data
= (unsigned char *) reswr_alloc (14);
1808 d
->data
[0] = gi
->width
;
1809 d
->data
[1] = gi
->height
;
1810 d
->data
[2] = gi
->colors
;
1812 put_16 (big_endian
, gi
->planes
, d
->data
+ 4);
1813 put_16 (big_endian
, gi
->bits
, d
->data
+ 6);
1814 put_32 (big_endian
, gi
->bytes
, d
->data
+ 8);
1815 put_16 (big_endian
, gi
->index
, d
->data
+ 12);
1822 put_16 (big_endian
, c
, first
->data
+ 4);
1827 /* Convert a menu resource to binary. */
1829 static struct bindata
*
1830 res_to_bin_menu (menu
, big_endian
)
1831 const struct menu
*menu
;
1837 menuex
= extended_menu (menu
);
1839 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1840 d
->length
= menuex
? 8 : 4;
1841 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1845 put_16 (big_endian
, 0, d
->data
);
1846 put_16 (big_endian
, 0, d
->data
+ 2);
1848 d
->next
= res_to_bin_menuitems (menu
->items
, big_endian
);
1852 put_16 (big_endian
, 1, d
->data
);
1853 put_16 (big_endian
, 4, d
->data
+ 2);
1854 put_32 (big_endian
, menu
->help
, d
->data
+ 4);
1856 d
->next
= res_to_bin_menuexitems (menu
->items
, big_endian
);
1862 /* Convert menu items to binary. */
1864 static struct bindata
*
1865 res_to_bin_menuitems (items
, big_endian
)
1866 const struct menuitem
*items
;
1869 struct bindata
*first
, **pp
;
1870 const struct menuitem
*mi
;
1875 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1880 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1881 d
->length
= mi
->popup
== NULL
? 4 : 2;
1882 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1885 if (mi
->next
== NULL
)
1886 flags
|= MENUITEM_ENDMENU
;
1887 if (mi
->popup
!= NULL
)
1888 flags
|= MENUITEM_POPUP
;
1890 put_16 (big_endian
, flags
, d
->data
);
1892 if (mi
->popup
== NULL
)
1893 put_16 (big_endian
, mi
->id
, d
->data
+ 2);
1898 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1901 if (mi
->popup
!= NULL
)
1903 *pp
= res_to_bin_menuitems (mi
->popup
, big_endian
);
1912 /* Convert menuex items to binary. */
1914 static struct bindata
*
1915 res_to_bin_menuexitems (items
, big_endian
)
1916 const struct menuitem
*items
;
1919 struct bindata
*first
, **pp
;
1920 unsigned long length
;
1921 const struct menuitem
*mi
;
1928 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1933 dword_align_bin (&pp
, &length
);
1935 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1937 d
->data
= (unsigned char *) reswr_alloc (12);
1941 put_32 (big_endian
, mi
->type
, d
->data
);
1942 put_32 (big_endian
, mi
->state
, d
->data
+ 4);
1943 put_16 (big_endian
, mi
->id
, d
->data
+ 8);
1946 if (mi
->next
== NULL
)
1948 if (mi
->popup
!= NULL
)
1950 put_16 (big_endian
, flags
, d
->data
+ 10);
1955 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1956 length
+= (*pp
)->length
;
1959 if (mi
->popup
!= NULL
)
1961 dword_align_bin (&pp
, &length
);
1963 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1965 d
->data
= (unsigned char *) reswr_alloc (4);
1967 put_32 (big_endian
, mi
->help
, d
->data
);
1972 *pp
= res_to_bin_menuexitems (mi
->popup
, big_endian
);
1975 length
+= (*pp
)->length
;
1984 /* Convert an rcdata resource to binary. This is also used to convert
1985 other information which happens to be stored in rcdata_item lists
1988 static struct bindata
*
1989 res_to_bin_rcdata (items
, big_endian
)
1990 const struct rcdata_item
*items
;
1993 struct bindata
*first
, **pp
;
1994 const struct rcdata_item
*ri
;
1999 for (ri
= items
; ri
!= NULL
; ri
= ri
->next
)
2003 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2012 d
->data
= (unsigned char *) reswr_alloc (2);
2013 put_16 (big_endian
, ri
->u
.word
, d
->data
);
2018 d
->data
= (unsigned char *) reswr_alloc (4);
2019 put_32 (big_endian
, ri
->u
.dword
, d
->data
);
2023 d
->length
= ri
->u
.string
.length
;
2024 d
->data
= (unsigned char *) ri
->u
.string
.s
;
2027 case RCDATA_WSTRING
:
2031 d
->length
= ri
->u
.wstring
.length
* 2;
2032 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2033 for (i
= 0; i
< ri
->u
.wstring
.length
; i
++)
2034 put_16 (big_endian
, ri
->u
.wstring
.w
[i
], d
->data
+ i
* 2);
2039 d
->length
= ri
->u
.buffer
.length
;
2040 d
->data
= (unsigned char *) ri
->u
.buffer
.data
;
2052 /* Convert a stringtable resource to binary. */
2054 static struct bindata
*
2055 res_to_bin_stringtable (st
, big_endian
)
2056 const struct stringtable
*st
;
2059 struct bindata
*first
, **pp
;
2065 for (i
= 0; i
< 16; i
++)
2071 slen
= st
->strings
[i
].length
;
2072 s
= st
->strings
[i
].string
;
2074 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2075 d
->length
= 2 + slen
* 2;
2076 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2078 put_16 (big_endian
, slen
, d
->data
);
2080 for (j
= 0; j
< slen
; j
++)
2081 put_16 (big_endian
, s
[j
], d
->data
+ 2 + j
* 2);
2091 /* Convert an ASCII string to a unicode binary string. This always
2092 returns exactly one bindata structure. */
2094 static struct bindata
*
2095 string_to_unicode_bin (s
, big_endian
)
2104 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2105 d
->length
= len
* 2 + 2;
2106 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2108 for (i
= 0; i
< len
; i
++)
2109 put_16 (big_endian
, s
[i
], d
->data
+ i
* 2);
2110 put_16 (big_endian
, 0, d
->data
+ i
* 2);
2117 /* Convert a versioninfo resource to binary. */
2119 static struct bindata
*
2120 res_to_bin_versioninfo (versioninfo
, big_endian
)
2121 const struct versioninfo
*versioninfo
;
2124 struct bindata
*first
, **pp
;
2125 unsigned long length
;
2126 struct ver_info
*vi
;
2128 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
2130 first
->data
= (unsigned char *) reswr_alloc (6);
2134 if (versioninfo
->fixed
== NULL
)
2135 put_16 (big_endian
, 0, first
->data
+ 2);
2137 put_16 (big_endian
, 52, first
->data
+ 2);
2139 put_16 (big_endian
, 0, first
->data
+ 4);
2143 *pp
= string_to_unicode_bin ("VS_VERSION_INFO", big_endian
);
2144 length
+= (*pp
)->length
;
2147 dword_align_bin (&pp
, &length
);
2149 if (versioninfo
->fixed
!= NULL
)
2151 const struct fixed_versioninfo
*fi
;
2154 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2156 d
->data
= (unsigned char *) reswr_alloc (52);
2160 fi
= versioninfo
->fixed
;
2162 put_32 (big_endian
, 0xfeef04bd, d
->data
);
2163 put_32 (big_endian
, 0x10000, d
->data
+ 4);
2164 put_32 (big_endian
, fi
->file_version_ms
, d
->data
+ 8);
2165 put_32 (big_endian
, fi
->file_version_ls
, d
->data
+ 12);
2166 put_32 (big_endian
, fi
->product_version_ms
, d
->data
+ 16);
2167 put_32 (big_endian
, fi
->product_version_ls
, d
->data
+ 20);
2168 put_32 (big_endian
, fi
->file_flags_mask
, d
->data
+ 24);
2169 put_32 (big_endian
, fi
->file_flags
, d
->data
+ 28);
2170 put_32 (big_endian
, fi
->file_os
, d
->data
+ 32);
2171 put_32 (big_endian
, fi
->file_type
, d
->data
+ 36);
2172 put_32 (big_endian
, fi
->file_subtype
, d
->data
+ 40);
2173 put_32 (big_endian
, fi
->file_date_ms
, d
->data
+ 44);
2174 put_32 (big_endian
, fi
->file_date_ls
, d
->data
+ 48);
2181 for (vi
= versioninfo
->var
; vi
!= NULL
; vi
= vi
->next
)
2183 struct bindata
*vid
;
2184 unsigned long vilen
;
2186 dword_align_bin (&pp
, &length
);
2188 vid
= (struct bindata
*) reswr_alloc (sizeof *vid
);
2190 vid
->data
= (unsigned char *) reswr_alloc (6);
2195 put_16 (big_endian
, 0, vid
->data
+ 2);
2196 put_16 (big_endian
, 0, vid
->data
+ 4);
2206 case VERINFO_STRING
:
2208 unsigned long hold
, vslen
;
2209 struct bindata
*vsd
;
2210 const struct ver_stringinfo
*vs
;
2212 *pp
= string_to_unicode_bin ("StringFileInfo", big_endian
);
2213 length
+= (*pp
)->length
;
2214 vilen
+= (*pp
)->length
;
2218 dword_align_bin (&pp
, &length
);
2219 vilen
+= length
- hold
;
2221 vsd
= (struct bindata
*) reswr_alloc (sizeof *vsd
);
2223 vsd
->data
= (unsigned char *) reswr_alloc (6);
2229 put_16 (big_endian
, 0, vsd
->data
+ 2);
2230 put_16 (big_endian
, 0, vsd
->data
+ 4);
2235 *pp
= unicode_to_bin (vi
->u
.string
.language
, big_endian
);
2236 length
+= (*pp
)->length
;
2237 vilen
+= (*pp
)->length
;
2238 vslen
+= (*pp
)->length
;
2241 for (vs
= vi
->u
.string
.strings
; vs
!= NULL
; vs
= vs
->next
)
2243 struct bindata
*vssd
;
2244 unsigned long vsslen
;
2247 dword_align_bin (&pp
, &length
);
2248 vilen
+= length
- hold
;
2249 vslen
+= length
- hold
;
2251 vssd
= (struct bindata
*) reswr_alloc (sizeof *vssd
);
2253 vssd
->data
= (unsigned char *) reswr_alloc (6);
2260 put_16 (big_endian
, 1, vssd
->data
+ 4);
2265 *pp
= unicode_to_bin (vs
->key
, big_endian
);
2266 length
+= (*pp
)->length
;
2267 vilen
+= (*pp
)->length
;
2268 vslen
+= (*pp
)->length
;
2269 vsslen
+= (*pp
)->length
;
2273 dword_align_bin (&pp
, &length
);
2274 vilen
+= length
- hold
;
2275 vslen
+= length
- hold
;
2276 vsslen
+= length
- hold
;
2278 *pp
= unicode_to_bin (vs
->value
, big_endian
);
2279 put_16 (big_endian
, (*pp
)->length
/ 2, vssd
->data
+ 2);
2280 length
+= (*pp
)->length
;
2281 vilen
+= (*pp
)->length
;
2282 vslen
+= (*pp
)->length
;
2283 vsslen
+= (*pp
)->length
;
2286 put_16 (big_endian
, vsslen
, vssd
->data
);
2289 put_16 (big_endian
, vslen
, vsd
->data
);
2296 unsigned long hold
, vvlen
, vvvlen
;
2297 struct bindata
*vvd
;
2298 const struct ver_varinfo
*vv
;
2300 *pp
= string_to_unicode_bin ("VarFileInfo", big_endian
);
2301 length
+= (*pp
)->length
;
2302 vilen
+= (*pp
)->length
;
2306 dword_align_bin (&pp
, &length
);
2307 vilen
+= length
- hold
;
2309 vvd
= (struct bindata
*) reswr_alloc (sizeof *vvd
);
2311 vvd
->data
= (unsigned char *) reswr_alloc (6);
2317 put_16 (big_endian
, 0, vvd
->data
+ 4);
2322 *pp
= unicode_to_bin (vi
->u
.var
.key
, big_endian
);
2323 length
+= (*pp
)->length
;
2324 vilen
+= (*pp
)->length
;
2325 vvlen
+= (*pp
)->length
;
2329 dword_align_bin (&pp
, &length
);
2330 vilen
+= length
- hold
;
2331 vvlen
+= length
- hold
;
2335 for (vv
= vi
->u
.var
.var
; vv
!= NULL
; vv
= vv
->next
)
2337 struct bindata
*vvsd
;
2339 vvsd
= (struct bindata
*) reswr_alloc (sizeof *vvsd
);
2341 vvsd
->data
= (unsigned char *) reswr_alloc (4);
2348 put_16 (big_endian
, vv
->language
, vvsd
->data
);
2349 put_16 (big_endian
, vv
->charset
, vvsd
->data
+ 2);
2356 put_16 (big_endian
, vvlen
, vvd
->data
);
2357 put_16 (big_endian
, vvvlen
, vvd
->data
+ 2);
2363 put_16 (big_endian
, vilen
, vid
->data
);
2366 put_16 (big_endian
, length
, first
->data
);
2371 /* Convert a generic resource to binary. */
2373 static struct bindata
*
2374 res_to_bin_generic (length
, data
)
2375 unsigned long length
;
2376 const unsigned char *data
;
2380 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2382 d
->data
= (unsigned char *) data
;
This page took 0.078566 seconds and 4 git commands to generate.