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
);
108 case RT_ACCELERATORS
:
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
< 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
;
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
, stroff
, slen
, itemlen
;
318 toosmall ("menuitem header");
320 mi
= (struct menuitem
*) res_alloc (sizeof *mi
);
324 flags
= get_16 (big_endian
, data
);
327 if ((flags
& MENUITEM_POPUP
) == 0)
332 if (length
< stroff
+ 2)
333 toosmall ("menuitem header");
335 if (get_16 (big_endian
, data
+ stroff
) == 0)
341 mi
->text
= get_unicode (data
+ stroff
, length
- stroff
, big_endian
,
344 itemlen
= stroff
+ slen
* 2 + 2;
346 if ((flags
& MENUITEM_POPUP
) == 0)
349 mi
->id
= get_16 (big_endian
, data
+ 2);
356 mi
->popup
= bin_to_res_menuitems (data
+ itemlen
, length
- itemlen
,
357 big_endian
, &subread
);
369 if ((flags
& MENUITEM_ENDMENU
) != 0)
376 /* Convert menuex items from binary. */
378 static struct menuitem
*
379 bin_to_res_menuexitems (data
, length
, big_endian
, read
)
380 const unsigned char *data
;
381 unsigned long length
;
385 struct menuitem
*first
, **pp
;
394 int flags
, slen
, itemlen
;
398 toosmall ("menuitem header");
400 mi
= (struct menuitem
*) res_alloc (sizeof *mi
);
401 mi
->type
= get_32 (big_endian
, data
);
402 mi
->state
= get_32 (big_endian
, data
+ 4);
403 mi
->id
= get_16 (big_endian
, data
+ 8);
405 flags
= get_16 (big_endian
, data
+ 10);
407 if (get_16 (big_endian
, data
+ 12) == 0)
413 mi
->text
= get_unicode (data
+ 12, length
- 12, big_endian
, &slen
);
415 itemlen
= 12 + slen
* 2 + 2;
416 itemlen
= (itemlen
+ 3) &~ 3;
418 if ((flags
& 1) == 0)
427 if (length
< itemlen
+ 4)
428 toosmall ("menuitem");
429 mi
->help
= get_32 (big_endian
, data
+ itemlen
);
432 mi
->popup
= bin_to_res_menuexitems (data
+ itemlen
,
434 big_endian
, &subread
);
446 if ((flags
& 0x80) != 0)
453 /* Convert a dialog resource from binary. */
455 static struct res_resource
*
456 bin_to_res_dialog (data
, length
, big_endian
)
457 const unsigned char *data
;
458 unsigned long length
;
463 int c
, sublen
, off
, i
;
464 struct dialog_control
**pp
;
465 struct res_resource
*r
;
468 toosmall ("dialog header");
470 d
= (struct dialog
*) res_alloc (sizeof *d
);
472 version
= get_16 (big_endian
, data
);
473 if (version
!= 0xffff)
476 d
->style
= get_32 (big_endian
, data
);
477 d
->exstyle
= get_32 (big_endian
, data
+ 4);
484 signature
= get_16 (big_endian
, data
+ 2);
486 fatal ("unexpected dialog signature %d", signature
);
488 d
->ex
= (struct dialog_ex
*) res_alloc (sizeof (struct dialog_ex
));
489 d
->ex
->help
= get_32 (big_endian
, data
+ 4);
490 d
->exstyle
= get_32 (big_endian
, data
+ 8);
491 d
->style
= get_32 (big_endian
, data
+ 12);
495 if (length
< off
+ 10)
496 toosmall ("dialog header");
498 c
= get_16 (big_endian
, data
+ off
);
499 d
->x
= get_16 (big_endian
, data
+ off
+ 2);
500 d
->y
= get_16 (big_endian
, data
+ off
+ 4);
501 d
->width
= get_16 (big_endian
, data
+ off
+ 6);
502 d
->height
= get_16 (big_endian
, data
+ off
+ 8);
506 sublen
= get_resid (&d
->menu
, data
+ off
, length
- off
, big_endian
);
509 sublen
= get_resid (&d
->class, data
+ off
, length
- off
, big_endian
);
512 d
->caption
= get_unicode (data
+ off
, length
- off
, big_endian
, &sublen
);
513 off
+= sublen
* 2 + 2;
515 if ((d
->style
& DS_SETFONT
) == 0)
527 if (length
< off
+ 2)
528 toosmall ("dialog font point size");
530 d
->pointsize
= get_16 (big_endian
, data
+ off
);
535 if (length
< off
+ 4)
536 toosmall ("dialogex font information");
537 d
->ex
->weight
= get_16 (big_endian
, data
+ off
);
538 d
->ex
->italic
= get_16 (big_endian
, data
+ off
+ 2);
542 d
->font
= get_unicode (data
+ off
, length
- off
, big_endian
, &sublen
);
543 off
+= sublen
* 2 + 2;
549 for (i
= 0; i
< c
; i
++)
551 struct dialog_control
*dc
;
554 off
= (off
+ 3) &~ 3;
556 dc
= (struct dialog_control
*) res_alloc (sizeof *dc
);
560 if (length
< off
+ 8)
561 toosmall ("dialog control");
563 dc
->style
= get_32 (big_endian
, data
+ off
);
564 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
570 if (length
< off
+ 12)
571 toosmall ("dialogex control");
572 dc
->help
= get_32 (big_endian
, data
+ off
);
573 dc
->exstyle
= get_32 (big_endian
, data
+ off
+ 4);
574 dc
->style
= get_32 (big_endian
, data
+ off
+ 18);
578 if (length
< off
+ 10)
579 toosmall ("dialog control");
581 dc
->x
= get_16 (big_endian
, data
+ off
);
582 dc
->y
= get_16 (big_endian
, data
+ off
+ 2);
583 dc
->width
= get_16 (big_endian
, data
+ off
+ 4);
584 dc
->height
= get_16 (big_endian
, data
+ off
+ 6);
585 dc
->id
= get_16 (big_endian
, data
+ off
+ 8);
589 sublen
= get_resid (&dc
->class, data
+ off
, length
- off
, big_endian
);
592 sublen
= get_resid (&dc
->text
, data
+ off
, length
- off
, big_endian
);
595 if (length
< off
+ 2)
596 toosmall ("dialog control end");
598 datalen
= get_16 (big_endian
, data
+ off
);
605 off
= (off
+ 3) &~ 3;
607 if (length
< off
+ datalen
)
608 toosmall ("dialog control data");
610 dc
->data
= ((struct rcdata_item
*)
611 res_alloc (sizeof (struct rcdata_item
)));
612 dc
->data
->next
= NULL
;
613 dc
->data
->type
= RCDATA_BUFFER
;
614 dc
->data
->u
.buffer
.length
= datalen
;
615 dc
->data
->u
.buffer
.data
= data
+ off
;
625 r
= (struct res_resource
*) res_alloc (sizeof *r
);
626 r
->type
= RES_TYPE_DIALOG
;
632 /* Convert a stringtable resource from binary. */
634 static struct res_resource
*
635 bin_to_res_string (data
, length
, big_endian
)
636 const unsigned char *data
;
637 unsigned long length
;
640 struct stringtable
*st
;
642 struct res_resource
*r
;
644 st
= (struct stringtable
*) res_alloc (sizeof *st
);
646 for (i
= 0; i
< 16; i
++)
651 toosmall ("stringtable string length");
652 slen
= get_16 (big_endian
, data
);
653 st
->strings
[i
].length
= slen
;
660 if (length
< 2 + 2 * slen
)
661 toosmall ("stringtable string");
663 s
= (unichar
*) res_alloc (slen
* sizeof (unichar
));
664 st
->strings
[i
].string
= s
;
666 for (j
= 0; j
< slen
; j
++)
667 s
[j
] = get_16 (big_endian
, data
+ 2 + j
* 2);
670 data
+= 2 + 2 * slen
;
671 length
-= 2 + 2 * slen
;
674 r
= (struct res_resource
*) res_alloc (sizeof *r
);
675 r
->type
= RES_TYPE_STRINGTABLE
;
676 r
->u
.stringtable
= st
;
681 /* Convert a fontdir resource from binary. */
683 static struct res_resource
*
684 bin_to_res_fontdir (data
, length
, big_endian
)
685 const unsigned char *data
;
686 unsigned long length
;
690 struct fontdir
*first
, **pp
;
691 struct res_resource
*r
;
694 toosmall ("fontdir header");
696 c
= get_16 (big_endian
, data
);
701 for (i
= 0; i
< c
; i
++)
707 toosmall ("fontdir");
709 fd
= (struct fontdir
*) res_alloc (sizeof *fd
);
710 fd
->index
= get_16 (big_endian
, data
);
712 /* To work out the length of the fontdir data, we must get the
713 length of the device name and face name strings, even though
714 we don't store them in the fontdir structure. The
715 documentation says that these are NULL terminated char
716 strings, not Unicode strings. */
720 while (off
< length
&& data
[off
] != '\0')
723 toosmall ("fontdir device name");
726 while (off
< length
&& data
[off
] != '\0')
729 toosmall ("fontdir face name");
739 /* The documentation does not indicate that any rounding is
746 r
= (struct res_resource
*) res_alloc (sizeof *r
);
747 r
->type
= RES_TYPE_FONTDIR
;
748 r
->u
.fontdir
= first
;
753 /* Convert an accelerators resource from binary. */
755 static struct res_resource
*
756 bin_to_res_accelerators (data
, length
, big_endian
)
757 const unsigned char *data
;
758 unsigned long length
;
761 struct accelerator
*first
, **pp
;
762 struct res_resource
*r
;
769 struct accelerator
*a
;
772 toosmall ("accelerator");
774 a
->flags
= get_16 (big_endian
, data
);
775 a
->key
= get_16 (big_endian
, data
+ 2);
776 a
->id
= get_16 (big_endian
, data
+ 4);
782 if ((a
->flags
& ACC_LAST
) != 0)
789 r
= (struct res_resource
*) res_alloc (sizeof *r
);
790 r
->type
= RES_TYPE_ACCELERATOR
;
796 /* Convert an rcdata resource from binary. */
798 static struct res_resource
*
799 bin_to_res_rcdata (data
, length
, big_endian
)
800 const unsigned char *data
;
801 unsigned long length
;
804 struct rcdata_item
*ri
;
805 struct res_resource
*r
;
807 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
810 ri
->type
= RCDATA_BUFFER
;
811 ri
->u
.buffer
.length
= length
;
812 ri
->u
.buffer
.data
= data
;
814 r
= (struct res_resource
*) res_alloc (sizeof *r
);
815 r
->type
= RES_TYPE_RCDATA
;
821 /* Convert a group cursor resource from binary. */
823 static struct res_resource
*
824 bin_to_res_group_cursor (data
, length
, big_endian
)
825 const unsigned char *data
;
826 unsigned long length
;
830 struct group_cursor
*first
, **pp
;
831 struct res_resource
*r
;
834 toosmall ("group cursor header");
836 type
= get_16 (big_endian
, data
+ 2);
838 fatal ("unexpected group cursor type %d", type
);
840 c
= get_16 (big_endian
, data
+ 4);
848 for (i
= 0; i
< c
; i
++)
850 struct group_cursor
*gc
;
853 toosmall ("group cursor");
855 gc
= (struct group_cursor
*) res_alloc (sizeof *gc
);
857 gc
->width
= get_16 (big_endian
, data
);
858 gc
->height
= get_16 (big_endian
, data
+ 2);
859 gc
->planes
= get_16 (big_endian
, data
+ 4);
860 gc
->bits
= get_16 (big_endian
, data
+ 6);
861 gc
->bytes
= get_32 (big_endian
, data
+ 8);
862 gc
->index
= get_16 (big_endian
, data
+ 12);
872 r
= (struct res_resource
*) res_alloc (sizeof *r
);
873 r
->type
= RES_TYPE_GROUP_CURSOR
;
874 r
->u
.group_cursor
= first
;
879 /* Convert a group icon resource from binary. */
881 static struct res_resource
*
882 bin_to_res_group_icon (data
, length
, big_endian
)
883 const unsigned char *data
;
884 unsigned long length
;
888 struct group_icon
*first
, **pp
;
889 struct res_resource
*r
;
892 toosmall ("group icon header");
894 type
= get_16 (big_endian
, data
+ 2);
896 fatal ("unexpected group icon type %d", type
);
898 c
= get_16 (big_endian
, data
+ 4);
906 for (i
= 0; i
< c
; i
++)
908 struct group_icon
*gi
;
911 toosmall ("group icon");
913 gi
= (struct group_icon
*) res_alloc (sizeof *gi
);
916 gi
->height
= data
[1];
917 gi
->colors
= data
[2];
918 gi
->planes
= get_16 (big_endian
, data
+ 4);
919 gi
->bits
= get_16 (big_endian
, data
+ 6);
920 gi
->bytes
= get_32 (big_endian
, data
+ 8);
921 gi
->index
= get_16 (big_endian
, data
+ 12);
931 r
= (struct res_resource
*) res_alloc (sizeof *r
);
932 r
->type
= RES_TYPE_GROUP_ICON
;
933 r
->u
.group_icon
= first
;
938 /* Extract data from a version header. If KEY is not NULL, then the
939 key must be KEY; otherwise, the key is returned in *PKEY. This
940 sets *LEN to the total length, *VALLEN to the value length, *TYPE
941 to the type, and *OFF to the offset to the children. */
944 get_version_header (data
, length
, big_endian
, key
, pkey
, len
, vallen
, type
,
946 const unsigned char *data
;
947 unsigned long length
;
959 *len
= get_16 (big_endian
, data
);
960 *vallen
= get_16 (big_endian
, data
+ 2);
961 *type
= get_16 (big_endian
, data
+ 4);
972 *pkey
= get_unicode (data
, length
, big_endian
, &sublen
);
973 *off
+= sublen
* 2 + 2;
981 if (get_16 (big_endian
, data
) != *key
)
982 fatal ("unexpected version string");
995 *off
= (*off
+ 3) &~ 3;
998 /* Convert a version resource from binary. */
1000 static struct res_resource
*
1001 bin_to_res_version (data
, length
, big_endian
)
1002 const unsigned char *data
;
1003 unsigned long length
;
1006 int verlen
, vallen
, type
, off
;
1007 struct fixed_versioninfo
*fi
;
1008 struct ver_info
*first
, **pp
;
1009 struct versioninfo
*v
;
1010 struct res_resource
*r
;
1012 get_version_header (data
, length
, big_endian
, "VS_VERSION_INFO",
1013 (unichar
*) NULL
, &verlen
, &vallen
, &type
, &off
);
1015 if (verlen
!= length
)
1016 fatal ("version length %d does not match resource length %lu",
1020 fatal ("unexpected version type %d", type
);
1029 unsigned long signature
, fiv
;
1032 fatal ("unexpected fixed version information length %d", vallen
);
1035 toosmall ("fixed version info");
1037 signature
= get_32 (big_endian
, data
);
1038 if (signature
!= 0xfeef04bd)
1039 fatal ("unexpected fixed version signature %lu", signature
);
1041 fiv
= get_32 (big_endian
, data
+ 4);
1042 if (fiv
!= 0 && fiv
!= 0x10000)
1043 fatal ("unexpected fixed version info version %lu", fiv
);
1045 fi
= (struct fixed_versioninfo
*) res_alloc (sizeof *fi
);
1047 fi
->file_version_ms
= get_32 (big_endian
, data
+ 8);
1048 fi
->file_version_ls
= get_32 (big_endian
, data
+ 12);
1049 fi
->product_version_ms
= get_32 (big_endian
, data
+ 16);
1050 fi
->product_version_ls
= get_32 (big_endian
, data
+ 20);
1051 fi
->file_flags_mask
= get_32 (big_endian
, data
+ 24);
1052 fi
->file_flags
= get_32 (big_endian
, data
+ 28);
1053 fi
->file_os
= get_32 (big_endian
, data
+ 32);
1054 fi
->file_type
= get_32 (big_endian
, data
+ 36);
1055 fi
->file_subtype
= get_32 (big_endian
, data
+ 40);
1056 fi
->file_date_ms
= get_32 (big_endian
, data
+ 44);
1057 fi
->file_date_ls
= get_32 (big_endian
, data
+ 48);
1068 struct ver_info
*vi
;
1072 toosmall ("version var info");
1074 vi
= (struct ver_info
*) res_alloc (sizeof *vi
);
1076 ch
= get_16 (big_endian
, data
+ 6);
1080 struct ver_stringinfo
**ppvs
;
1082 vi
->type
= VERINFO_STRING
;
1084 get_version_header (data
, length
, big_endian
, "StringFileInfo",
1085 (unichar
*) NULL
, &verlen
, &vallen
, &type
,
1089 fatal ("unexpected stringfileinfo value length %d", vallen
);
1094 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1095 &vi
->u
.string
.language
, &verlen
, &vallen
,
1099 fatal ("unexpected version stringtable value length %d", vallen
);
1105 vi
->u
.string
.strings
= NULL
;
1106 ppvs
= &vi
->u
.string
.strings
;
1108 /* It's convenient to round verlen to a 4 byte alignment,
1109 since we round the subvariables in the loop. */
1110 verlen
= (verlen
+ 3) &~ 3;
1114 struct ver_stringinfo
*vs
;
1115 int subverlen
, vslen
, valoff
;
1117 vs
= (struct ver_stringinfo
*) res_alloc (sizeof *vs
);
1119 get_version_header (data
, length
, big_endian
,
1120 (const char *) NULL
, &vs
->key
, &subverlen
,
1121 &vallen
, &type
, &off
);
1123 subverlen
= (subverlen
+ 3) &~ 3;
1128 vs
->value
= get_unicode (data
, length
, big_endian
, &vslen
);
1129 valoff
= vslen
* 2 + 2;
1130 valoff
= (valoff
+ 3) &~ 3;
1132 if (off
+ valoff
!= subverlen
)
1133 fatal ("unexpected version string length %d != %d + %d",
1134 subverlen
, off
, valoff
);
1143 if (verlen
< subverlen
)
1144 fatal ("unexpected version string length %d < %d",
1147 verlen
-= subverlen
;
1152 struct ver_varinfo
**ppvv
;
1154 vi
->type
= VERINFO_VAR
;
1156 get_version_header (data
, length
, big_endian
, "VarFileInfo",
1157 (unichar
*) NULL
, &verlen
, &vallen
, &type
,
1161 fatal ("unexpected varfileinfo value length %d", vallen
);
1166 get_version_header (data
, length
, big_endian
, (const char *) NULL
,
1167 &vi
->u
.var
.key
, &verlen
, &vallen
, &type
, &off
);
1172 vi
->u
.var
.var
= NULL
;
1173 ppvv
= &vi
->u
.var
.var
;
1177 struct ver_varinfo
*vv
;
1180 toosmall ("version varfileinfo");
1182 vv
= (struct ver_varinfo
*) res_alloc (sizeof *vv
);
1184 vv
->language
= get_16 (big_endian
, data
);
1185 vv
->charset
= get_16 (big_endian
, data
+ 2);
1195 fatal ("unexpected version value length %d", vallen
);
1201 fatal ("unexpected version string");
1208 v
= (struct versioninfo
*) res_alloc (sizeof *v
);
1212 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1213 r
->type
= RES_TYPE_VERSIONINFO
;
1214 r
->u
.versioninfo
= v
;
1219 /* Convert an arbitrary user defined resource from binary. */
1221 static struct res_resource
*
1222 bin_to_res_userdata (data
, length
, big_endian
)
1223 const unsigned char *data
;
1224 unsigned long length
;
1227 struct rcdata_item
*ri
;
1228 struct res_resource
*r
;
1230 ri
= (struct rcdata_item
*) res_alloc (sizeof *ri
);
1233 ri
->type
= RCDATA_BUFFER
;
1234 ri
->u
.buffer
.length
= length
;
1235 ri
->u
.buffer
.data
= data
;
1237 r
= (struct res_resource
*) res_alloc (sizeof *r
);
1238 r
->type
= RES_TYPE_USERDATA
;
1244 /* Macros to swap out values. */
1246 #define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
1247 #define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
1249 /* Local functions used to convert resources to binary format. */
1251 static void dword_align_bin
PARAMS ((struct bindata
***, unsigned long *));
1252 static struct bindata
*resid_to_bin
PARAMS ((struct res_id
, int));
1253 static struct bindata
*unicode_to_bin
PARAMS ((const unichar
*, int));
1254 static struct bindata
*res_to_bin_accelerator
1255 PARAMS ((const struct accelerator
*, int));
1256 static struct bindata
*res_to_bin_cursor
1257 PARAMS ((const struct cursor
*, int));
1258 static struct bindata
*res_to_bin_group_cursor
1259 PARAMS ((const struct group_cursor
*, int));
1260 static struct bindata
*res_to_bin_dialog
1261 PARAMS ((const struct dialog
*, int));
1262 static struct bindata
*res_to_bin_fontdir
1263 PARAMS ((const struct fontdir
*, int));
1264 static struct bindata
*res_to_bin_group_icon
1265 PARAMS ((const struct group_icon
*, int));
1266 static struct bindata
*res_to_bin_menu
1267 PARAMS ((const struct menu
*, int));
1268 static struct bindata
*res_to_bin_menuitems
1269 PARAMS ((const struct menuitem
*, int));
1270 static struct bindata
*res_to_bin_menuexitems
1271 PARAMS ((const struct menuitem
*, int));
1272 static struct bindata
*res_to_bin_rcdata
1273 PARAMS ((const struct rcdata_item
*, int));
1274 static struct bindata
*res_to_bin_stringtable
1275 PARAMS ((const struct stringtable
*, int));
1276 static struct bindata
*string_to_unicode_bin
PARAMS ((const char *, int));
1277 static struct bindata
*res_to_bin_versioninfo
1278 PARAMS ((const struct versioninfo
*, int));
1279 static struct bindata
*res_to_bin_generic
1280 PARAMS ((unsigned long, const unsigned char *));
1282 /* Convert a resource to binary. */
1285 res_to_bin (res
, big_endian
)
1286 const struct res_resource
*res
;
1293 case RES_TYPE_BITMAP
:
1296 case RES_TYPE_MESSAGETABLE
:
1297 return res_to_bin_generic (res
->u
.data
.length
, res
->u
.data
.data
);
1298 case RES_TYPE_ACCELERATOR
:
1299 return res_to_bin_accelerator (res
->u
.acc
, big_endian
);
1300 case RES_TYPE_CURSOR
:
1301 return res_to_bin_cursor (res
->u
.cursor
, big_endian
);
1302 case RES_TYPE_GROUP_CURSOR
:
1303 return res_to_bin_group_cursor (res
->u
.group_cursor
, big_endian
);
1304 case RES_TYPE_DIALOG
:
1305 return res_to_bin_dialog (res
->u
.dialog
, big_endian
);
1306 case RES_TYPE_FONTDIR
:
1307 return res_to_bin_fontdir (res
->u
.fontdir
, big_endian
);
1308 case RES_TYPE_GROUP_ICON
:
1309 return res_to_bin_group_icon (res
->u
.group_icon
, big_endian
);
1311 return res_to_bin_menu (res
->u
.menu
, big_endian
);
1312 case RES_TYPE_RCDATA
:
1313 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1314 case RES_TYPE_STRINGTABLE
:
1315 return res_to_bin_stringtable (res
->u
.stringtable
, big_endian
);
1316 case RES_TYPE_USERDATA
:
1317 return res_to_bin_rcdata (res
->u
.rcdata
, big_endian
);
1318 case RES_TYPE_VERSIONINFO
:
1319 return res_to_bin_versioninfo (res
->u
.versioninfo
, big_endian
);
1323 /* Align to a 32 bit boundary. PPP points to the of a list of bindata
1324 structures. LENGTH points to the length of the structures. If
1325 necessary, this adds a new bindata to bring length up to a 32 bit
1326 boundary. It updates *PPP and *LENGTH. */
1329 dword_align_bin (ppp
, length
)
1330 struct bindata
***ppp
;
1331 unsigned long *length
;
1336 if ((*length
& 3) == 0)
1339 add
= 4 - (*length
& 3);
1341 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1343 d
->data
= (unsigned char *) reswr_alloc (add
);
1344 memset (d
->data
, 0, add
);
1348 *ppp
= &(**ppp
)->next
;
1353 /* Convert a resource ID to binary. This always returns exactly one
1354 bindata structure. */
1356 static struct bindata
*
1357 resid_to_bin (id
, big_endian
)
1363 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1368 d
->data
= (unsigned char *) reswr_alloc (4);
1369 put_16 (big_endian
, 0xffff, d
->data
);
1370 put_16 (big_endian
, id
.u
.id
, d
->data
+ 2);
1376 d
->length
= id
.u
.n
.length
* 2 + 2;
1377 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1378 for (i
= 0; i
< id
.u
.n
.length
; i
++)
1379 put_16 (big_endian
, id
.u
.n
.name
[i
], d
->data
+ i
* 2);
1380 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1388 /* Convert a null terminated unicode string to binary. This always
1389 returns exactly one bindata structure. */
1391 static struct bindata
*
1392 unicode_to_bin (str
, big_endian
)
1404 for (s
= str
; *s
!= 0; s
++)
1408 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1409 d
->length
= len
* 2 + 2;
1410 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1413 put_16 (big_endian
, 0, d
->data
);
1419 for (s
= str
, i
= 0; *s
!= 0; s
++, i
++)
1420 put_16 (big_endian
, *s
, d
->data
+ i
* 2);
1421 put_16 (big_endian
, 0, d
->data
+ i
* 2);
1429 /* Convert an accelerator resource to binary. */
1431 static struct bindata
*
1432 res_to_bin_accelerator (accelerators
, big_endian
)
1433 const struct accelerator
*accelerators
;
1436 struct bindata
*first
, **pp
;
1437 const struct accelerator
*a
;
1442 for (a
= accelerators
; a
!= NULL
; a
= a
->next
)
1446 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1448 d
->data
= (unsigned char *) reswr_alloc (8);
1451 a
->flags
| (a
->next
== NULL
? 0 : ACC_LAST
),
1453 put_16 (big_endian
, a
->key
, d
->data
+ 2);
1454 put_16 (big_endian
, a
->id
, d
->data
+ 4);
1455 put_16 (big_endian
, 0, d
->data
+ 8);
1465 /* Convert a cursor resource to binary. */
1467 static struct bindata
*
1468 res_to_bin_cursor (c
, big_endian
)
1469 const struct cursor
*c
;
1474 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1476 d
->data
= (unsigned char *) reswr_alloc (4);
1478 put_16 (big_endian
, c
->xhotspot
, d
->data
);
1479 put_16 (big_endian
, c
->yhotspot
, d
->data
+ 2);
1481 d
->next
= (struct bindata
*) reswr_alloc (sizeof *d
);
1482 d
->next
->length
= c
->length
;
1483 d
->next
->data
= (unsigned char *) c
->data
;
1484 d
->next
->next
= NULL
;
1489 /* Convert a group cursor resource to binary. */
1491 static struct bindata
*
1492 res_to_bin_group_cursor (group_cursors
, big_endian
)
1493 const struct group_cursor
*group_cursors
;
1496 struct bindata
*first
, **pp
;
1498 const struct group_cursor
*gc
;
1500 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1502 first
->data
= (unsigned char *) reswr_alloc (6);
1504 put_16 (big_endian
, 0, first
->data
);
1505 put_16 (big_endian
, 2, first
->data
+ 2);
1511 for (gc
= group_cursors
; gc
!= NULL
; gc
= gc
->next
)
1517 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1519 d
->data
= (unsigned char *) reswr_alloc (14);
1521 put_16 (big_endian
, gc
->width
, d
->data
);
1522 put_16 (big_endian
, gc
->height
, d
->data
+ 2);
1523 put_16 (big_endian
, gc
->planes
, d
->data
+ 4);
1524 put_16 (big_endian
, gc
->bits
, d
->data
+ 6);
1525 put_32 (big_endian
, gc
->bytes
, d
->data
+ 8);
1526 put_16 (big_endian
, gc
->index
, d
->data
+ 12);
1533 put_16 (big_endian
, c
, first
->data
+ 4);
1538 /* Convert a dialog resource to binary. */
1540 static struct bindata
*
1541 res_to_bin_dialog (dialog
, big_endian
)
1542 const struct dialog
*dialog
;
1546 struct bindata
*first
, **pp
;
1547 unsigned long length
;
1549 struct dialog_control
*dc
;
1551 dialogex
= extended_dialog (dialog
);
1553 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1554 first
->length
= dialogex
? 26 : 18;
1555 first
->data
= (unsigned char *) reswr_alloc (first
->length
);
1557 length
= first
->length
;
1561 put_32 (big_endian
, dialog
->style
, first
->data
);
1562 put_32 (big_endian
, dialog
->style
, first
->data
+ 4);
1567 put_16 (big_endian
, 0xffff, first
->data
);
1568 put_16 (big_endian
, 1, first
->data
+ 2);
1569 if (dialog
->ex
== NULL
)
1570 put_32 (big_endian
, 0, first
->data
+ 4);
1572 put_32 (big_endian
, dialog
->ex
->help
, first
->data
+ 4);
1573 put_32 (big_endian
, dialog
->exstyle
, first
->data
+ 8);
1574 put_32 (big_endian
, dialog
->style
, first
->data
+ 12);
1578 put_16 (big_endian
, dialog
->x
, first
->data
+ off
+ 2);
1579 put_16 (big_endian
, dialog
->y
, first
->data
+ off
+ 4);
1580 put_16 (big_endian
, dialog
->width
, first
->data
+ off
+ 6);
1581 put_16 (big_endian
, dialog
->height
, first
->data
+ off
+ 8);
1585 *pp
= resid_to_bin (dialog
->menu
, big_endian
);
1586 length
+= (*pp
)->length
;
1589 *pp
= resid_to_bin (dialog
->class, big_endian
);
1590 length
+= (*pp
)->length
;
1593 *pp
= unicode_to_bin (dialog
->caption
, big_endian
);
1594 length
+= (*pp
)->length
;
1597 if ((dialog
->style
& DS_SETFONT
) != 0)
1601 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1602 d
->length
= dialogex
? 2 : 6;
1603 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1605 length
+= d
->length
;
1607 put_16 (big_endian
, dialog
->pointsize
, d
->data
);
1611 if (dialog
->ex
== NULL
)
1613 put_16 (big_endian
, 0, d
->data
+ 2);
1614 put_16 (big_endian
, 0, d
->data
+ 4);
1618 put_16 (big_endian
, dialog
->ex
->weight
, d
->data
+ 2);
1619 put_16 (big_endian
, dialog
->ex
->italic
, d
->data
+ 4);
1626 *pp
= unicode_to_bin (dialog
->font
, big_endian
);
1627 length
+= (*pp
)->length
;
1632 for (dc
= dialog
->controls
; dc
!= NULL
; dc
= dc
->next
)
1634 unsigned long length
;
1640 dword_align_bin (&pp
, &length
);
1642 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1643 d
->length
= dialogex
? 22 : 18;
1644 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1646 length
+= d
->length
;
1650 put_32 (big_endian
, dc
->style
, d
->data
);
1651 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1656 put_32 (big_endian
, dc
->help
, d
->data
);
1657 put_32 (big_endian
, dc
->exstyle
, d
->data
+ 4);
1658 put_32 (big_endian
, dc
->style
, d
->data
+ 8);
1662 put_16 (big_endian
, dc
->x
, d
->data
+ dcoff
);
1663 put_16 (big_endian
, dc
->y
, d
->data
+ dcoff
+ 2);
1664 put_16 (big_endian
, dc
->width
, d
->data
+ dcoff
+ 4);
1665 put_16 (big_endian
, dc
->height
, d
->data
+ dcoff
+ 6);
1666 put_16 (big_endian
, dc
->id
, d
->data
+ dcoff
+ 8);
1671 *pp
= resid_to_bin (dc
->class, big_endian
);
1672 length
+= (*pp
)->length
;
1675 *pp
= resid_to_bin (dc
->text
, big_endian
);
1676 length
+= (*pp
)->length
;
1679 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1681 d
->data
= (unsigned char *) reswr_alloc (2);
1689 if (dc
->data
== NULL
)
1690 put_16 (big_endian
, 0, d
->data
);
1693 dword_align_bin (&pp
, &length
);
1695 *pp
= res_to_bin_rcdata (dc
->data
, big_endian
);
1698 length
+= (*pp
)->length
;
1704 put_16 (big_endian
, c
, first
->data
+ off
);
1709 /* Convert a fontdir resource to binary. */
1711 static struct bindata
*
1712 res_to_bin_fontdir (fontdirs
, big_endian
)
1713 const struct fontdir
*fontdirs
;
1716 struct bindata
*first
, **pp
;
1718 const struct fontdir
*fd
;
1720 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1722 first
->data
= (unsigned char *) reswr_alloc (2);
1728 for (fd
= fontdirs
; fd
!= NULL
; fd
= fd
->next
)
1734 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1736 d
->data
= (unsigned char *) reswr_alloc (2);
1738 put_16 (big_endian
, fd
->index
, d
->data
);
1743 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1744 d
->length
= fd
->length
;
1745 d
->data
= (unsigned char *) fd
->data
;
1752 put_16 (big_endian
, c
, first
->data
);
1757 /* Convert a group icon resource to binary. */
1759 static struct bindata
*
1760 res_to_bin_group_icon (group_icons
, big_endian
)
1761 const struct group_icon
*group_icons
;
1764 struct bindata
*first
, **pp
;
1766 const struct group_icon
*gi
;
1768 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
1770 first
->data
= (unsigned char *) reswr_alloc (6);
1772 put_16 (big_endian
, 0, first
->data
);
1773 put_16 (big_endian
, 1, first
->data
+ 2);
1779 for (gi
= group_icons
; gi
!= NULL
; gi
= gi
->next
)
1785 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1787 d
->data
= (unsigned char *) reswr_alloc (14);
1789 d
->data
[0] = gi
->width
;
1790 d
->data
[1] = gi
->height
;
1791 d
->data
[2] = gi
->colors
;
1793 put_16 (big_endian
, gi
->planes
, d
->data
+ 4);
1794 put_16 (big_endian
, gi
->bits
, d
->data
+ 6);
1795 put_32 (big_endian
, gi
->bytes
, d
->data
+ 8);
1796 put_16 (big_endian
, gi
->index
, d
->data
+ 12);
1803 put_16 (big_endian
, c
, first
->data
+ 4);
1808 /* Convert a menu resource to binary. */
1810 static struct bindata
*
1811 res_to_bin_menu (menu
, big_endian
)
1812 const struct menu
*menu
;
1818 menuex
= extended_menu (menu
);
1820 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1821 d
->length
= menuex
? 8 : 4;
1822 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1826 put_16 (big_endian
, 0, d
->data
);
1827 put_16 (big_endian
, 0, d
->data
+ 2);
1829 d
->next
= res_to_bin_menuitems (menu
->items
, big_endian
);
1833 put_16 (big_endian
, 1, d
->data
);
1834 put_16 (big_endian
, 4, d
->data
+ 2);
1835 put_32 (big_endian
, menu
->help
, d
->data
+ 4);
1837 d
->next
= res_to_bin_menuexitems (menu
->items
, big_endian
);
1843 /* Convert menu items to binary. */
1845 static struct bindata
*
1846 res_to_bin_menuitems (items
, big_endian
)
1847 const struct menuitem
*items
;
1850 struct bindata
*first
, **pp
;
1851 const struct menuitem
*mi
;
1856 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1861 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1862 d
->length
= mi
->popup
== NULL
? 4 : 2;
1863 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
1866 if (mi
->next
== NULL
)
1867 flags
|= MENUITEM_ENDMENU
;
1868 if (mi
->popup
!= NULL
)
1869 flags
|= MENUITEM_POPUP
;
1871 put_16 (big_endian
, flags
, d
->data
);
1873 if (mi
->popup
== NULL
)
1874 put_16 (big_endian
, mi
->id
, d
->data
+ 2);
1879 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1882 if (mi
->popup
!= NULL
)
1884 *pp
= res_to_bin_menuitems (mi
->popup
, big_endian
);
1893 /* Convert menuex items to binary. */
1895 static struct bindata
*
1896 res_to_bin_menuexitems (items
, big_endian
)
1897 const struct menuitem
*items
;
1900 struct bindata
*first
, **pp
;
1901 unsigned long length
;
1902 const struct menuitem
*mi
;
1909 for (mi
= items
; mi
!= NULL
; mi
= mi
->next
)
1914 dword_align_bin (&pp
, &length
);
1916 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1918 d
->data
= (unsigned char *) reswr_alloc (12);
1922 put_32 (big_endian
, mi
->type
, d
->data
);
1923 put_32 (big_endian
, mi
->state
, d
->data
+ 4);
1924 put_16 (big_endian
, mi
->id
, d
->data
+ 8);
1927 if (mi
->next
== NULL
)
1929 if (mi
->popup
!= NULL
)
1931 put_16 (big_endian
, flags
, d
->data
+ 10);
1936 *pp
= unicode_to_bin (mi
->text
, big_endian
);
1937 length
+= (*pp
)->length
;
1940 if (mi
->popup
!= NULL
)
1942 dword_align_bin (&pp
, &length
);
1944 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1946 d
->data
= (unsigned char *) reswr_alloc (4);
1948 put_32 (big_endian
, mi
->help
, d
->data
);
1953 *pp
= res_to_bin_menuexitems (mi
->popup
, big_endian
);
1956 length
+= (*pp
)->length
;
1965 /* Convert an rcdata resource to binary. This is also used to convert
1966 other information which happens to be stored in rcdata_item lists
1969 static struct bindata
*
1970 res_to_bin_rcdata (items
, big_endian
)
1971 const struct rcdata_item
*items
;
1974 struct bindata
*first
, **pp
;
1975 const struct rcdata_item
*ri
;
1980 for (ri
= items
; ri
!= NULL
; ri
= ri
->next
)
1984 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
1993 d
->data
= (unsigned char *) reswr_alloc (2);
1994 put_16 (big_endian
, ri
->u
.word
, d
->data
);
1999 d
->data
= (unsigned char *) reswr_alloc (4);
2000 put_32 (big_endian
, ri
->u
.dword
, d
->data
);
2004 d
->length
= ri
->u
.string
.length
;
2005 d
->data
= (unsigned char *) ri
->u
.string
.s
;
2008 case RCDATA_WSTRING
:
2012 d
->length
= ri
->u
.wstring
.length
* 2;
2013 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2014 for (i
= 0; i
< ri
->u
.wstring
.length
; i
++)
2015 put_16 (big_endian
, ri
->u
.wstring
.w
[i
], d
->data
+ i
* 2);
2020 d
->length
= ri
->u
.buffer
.length
;
2021 d
->data
= (unsigned char *) ri
->u
.buffer
.data
;
2033 /* Convert a stringtable resource to binary. */
2035 static struct bindata
*
2036 res_to_bin_stringtable (st
, big_endian
)
2037 const struct stringtable
*st
;
2040 struct bindata
*first
, **pp
;
2046 for (i
= 0; i
< 16; i
++)
2052 slen
= st
->strings
[i
].length
;
2053 s
= st
->strings
[i
].string
;
2055 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2056 d
->length
= 2 + slen
* 2;
2057 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2059 put_16 (big_endian
, slen
, d
->data
);
2061 for (j
= 0; j
< slen
; j
++)
2062 put_16 (big_endian
, s
[j
], d
->data
+ 2 + j
* 2);
2072 /* Convert an ASCII string to a unicode binary string. This always
2073 returns exactly one bindata structure. */
2075 static struct bindata
*
2076 string_to_unicode_bin (s
, big_endian
)
2085 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2086 d
->length
= len
* 2 + 2;
2087 d
->data
= (unsigned char *) reswr_alloc (d
->length
);
2089 for (i
= 0; i
< len
; i
++)
2090 put_16 (big_endian
, s
[i
], d
->data
+ i
* 2);
2091 put_16 (big_endian
, 0, d
->data
+ i
* 2);
2098 /* Convert a versioninfo resource to binary. */
2100 static struct bindata
*
2101 res_to_bin_versioninfo (versioninfo
, big_endian
)
2102 const struct versioninfo
*versioninfo
;
2105 struct bindata
*first
, **pp
;
2106 unsigned long length
;
2107 struct ver_info
*vi
;
2109 first
= (struct bindata
*) reswr_alloc (sizeof *first
);
2111 first
->data
= (unsigned char *) reswr_alloc (6);
2115 if (versioninfo
->fixed
== NULL
)
2116 put_16 (big_endian
, 0, first
->data
+ 2);
2118 put_16 (big_endian
, 52, first
->data
+ 2);
2120 put_16 (big_endian
, 0, first
->data
+ 4);
2124 *pp
= string_to_unicode_bin ("VS_VERSION_INFO", big_endian
);
2125 length
+= (*pp
)->length
;
2128 dword_align_bin (&pp
, &length
);
2130 if (versioninfo
->fixed
!= NULL
)
2132 const struct fixed_versioninfo
*fi
;
2135 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2137 d
->data
= (unsigned char *) reswr_alloc (52);
2141 fi
= versioninfo
->fixed
;
2143 put_32 (big_endian
, 0xfeef04bd, d
->data
);
2144 put_32 (big_endian
, 0x10000, d
->data
+ 4);
2145 put_32 (big_endian
, fi
->file_version_ms
, d
->data
+ 8);
2146 put_32 (big_endian
, fi
->file_version_ls
, d
->data
+ 12);
2147 put_32 (big_endian
, fi
->product_version_ms
, d
->data
+ 16);
2148 put_32 (big_endian
, fi
->product_version_ls
, d
->data
+ 20);
2149 put_32 (big_endian
, fi
->file_flags_mask
, d
->data
+ 24);
2150 put_32 (big_endian
, fi
->file_flags
, d
->data
+ 28);
2151 put_32 (big_endian
, fi
->file_os
, d
->data
+ 32);
2152 put_32 (big_endian
, fi
->file_type
, d
->data
+ 36);
2153 put_32 (big_endian
, fi
->file_subtype
, d
->data
+ 40);
2154 put_32 (big_endian
, fi
->file_date_ms
, d
->data
+ 44);
2155 put_32 (big_endian
, fi
->file_date_ls
, d
->data
+ 48);
2162 for (vi
= versioninfo
->var
; vi
!= NULL
; vi
= vi
->next
)
2164 struct bindata
*vid
;
2165 unsigned long vilen
;
2167 dword_align_bin (&pp
, &length
);
2169 vid
= (struct bindata
*) reswr_alloc (sizeof *vid
);
2171 vid
->data
= (unsigned char *) reswr_alloc (6);
2176 put_16 (big_endian
, 0, vid
->data
+ 2);
2177 put_16 (big_endian
, 0, vid
->data
+ 4);
2187 case VERINFO_STRING
:
2189 unsigned long hold
, vslen
;
2190 struct bindata
*vsd
;
2191 const struct ver_stringinfo
*vs
;
2193 *pp
= string_to_unicode_bin ("StringFileInfo", big_endian
);
2194 length
+= (*pp
)->length
;
2195 vilen
+= (*pp
)->length
;
2199 dword_align_bin (&pp
, &length
);
2200 vilen
+= length
- hold
;
2202 vsd
= (struct bindata
*) reswr_alloc (sizeof *vsd
);
2204 vsd
->data
= (unsigned char *) reswr_alloc (6);
2210 put_16 (big_endian
, 0, vsd
->data
+ 2);
2211 put_16 (big_endian
, 0, vsd
->data
+ 4);
2216 *pp
= unicode_to_bin (vi
->u
.string
.language
, big_endian
);
2217 length
+= (*pp
)->length
;
2218 vilen
+= (*pp
)->length
;
2219 vslen
+= (*pp
)->length
;
2222 for (vs
= vi
->u
.string
.strings
; vs
!= NULL
; vs
= vs
->next
)
2224 struct bindata
*vssd
;
2225 unsigned long vsslen
;
2228 dword_align_bin (&pp
, &length
);
2229 vilen
+= length
- hold
;
2230 vslen
+= length
- hold
;
2232 vssd
= (struct bindata
*) reswr_alloc (sizeof *vssd
);
2234 vssd
->data
= (unsigned char *) reswr_alloc (6);
2241 put_16 (big_endian
, 0, vssd
->data
+ 2);
2242 put_16 (big_endian
, 1, vssd
->data
+ 4);
2247 *pp
= unicode_to_bin (vs
->key
, big_endian
);
2248 length
+= (*pp
)->length
;
2249 vilen
+= (*pp
)->length
;
2250 vslen
+= (*pp
)->length
;
2251 vsslen
+= (*pp
)->length
;
2255 dword_align_bin (&pp
, &length
);
2256 vilen
+= length
- hold
;
2257 vslen
+= length
- hold
;
2258 vsslen
+= length
- hold
;
2260 *pp
= unicode_to_bin (vs
->value
, big_endian
);
2261 length
+= (*pp
)->length
;
2262 vilen
+= (*pp
)->length
;
2263 vslen
+= (*pp
)->length
;
2264 vsslen
+= (*pp
)->length
;
2267 put_16 (big_endian
, vsslen
, vssd
->data
);
2270 put_16 (big_endian
, vslen
, vsd
->data
);
2277 unsigned long hold
, vvlen
, vvvlen
;
2278 struct bindata
*vvd
;
2279 const struct ver_varinfo
*vv
;
2281 *pp
= string_to_unicode_bin ("VarFileInfo", big_endian
);
2282 length
+= (*pp
)->length
;
2283 vilen
+= (*pp
)->length
;
2287 dword_align_bin (&pp
, &length
);
2288 vilen
+= length
- hold
;
2290 vvd
= (struct bindata
*) reswr_alloc (sizeof *vvd
);
2292 vvd
->data
= (unsigned char *) reswr_alloc (6);
2298 put_16 (big_endian
, 0, vvd
->data
+ 4);
2303 *pp
= unicode_to_bin (vi
->u
.var
.key
, big_endian
);
2304 length
+= (*pp
)->length
;
2305 vilen
+= (*pp
)->length
;
2306 vvlen
+= (*pp
)->length
;
2310 dword_align_bin (&pp
, &length
);
2311 vilen
+= length
- hold
;
2312 vvlen
+= length
- hold
;
2316 for (vv
= vi
->u
.var
.var
; vv
!= NULL
; vv
= vv
->next
)
2318 struct bindata
*vvsd
;
2320 vvsd
= (struct bindata
*) reswr_alloc (sizeof *vvsd
);
2322 vvsd
->data
= (unsigned char *) reswr_alloc (4);
2329 put_16 (big_endian
, vv
->language
, vvsd
->data
);
2330 put_16 (big_endian
, vv
->charset
, vvsd
->data
+ 2);
2337 put_16 (big_endian
, vvlen
, vvd
->data
);
2338 put_16 (big_endian
, vvvlen
, vvd
->data
+ 2);
2344 put_16 (big_endian
, vilen
, vid
->data
);
2347 put_16 (big_endian
, length
, first
->data
);
2352 /* Convert a generic resource to binary. */
2354 static struct bindata
*
2355 res_to_bin_generic (length
, data
)
2356 unsigned long length
;
2357 const unsigned char *data
;
2361 d
= (struct bindata
*) reswr_alloc (sizeof *d
);
2363 d
->data
= (unsigned char *) data
;