1 /* resbin.c -- manipulate the Windows binary resource format.
2 Copyright 1997 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
);
476 if (version
!= 0xffff)
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);
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
+ 18);
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);
588 dc
->id
= get_16 (big_endian
, data
+ off
+ 8);
592 sublen
= get_resid (&dc
->class, data
+ off
, length
- off
, big_endian
);
595 sublen
= get_resid (&dc
->text
, data
+ off
, length
- off
, big_endian
);
598 if (length
< off
+ 2)
599 toosmall (_("dialog control end"));
601 datalen
= get_16 (big_endian
, data
+ off
);
608 off
= (off
+ 3) &~ 3;
610 if (length
< off
+ datalen
)
611 toosmall (_("dialog control data"));
613 dc
->data
= ((struct rcdata_item
*)
614 res_alloc (sizeof (struct rcdata_item
)));
615 dc
->data
->next
= NULL
;
616 dc
->data
->type
= RCDATA_BUFFER
;
617 dc
->data
->u
.buffer
.length
= datalen
;
618 dc
->data
->u
.buffer
.data
= data
+ off
;
628 r
= (struct res_resource
*) res_alloc (sizeof *r
);
629 r
->type
= RES_TYPE_DIALOG
;
635 /* Convert a stringtable resource from binary. */
637 static struct res_resource
*
638 bin_to_res_string (data
, length
, big_endian
)
639 const unsigned char *data
;
640 unsigned long length
;
643 struct stringtable
*st
;
645 struct res_resource
*r
;
647 st
= (struct stringtable
*) res_alloc (sizeof *st
);
649 for (i
= 0; i
< 16; i
++)
654 toosmall (_("stringtable string length"));
655 slen
= get_16 (big_endian
, data
);
656 st
->strings
[i
].length
= slen
;
663 if (length
< 2 + 2 * slen
)
664 toosmall (_("stringtable string"));
666 s
= (unichar
*) res_alloc (slen
* sizeof (unichar
));
667 st
->strings
[i
].string
= s
;
669 for (j
= 0; j
< slen
; j
++)
670 s
[j
] = get_16 (big_endian
, data
+ 2 + j
* 2);
673 data
+= 2 + 2 * slen
;
674 length
-= 2 + 2 * slen
;
677 r
= (struct res_resource
*) res_alloc (sizeof *r
);
678 r
->type
= RES_TYPE_STRINGTABLE
;
679 r
->u
.stringtable
= st
;
684 /* Convert a fontdir resource from binary. */
686 static struct res_resource
*
687 bin_to_res_fontdir (data
, length
, big_endian
)
688 const unsigned char *data
;
689 unsigned long length
;
693 struct fontdir
*first
, **pp
;
694 struct res_resource
*r
;
697 toosmall (_("fontdir header"));
699 c
= get_16 (big_endian
, data
);
704 for (i
= 0; i
< c
; i
++)
710 toosmall (_("fontdir"));
712 fd
= (struct fontdir
*) res_alloc (sizeof *fd
);
713 fd
->index
= get_16 (big_endian
, data
);
715 /* To work out the length of the fontdir data, we must get the
716 length of the device name and face name strings, even though
717 we don't store them in the fontdir structure. The
718 documentation says that these are NULL terminated char
719 strings, not Unicode strings. */
723 while (off
< length
&& data
[off
] != '\0')
726 toosmall (_("fontdir device name"));
729 while (off
< length
&& data
[off
] != '\0')
732 toosmall (_("fontdir face name"));
742 /* The documentation does not indicate that any rounding is
749 r
= (struct res_resource
*) res_alloc (sizeof *r
);
750 r
->type
= RES_TYPE_FONTDIR
;
751 r
->u
.fontdir
= first
;
756 /* Convert an accelerators resource from binary. */
758 static struct res_resource
*
759 bin_to_res_accelerators (data
, length
, big_endian
)
760 const unsigned char *data
;
761 unsigned long length
;
764 struct accelerator
*first
, **pp
;
765 struct res_resource
*r
;
772 struct accelerator
*a
;
775 toosmall (_("accelerator"));
777 a
= (struct accelerator
*) res_alloc (sizeof *a
);
779 a
->flags
= get_16 (big_endian
, data
);
780 a
->key
= get_16 (big_endian
, data
+ 2);
781 a
->id
= get_16 (big_endian
, data
+ 4);
787 if ((a
->flags
& ACC_LAST
) != 0)
794 r
= (struct res_resource
*) res_alloc (sizeof *r
);
795 r
->type
= RES_TYPE_ACCELERATOR
;
801 /* Convert an rcdata resource from binary. */
803 static struct res_resource
*
804 bin_to_res_rcdata (data
, length
, big_endian
)
805 const unsigned char *data
;
806 unsigned long length
;
809 struct rcdata_item
*ri
;
810 struct res_resource
*r
;
812 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
815 ri
->type
= RCDATA_BUFFER
;
816 ri
->u
.buffer
.length
= length
;
817 ri
->u
.buffer
.data
= data
;
819 r
= (struct res_resource
*) res_alloc (sizeof *r
);
820 r
->type
= RES_TYPE_RCDATA
;
826 /* Convert a group cursor resource from binary. */
828 static struct res_resource
*
829 bin_to_res_group_cursor (data
, length
, big_endian
)
830 const unsigned char *data
;
831 unsigned long length
;
835 struct group_cursor
*first
, **pp
;
836 struct res_resource
*r
;
839 toosmall (_("group cursor header"));
841 type
= get_16 (big_endian
, data
+ 2);
843 fatal (_("unexpected group cursor type %d"), type
);
845 c
= get_16 (big_endian
, data
+ 4);
853 for (i
= 0; i
< c
; i
++)
855 struct group_cursor
*gc
;
858 toosmall (_("group cursor"));
860 gc
= (struct group_cursor
*) res_alloc (sizeof *gc
);
862 gc
->width
= get_16 (big_endian
, data
);
863 gc
->height
= get_16 (big_endian
, data
+ 2);
864 gc
->planes
= get_16 (big_endian
, data
+ 4);
865 gc
->bits
= get_16 (big_endian
, data
+ 6);
866 gc
->bytes
= get_32 (big_endian
, data
+ 8);
867 gc
->index
= get_16 (big_endian
, data
+ 12);
877 r
= (struct res_resource
*) res_alloc (sizeof *r
);
878 r
->type
= RES_TYPE_GROUP_CURSOR
;
879 r
->u
.group_cursor
= first
;
884 /* Convert a group icon resource from binary. */
886 static struct res_resource
*
887 bin_to_res_group_icon (data
, length
, big_endian
)
888 const unsigned char *data
;
889 unsigned long length
;
893 struct group_icon
*first
, **pp
;
894 struct res_resource
*r
;
897 toosmall (_("group icon header"));
899 type
= get_16 (big_endian
, data
+ 2);
901 fatal (_("unexpected group icon type %d"), type
);
903 c
= get_16 (big_endian
, data
+ 4);
911 for (i
= 0; i
< c
; i
++)
913 struct group_icon
*gi
;
916 toosmall (_("group icon"));
918 gi
= (struct group_icon
*) res_alloc (sizeof *gi
);
921 gi
->height
= data
[1];
922 gi
->colors
= data
[2];
923 gi
->planes
= get_16 (big_endian
, data
+ 4);
924 gi
->bits
= get_16 (big_endian
, data
+ 6);
925 gi
->bytes
= get_32 (big_endian
, data
+ 8);
926 gi
->index
= get_16 (big_endian
, data
+ 12);
936 r
= (struct res_resource
*) res_alloc (sizeof *r
);
937 r
->type
= RES_TYPE_GROUP_ICON
;
938 r
->u
.group_icon
= first
;
943 /* Extract data from a version header. If KEY is not NULL, then the
944 key must be KEY; otherwise, the key is returned in *PKEY. This
945 sets *LEN to the total length, *VALLEN to the value length, *TYPE
946 to the type, and *OFF to the offset to the children. */
949 get_version_header (data
, length
, big_endian
, key
, pkey
, len
, vallen
, type
,
951 const unsigned char *data
;
952 unsigned long length
;
964 *len
= get_16 (big_endian
, data
);
965 *vallen
= get_16 (big_endian
, data
+ 2);
966 *type
= get_16 (big_endian
, data
+ 4);
977 *pkey
= get_unicode (data
, length
, big_endian
, &sublen
);
978 *off
+= sublen
* 2 + 2;
986 if (get_16 (big_endian
, data
) != (unsigned char) *key
)
987 fatal (_("unexpected version string"));
1000 *off
= (*off
+ 3) &~ 3;
1003 /* Convert a version resource from binary. */
1005 static struct res_resource
*
1006 bin_to_res_version (data
, length
, big_endian
)
1007 const unsigned char *data
;
1008 unsigned long length
;
1011 int verlen
, vallen
, type
, off
;
1012 struct fixed_versioninfo
*fi
;
1013 struct ver_info
*first
, **pp
;
1014 struct versioninfo
*v
;
1015 struct res_resource
*r
;
1017 get_version_header (data
, length
, big_endian
, "VS_VERSION_INFO",
1018 (unichar
*) NULL
, &verlen
, &vallen
, &type
, &off
);
1020 if ((unsigned int) verlen
!= length
)
1021 fatal (_("version length %d does not match resource length %lu"),
1025 fatal (_("unexpected version type %d"), type
);
1034 unsigned long signature
, fiv
;
1037 fatal (_("unexpected fixed version information length %d"), vallen
);
1040 toosmall (_("fixed version info"));
1042 signature
= get_32 (big_endian
, data
);
1043 if (signature
!= 0xfeef04bd)
1044 fatal (_("unexpected fixed version signature %lu"), signature
);
1046 fiv
= get_32 (big_endian
, data
+ 4);
1047 if (fiv
!= 0 && fiv
!= 0x10000)
1048 fatal (_("unexpected fixed version info version %lu"), fiv
);
1050 fi
= (struct fixed_versioninfo
*) res_alloc (sizeof *fi
);
1052 fi
->file_version_ms
= get_32 (big_endian
, data
+ 8);
1053 fi
->file_version_ls
= get_32 (big_endian
, data
+ 12);
1054 fi
->product_version_ms
= get_32 (big_endian
, data
+ 16);
1055 fi
->product_version_ls
= get_32 (big_endian
, data
+ 20);
1056 fi
->file_flags_mask
= get_32 (big_endian
, data
+ 24);
1057 fi
->file_flags
= get_32 (big_endian
, data
+ 28);
1058 fi
->file_os
= get_32 (big_endian
, data
+ 32);
1059 fi
->file_type
= get_32 (big_endian
, data
+ 36);
1060 fi
->file_subtype
= get_32 (big_endian
, data
+ 40);
1061 fi
->file_date_ms
= get_32 (big_endian
, data
+ 44);
1062 fi
->file_date_ls
= get_32 (big_endian
, data
+ 48);
1073 struct ver_info
*vi
;
1077 toosmall (_("version var info"));
1079 vi
= (struct ver_info
*) res_alloc (sizeof *vi
);
1081 ch
= get_16 (big_endian
, data
+ 6);
1085 struct ver_stringinfo
**ppvs
;
1087 vi
->type
= VERINFO_STRING
;
1089 get_version_header (data
, length
, big_endian
, "StringFileInfo",
1090 (unichar
*) NULL
, &verlen
, &vallen
, &type
,
1094 fatal (_("unexpected stringfileinfo value length %d"), vallen
);
1099 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1100 &vi
->u
.string
.language
, &verlen
, &vallen
,
1104 fatal (_("unexpected version stringtable value length %d"), vallen
);
1110 vi
->u
.string
.strings
= NULL
;
1111 ppvs
= &vi
->u
.string
.strings
;
1113 /* It's convenient to round verlen to a 4 byte alignment,
1114 since we round the subvariables in the loop. */
1115 verlen
= (verlen
+ 3) &~ 3;
1119 struct ver_stringinfo
*vs
;
1120 int subverlen
, vslen
, valoff
;
1122 vs
= (struct ver_stringinfo
*) res_alloc (sizeof *vs
);
1124 get_version_header (data
, length
, big_endian
,
1125 (const char *) NULL
, &vs
->key
, &subverlen
,
1126 &vallen
, &type
, &off
);
1128 subverlen
= (subverlen
+ 3) &~ 3;
1133 vs
->value
= get_unicode (data
, length
, big_endian
, &vslen
);
1134 valoff
= vslen
* 2 + 2;
1135 valoff
= (valoff
+ 3) &~ 3;
1137 if (off
+ valoff
!= subverlen
)
1138 fatal (_("unexpected version string length %d != %d + %d"),
1139 subverlen
, off
, valoff
);
1148 if (verlen
< subverlen
)
1149 fatal (_("unexpected version string length %d < %d"),
1152 verlen
-= subverlen
;
1157 struct ver_varinfo
**ppvv
;
1159 vi
->type
= VERINFO_VAR
;
1161 get_version_header (data
, length
, big_endian
, "VarFileInfo",
1162 (unichar
*) NULL
, &verlen
, &vallen
, &type
,
1166 fatal (_("unexpected varfileinfo value length %d"), vallen
);
1171 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1172 &vi
->u
.var
.key
, &verlen
, &vallen
, &type
, &off
);
1177 vi
->u
.var
.var
= NULL
;
1178 ppvv
= &vi
->u
.var
.var
;
1182 struct ver_varinfo
*vv
;
1185 toosmall (_("version varfileinfo"));
1187 vv
= (struct ver_varinfo
*) res_alloc (sizeof *vv
);
1189 vv
->language
= get_16 (big_endian
, data
);
1190 vv
->charset
= get_16 (big_endian
, data
+ 2);
1200 fatal (_("unexpected version value length %d"), vallen
);
1206 fatal (_("unexpected version string"));
1213 v
= (struct versioninfo
*) res_alloc (sizeof *v
);
1217 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1218 r
->type
= RES_TYPE_VERSIONINFO
;
1219 r
->u
.versioninfo
= v
;
1224 /* Convert an arbitrary user defined resource from binary. */
1226 static struct res_resource
*
1227 bin_to_res_userdata (data
, length
, big_endian
)
1228 const unsigned char *data
;
1229 unsigned long length
;
1232 struct rcdata_item
*ri
;
1233 struct res_resource
*r
;
1235 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
1238 ri
->type
= RCDATA_BUFFER
;
1239 ri
->u
.buffer
.length
= length
;
1240 ri
->u
.buffer
.data
= data
;
1242 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1243 r
->type
= RES_TYPE_USERDATA
;
1249 /* Macros to swap out values. */
1251 #define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
1252 #define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
1254 /* Local functions used to convert resources to binary format. */
1256 static void dword_align_bin
PARAMS ((struct bindata
***, unsigned long *));
1257 static struct bindata
*resid_to_bin
PARAMS ((struct res_id
, int));
1258 static struct bindata
*unicode_to_bin
PARAMS ((const unichar
*, int));
1259 static struct bindata
*res_to_bin_accelerator
1260 PARAMS ((const struct accelerator
*, int));
1261 static struct bindata
*res_to_bin_cursor
1262 PARAMS ((const struct cursor
*, int));
1263 static struct bindata
*res_to_bin_group_cursor
1264 PARAMS ((const struct group_cursor
*, int));
1265 static struct bindata
*res_to_bin_dialog
1266 PARAMS ((const struct dialog
*, int));
1267 static struct bindata
*res_to_bin_fontdir
1268 PARAMS ((const struct fontdir
*, int));
1269 static struct bindata
*res_to_bin_group_icon
1270 PARAMS ((const struct group_icon
*, int));
1271 static struct bindata
*res_to_bin_menu
1272 PARAMS ((const struct menu
*, int));
1273 static struct bindata
*res_to_bin_menuitems
1274 PARAMS ((const struct menuitem
*, int));
1275 static struct bindata
*res_to_bin_menuexitems
1276 PARAMS ((const struct menuitem
*, int));
1277 static struct bindata
*res_to_bin_rcdata
1278 PARAMS ((const struct rcdata_item
*, int));
1279 static struct bindata
*res_to_bin_stringtable
1280 PARAMS ((const struct stringtable
*, int));
1281 static struct bindata
*string_to_unicode_bin
PARAMS ((const char *, int));
1282 static struct bindata
*res_to_bin_versioninfo
1283 PARAMS ((const struct versioninfo
*, int));
1284 static struct bindata
*res_to_bin_generic
1285 PARAMS ((unsigned long, const unsigned char *));
1287 /* Convert a resource to binary. */
1290 res_to_bin (res
, big_endian
)
1291 const struct res_resource
*res
;
1298 case RES_TYPE_BITMAP
:
1301 case RES_TYPE_MESSAGETABLE
:
1302 return res_to_bin_generic (res
->u
.data
.length
, res
->u
.data
.data
);
1303 case RES_TYPE_ACCELERATOR
:
1304 return res_to_bin_accelerator (res
->u
.acc
, big_endian
);
1305 case RES_TYPE_CURSOR
:
1306 return res_to_bin_cursor (res
->u
.cursor
, big_endian
);
1307 case RES_TYPE_GROUP_CURSOR
:
1308 return res_to_bin_group_cursor (res
->u
.group_cursor
, big_endian
);
1309 case RES_TYPE_DIALOG
:
1310 return res_to_bin_dialog (res
->u
.dialog
, big_endian
);
1311 case RES_TYPE_FONTDIR
:
1312 return res_to_bin_fontdir (res
->u
.fontdir
, big_endian
);
1313 case RES_TYPE_GROUP_ICON
:
1314 return res_to_bin_group_icon (res
->u
.group_icon
, big_endian
);
1316 return res_to_bin_menu (res
->u
.menu
, big_endian
);
1317 case RES_TYPE_RCDATA
:
1318 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1319 case RES_TYPE_STRINGTABLE
:
1320 return res_to_bin_stringtable (res
->u
.stringtable
, big_endian
);
1321 case RES_TYPE_USERDATA
:
1322 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1323 case RES_TYPE_VERSIONINFO
:
1324 return res_to_bin_versioninfo (res
->u
.versioninfo
, big_endian
);
1328 /* Align to a 32 bit boundary. PPP points to the of a list of bindata
1329 structures. LENGTH points to the length of the structures. If
1330 necessary, this adds a new bindata to bring length up to a 32 bit
1331 boundary. It updates *PPP and *LENGTH. */
1334 dword_align_bin (ppp
, length
)
1335 struct bindata
***ppp
;
1336 unsigned long *length
;
1341 if ((*length
& 3) == 0)
1344 add
= 4 - (*length
& 3);
1346 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1348 d
->data
= (unsigned char *) reswr_alloc (add
);
1349 memset (d
->data
, 0, add
);
1353 *ppp
= &(**ppp
)->next
;
1358 /* Convert a resource ID to binary. This always returns exactly one
1359 bindata structure. */
1361 static struct bindata
*
1362 resid_to_bin (id
, big_endian
)
1368 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1373 d
->data
= (unsigned char *) reswr_alloc (4);
1374 put_16 (big_endian
, 0xffff, d
->data
);
1375 put_16 (big_endian
, id
.u
.id
, d
->data
+ 2);
1381 d
->length
= id
.u
.n
.length
* 2 + 2;
1382 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1383 for (i
= 0; i
< id
.u
.n
.length
; i
++)
1384 put_16 (big_endian
, id
.u
.n
.name
[i
], d
->data
+ i
* 2);
1385 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1393 /* Convert a null terminated unicode string to binary. This always
1394 returns exactly one bindata structure. */
1396 static struct bindata
*
1397 unicode_to_bin (str
, big_endian
)
1409 for (s
= str
; *s
!= 0; s
++)
1413 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1414 d
->length
= len
* 2 + 2;
1415 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1418 put_16 (big_endian
, 0, d
->data
);
1424 for (s
= str
, i
= 0; *s
!= 0; s
++, i
++)
1425 put_16 (big_endian
, *s
, d
->data
+ i
* 2);
1426 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1434 /* Convert an accelerator resource to binary. */
1436 static struct bindata
*
1437 res_to_bin_accelerator (accelerators
, big_endian
)
1438 const struct accelerator
*accelerators
;
1441 struct bindata
*first
, **pp
;
1442 const struct accelerator
*a
;
1447 for (a
= accelerators
; a
!= NULL
; a
= a
->next
)
1451 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1453 d
->data
= (unsigned char *) reswr_alloc (8);
1456 a
->flags
| (a
->next
!= NULL
? 0 : ACC_LAST
),
1458 put_16 (big_endian
, a
->key
, d
->data
+ 2);
1459 put_16 (big_endian
, a
->id
, d
->data
+ 4);
1460 put_16 (big_endian
, 0, d
->data
+ 8);
1470 /* Convert a cursor resource to binary. */
1472 static struct bindata
*
1473 res_to_bin_cursor (c
, big_endian
)
1474 const struct cursor
*c
;
1479 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1481 d
->data
= (unsigned char *) reswr_alloc (4);
1483 put_16 (big_endian
, c
->xhotspot
, d
->data
);
1484 put_16 (big_endian
, c
->yhotspot
, d
->data
+ 2);
1486 d
->next
= (struct bindata
*) reswr_alloc (sizeof *d
);
1487 d
->next
->length
= c
->length
;
1488 d
->next
->data
= (unsigned char *) c
->data
;
1489 d
->next
->next
= NULL
;
1494 /* Convert a group cursor resource to binary. */
1496 static struct bindata
*
1497 res_to_bin_group_cursor (group_cursors
, big_endian
)
1498 const struct group_cursor
*group_cursors
;
1501 struct bindata
*first
, **pp
;
1503 const struct group_cursor
*gc
;
1505 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1507 first
->data
= (unsigned char *) reswr_alloc (6);
1509 put_16 (big_endian
, 0, first
->data
);
1510 put_16 (big_endian
, 2, first
->data
+ 2);
1516 for (gc
= group_cursors
; gc
!= NULL
; gc
= gc
->next
)
1522 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1524 d
->data
= (unsigned char *) reswr_alloc (14);
1526 put_16 (big_endian
, gc
->width
, d
->data
);
1527 put_16 (big_endian
, gc
->height
, d
->data
+ 2);
1528 put_16 (big_endian
, gc
->planes
, d
->data
+ 4);
1529 put_16 (big_endian
, gc
->bits
, d
->data
+ 6);
1530 put_32 (big_endian
, gc
->bytes
, d
->data
+ 8);
1531 put_16 (big_endian
, gc
->index
, d
->data
+ 12);
1538 put_16 (big_endian
, c
, first
->data
+ 4);
1543 /* Convert a dialog resource to binary. */
1545 static struct bindata
*
1546 res_to_bin_dialog (dialog
, big_endian
)
1547 const struct dialog
*dialog
;
1551 struct bindata
*first
, **pp
;
1552 unsigned long length
;
1554 struct dialog_control
*dc
;
1556 dialogex
= extended_dialog (dialog
);
1558 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1559 first
->length
= dialogex
? 26 : 18;
1560 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1562 length
= first
->length
;
1566 put_32 (big_endian
, dialog
->style
, first
->data
);
1567 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 4);
1572 put_16 (big_endian
, 0xffff, first
->data
);
1573 put_16 (big_endian
, 1, first
->data
+ 2);
1574 if (dialog
->ex
== NULL
)
1575 put_32 (big_endian
, 0, first
->data
+ 4);
1577 put_32 (big_endian
, dialog
->ex
->help
, first
->data
+ 4);
1578 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 8);
1579 put_32 (big_endian
, dialog
->style
, first
->data
+ 12);
1583 put_16 (big_endian
, dialog
->x
, first
->data
+ off
+ 2);
1584 put_16 (big_endian
, dialog
->y
, first
->data
+ off
+ 4);
1585 put_16 (big_endian
, dialog
->width
, first
->data
+ off
+ 6);
1586 put_16 (big_endian
, dialog
->height
, first
->data
+ off
+ 8);
1590 *pp
= resid_to_bin (dialog
->menu
, big_endian
);
1591 length
+= (*pp
)->length
;
1594 *pp
= resid_to_bin (dialog
->class, big_endian
);
1595 length
+= (*pp
)->length
;
1598 *pp
= unicode_to_bin (dialog
->caption
, big_endian
);
1599 length
+= (*pp
)->length
;
1602 if ((dialog
->style
& DS_SETFONT
) != 0)
1606 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1607 d
->length
= dialogex
? 6 : 2;
1608 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1610 length
+= d
->length
;
1612 put_16 (big_endian
, dialog
->pointsize
, d
->data
);
1616 if (dialog
->ex
== NULL
)
1618 put_16 (big_endian
, 0, d
->data
+ 2);
1619 put_16 (big_endian
, 0, d
->data
+ 4);
1623 put_16 (big_endian
, dialog
->ex
->weight
, d
->data
+ 2);
1624 put_16 (big_endian
, dialog
->ex
->italic
, d
->data
+ 4);
1631 *pp
= unicode_to_bin (dialog
->font
, big_endian
);
1632 length
+= (*pp
)->length
;
1637 for (dc
= dialog
->controls
; dc
!= NULL
; dc
= dc
->next
)
1644 dword_align_bin (&pp
, &length
);
1646 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1647 d
->length
= dialogex
? 22 : 18;
1648 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1650 length
+= d
->length
;
1654 put_32 (big_endian
, dc
->style
, d
->data
);
1655 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1660 put_32 (big_endian
, dc
->help
, d
->data
);
1661 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1662 put_32 (big_endian
, dc
->style
, d
->data
+ 8);
1666 put_16 (big_endian
, dc
->x
, d
->data
+ dcoff
);
1667 put_16 (big_endian
, dc
->y
, d
->data
+ dcoff
+ 2);
1668 put_16 (big_endian
, dc
->width
, d
->data
+ dcoff
+ 4);
1669 put_16 (big_endian
, dc
->height
, d
->data
+ dcoff
+ 6);
1670 put_16 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1675 *pp
= resid_to_bin (dc
->class, big_endian
);
1676 length
+= (*pp
)->length
;
1679 *pp
= resid_to_bin (dc
->text
, big_endian
);
1680 length
+= (*pp
)->length
;
1683 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1685 d
->data
= (unsigned char *) reswr_alloc (2);
1693 if (dc
->data
== NULL
)
1694 put_16 (big_endian
, 0, d
->data
);
1697 unsigned long sublen
;
1699 dword_align_bin (&pp
, &length
);
1701 *pp
= res_to_bin_rcdata (dc
->data
, big_endian
);
1705 sublen
+= (*pp
)->length
;
1709 put_16 (big_endian
, sublen
, d
->data
);
1715 put_16 (big_endian
, c
, first
->data
+ off
);
1720 /* Convert a fontdir resource to binary. */
1722 static struct bindata
*
1723 res_to_bin_fontdir (fontdirs
, big_endian
)
1724 const struct fontdir
*fontdirs
;
1727 struct bindata
*first
, **pp
;
1729 const struct fontdir
*fd
;
1731 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1733 first
->data
= (unsigned char *) reswr_alloc (2);
1739 for (fd
= fontdirs
; fd
!= NULL
; fd
= fd
->next
)
1745 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1747 d
->data
= (unsigned char *) reswr_alloc (2);
1749 put_16 (big_endian
, fd
->index
, d
->data
);
1754 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1755 d
->length
= fd
->length
;
1756 d
->data
= (unsigned char *) fd
->data
;
1763 put_16 (big_endian
, c
, first
->data
);
1768 /* Convert a group icon resource to binary. */
1770 static struct bindata
*
1771 res_to_bin_group_icon (group_icons
, big_endian
)
1772 const struct group_icon
*group_icons
;
1775 struct bindata
*first
, **pp
;
1777 const struct group_icon
*gi
;
1779 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1781 first
->data
= (unsigned char *) reswr_alloc (6);
1783 put_16 (big_endian
, 0, first
->data
);
1784 put_16 (big_endian
, 1, first
->data
+ 2);
1790 for (gi
= group_icons
; gi
!= NULL
; gi
= gi
->next
)
1796 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1798 d
->data
= (unsigned char *) reswr_alloc (14);
1800 d
->data
[0] = gi
->width
;
1801 d
->data
[1] = gi
->height
;
1802 d
->data
[2] = gi
->colors
;
1804 put_16 (big_endian
, gi
->planes
, d
->data
+ 4);
1805 put_16 (big_endian
, gi
->bits
, d
->data
+ 6);
1806 put_32 (big_endian
, gi
->bytes
, d
->data
+ 8);
1807 put_16 (big_endian
, gi
->index
, d
->data
+ 12);
1814 put_16 (big_endian
, c
, first
->data
+ 4);
1819 /* Convert a menu resource to binary. */
1821 static struct bindata
*
1822 res_to_bin_menu (menu
, big_endian
)
1823 const struct menu
*menu
;
1829 menuex
= extended_menu (menu
);
1831 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1832 d
->length
= menuex
? 8 : 4;
1833 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1837 put_16 (big_endian
, 0, d
->data
);
1838 put_16 (big_endian
, 0, d
->data
+ 2);
1840 d
->next
= res_to_bin_menuitems (menu
->items
, big_endian
);
1844 put_16 (big_endian
, 1, d
->data
);
1845 put_16 (big_endian
, 4, d
->data
+ 2);
1846 put_32 (big_endian
, menu
->help
, d
->data
+ 4);
1848 d
->next
= res_to_bin_menuexitems (menu
->items
, big_endian
);
1854 /* Convert menu items to binary. */
1856 static struct bindata
*
1857 res_to_bin_menuitems (items
, big_endian
)
1858 const struct menuitem
*items
;
1861 struct bindata
*first
, **pp
;
1862 const struct menuitem
*mi
;
1867 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1872 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1873 d
->length
= mi
->popup
== NULL
? 4 : 2;
1874 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1877 if (mi
->next
== NULL
)
1878 flags
|= MENUITEM_ENDMENU
;
1879 if (mi
->popup
!= NULL
)
1880 flags
|= MENUITEM_POPUP
;
1882 put_16 (big_endian
, flags
, d
->data
);
1884 if (mi
->popup
== NULL
)
1885 put_16 (big_endian
, mi
->id
, d
->data
+ 2);
1890 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1893 if (mi
->popup
!= NULL
)
1895 *pp
= res_to_bin_menuitems (mi
->popup
, big_endian
);
1904 /* Convert menuex items to binary. */
1906 static struct bindata
*
1907 res_to_bin_menuexitems (items
, big_endian
)
1908 const struct menuitem
*items
;
1911 struct bindata
*first
, **pp
;
1912 unsigned long length
;
1913 const struct menuitem
*mi
;
1920 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1925 dword_align_bin (&pp
, &length
);
1927 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1929 d
->data
= (unsigned char *) reswr_alloc (12);
1933 put_32 (big_endian
, mi
->type
, d
->data
);
1934 put_32 (big_endian
, mi
->state
, d
->data
+ 4);
1935 put_16 (big_endian
, mi
->id
, d
->data
+ 8);
1938 if (mi
->next
== NULL
)
1940 if (mi
->popup
!= NULL
)
1942 put_16 (big_endian
, flags
, d
->data
+ 10);
1947 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1948 length
+= (*pp
)->length
;
1951 if (mi
->popup
!= NULL
)
1953 dword_align_bin (&pp
, &length
);
1955 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1957 d
->data
= (unsigned char *) reswr_alloc (4);
1959 put_32 (big_endian
, mi
->help
, d
->data
);
1964 *pp
= res_to_bin_menuexitems (mi
->popup
, big_endian
);
1967 length
+= (*pp
)->length
;
1976 /* Convert an rcdata resource to binary. This is also used to convert
1977 other information which happens to be stored in rcdata_item lists
1980 static struct bindata
*
1981 res_to_bin_rcdata (items
, big_endian
)
1982 const struct rcdata_item
*items
;
1985 struct bindata
*first
, **pp
;
1986 const struct rcdata_item
*ri
;
1991 for (ri
= items
; ri
!= NULL
; ri
= ri
->next
)
1995 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2004 d
->data
= (unsigned char *) reswr_alloc (2);
2005 put_16 (big_endian
, ri
->u
.word
, d
->data
);
2010 d
->data
= (unsigned char *) reswr_alloc (4);
2011 put_32 (big_endian
, ri
->u
.dword
, d
->data
);
2015 d
->length
= ri
->u
.string
.length
;
2016 d
->data
= (unsigned char *) ri
->u
.string
.s
;
2019 case RCDATA_WSTRING
:
2023 d
->length
= ri
->u
.wstring
.length
* 2;
2024 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2025 for (i
= 0; i
< ri
->u
.wstring
.length
; i
++)
2026 put_16 (big_endian
, ri
->u
.wstring
.w
[i
], d
->data
+ i
* 2);
2031 d
->length
= ri
->u
.buffer
.length
;
2032 d
->data
= (unsigned char *) ri
->u
.buffer
.data
;
2044 /* Convert a stringtable resource to binary. */
2046 static struct bindata
*
2047 res_to_bin_stringtable (st
, big_endian
)
2048 const struct stringtable
*st
;
2051 struct bindata
*first
, **pp
;
2057 for (i
= 0; i
< 16; i
++)
2063 slen
= st
->strings
[i
].length
;
2064 s
= st
->strings
[i
].string
;
2066 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2067 d
->length
= 2 + slen
* 2;
2068 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2070 put_16 (big_endian
, slen
, d
->data
);
2072 for (j
= 0; j
< slen
; j
++)
2073 put_16 (big_endian
, s
[j
], d
->data
+ 2 + j
* 2);
2083 /* Convert an ASCII string to a unicode binary string. This always
2084 returns exactly one bindata structure. */
2086 static struct bindata
*
2087 string_to_unicode_bin (s
, big_endian
)
2096 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2097 d
->length
= len
* 2 + 2;
2098 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2100 for (i
= 0; i
< len
; i
++)
2101 put_16 (big_endian
, s
[i
], d
->data
+ i
* 2);
2102 put_16 (big_endian
, 0, d
->data
+ i
* 2);
2109 /* Convert a versioninfo resource to binary. */
2111 static struct bindata
*
2112 res_to_bin_versioninfo (versioninfo
, big_endian
)
2113 const struct versioninfo
*versioninfo
;
2116 struct bindata
*first
, **pp
;
2117 unsigned long length
;
2118 struct ver_info
*vi
;
2120 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
2122 first
->data
= (unsigned char *) reswr_alloc (6);
2126 if (versioninfo
->fixed
== NULL
)
2127 put_16 (big_endian
, 0, first
->data
+ 2);
2129 put_16 (big_endian
, 52, first
->data
+ 2);
2131 put_16 (big_endian
, 0, first
->data
+ 4);
2135 *pp
= string_to_unicode_bin ("VS_VERSION_INFO", big_endian
);
2136 length
+= (*pp
)->length
;
2139 dword_align_bin (&pp
, &length
);
2141 if (versioninfo
->fixed
!= NULL
)
2143 const struct fixed_versioninfo
*fi
;
2146 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2148 d
->data
= (unsigned char *) reswr_alloc (52);
2152 fi
= versioninfo
->fixed
;
2154 put_32 (big_endian
, 0xfeef04bd, d
->data
);
2155 put_32 (big_endian
, 0x10000, d
->data
+ 4);
2156 put_32 (big_endian
, fi
->file_version_ms
, d
->data
+ 8);
2157 put_32 (big_endian
, fi
->file_version_ls
, d
->data
+ 12);
2158 put_32 (big_endian
, fi
->product_version_ms
, d
->data
+ 16);
2159 put_32 (big_endian
, fi
->product_version_ls
, d
->data
+ 20);
2160 put_32 (big_endian
, fi
->file_flags_mask
, d
->data
+ 24);
2161 put_32 (big_endian
, fi
->file_flags
, d
->data
+ 28);
2162 put_32 (big_endian
, fi
->file_os
, d
->data
+ 32);
2163 put_32 (big_endian
, fi
->file_type
, d
->data
+ 36);
2164 put_32 (big_endian
, fi
->file_subtype
, d
->data
+ 40);
2165 put_32 (big_endian
, fi
->file_date_ms
, d
->data
+ 44);
2166 put_32 (big_endian
, fi
->file_date_ls
, d
->data
+ 48);
2173 for (vi
= versioninfo
->var
; vi
!= NULL
; vi
= vi
->next
)
2175 struct bindata
*vid
;
2176 unsigned long vilen
;
2178 dword_align_bin (&pp
, &length
);
2180 vid
= (struct bindata
*) reswr_alloc (sizeof *vid
);
2182 vid
->data
= (unsigned char *) reswr_alloc (6);
2187 put_16 (big_endian
, 0, vid
->data
+ 2);
2188 put_16 (big_endian
, 0, vid
->data
+ 4);
2198 case VERINFO_STRING
:
2200 unsigned long hold
, vslen
;
2201 struct bindata
*vsd
;
2202 const struct ver_stringinfo
*vs
;
2204 *pp
= string_to_unicode_bin ("StringFileInfo", big_endian
);
2205 length
+= (*pp
)->length
;
2206 vilen
+= (*pp
)->length
;
2210 dword_align_bin (&pp
, &length
);
2211 vilen
+= length
- hold
;
2213 vsd
= (struct bindata
*) reswr_alloc (sizeof *vsd
);
2215 vsd
->data
= (unsigned char *) reswr_alloc (6);
2221 put_16 (big_endian
, 0, vsd
->data
+ 2);
2222 put_16 (big_endian
, 0, vsd
->data
+ 4);
2227 *pp
= unicode_to_bin (vi
->u
.string
.language
, big_endian
);
2228 length
+= (*pp
)->length
;
2229 vilen
+= (*pp
)->length
;
2230 vslen
+= (*pp
)->length
;
2233 for (vs
= vi
->u
.string
.strings
; vs
!= NULL
; vs
= vs
->next
)
2235 struct bindata
*vssd
;
2236 unsigned long vsslen
;
2239 dword_align_bin (&pp
, &length
);
2240 vilen
+= length
- hold
;
2241 vslen
+= length
- hold
;
2243 vssd
= (struct bindata
*) reswr_alloc (sizeof *vssd
);
2245 vssd
->data
= (unsigned char *) reswr_alloc (6);
2252 put_16 (big_endian
, 0, vssd
->data
+ 2);
2253 put_16 (big_endian
, 1, vssd
->data
+ 4);
2258 *pp
= unicode_to_bin (vs
->key
, big_endian
);
2259 length
+= (*pp
)->length
;
2260 vilen
+= (*pp
)->length
;
2261 vslen
+= (*pp
)->length
;
2262 vsslen
+= (*pp
)->length
;
2266 dword_align_bin (&pp
, &length
);
2267 vilen
+= length
- hold
;
2268 vslen
+= length
- hold
;
2269 vsslen
+= length
- hold
;
2271 *pp
= unicode_to_bin (vs
->value
, big_endian
);
2272 length
+= (*pp
)->length
;
2273 vilen
+= (*pp
)->length
;
2274 vslen
+= (*pp
)->length
;
2275 vsslen
+= (*pp
)->length
;
2278 put_16 (big_endian
, vsslen
, vssd
->data
);
2281 put_16 (big_endian
, vslen
, vsd
->data
);
2288 unsigned long hold
, vvlen
, vvvlen
;
2289 struct bindata
*vvd
;
2290 const struct ver_varinfo
*vv
;
2292 *pp
= string_to_unicode_bin ("VarFileInfo", big_endian
);
2293 length
+= (*pp
)->length
;
2294 vilen
+= (*pp
)->length
;
2298 dword_align_bin (&pp
, &length
);
2299 vilen
+= length
- hold
;
2301 vvd
= (struct bindata
*) reswr_alloc (sizeof *vvd
);
2303 vvd
->data
= (unsigned char *) reswr_alloc (6);
2309 put_16 (big_endian
, 0, vvd
->data
+ 4);
2314 *pp
= unicode_to_bin (vi
->u
.var
.key
, big_endian
);
2315 length
+= (*pp
)->length
;
2316 vilen
+= (*pp
)->length
;
2317 vvlen
+= (*pp
)->length
;
2321 dword_align_bin (&pp
, &length
);
2322 vilen
+= length
- hold
;
2323 vvlen
+= length
- hold
;
2327 for (vv
= vi
->u
.var
.var
; vv
!= NULL
; vv
= vv
->next
)
2329 struct bindata
*vvsd
;
2331 vvsd
= (struct bindata
*) reswr_alloc (sizeof *vvsd
);
2333 vvsd
->data
= (unsigned char *) reswr_alloc (4);
2340 put_16 (big_endian
, vv
->language
, vvsd
->data
);
2341 put_16 (big_endian
, vv
->charset
, vvsd
->data
+ 2);
2348 put_16 (big_endian
, vvlen
, vvd
->data
);
2349 put_16 (big_endian
, vvvlen
, vvd
->data
+ 2);
2355 put_16 (big_endian
, vilen
, vid
->data
);
2358 put_16 (big_endian
, length
, first
->data
);
2363 /* Convert a generic resource to binary. */
2365 static struct bindata
*
2366 res_to_bin_generic (length
, data
)
2367 unsigned long length
;
2368 const unsigned char *data
;
2372 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2374 d
->data
= (unsigned char *) data
;
This page took 0.084527 seconds and 4 git commands to generate.