1 /* resbin.c -- manipulate the Windows binary resource format.
2    Copyright 1997, 1998, 1999, 2002, 2003
3    Free Software Foundation, Inc.
4    Written by Ian Lance Taylor, Cygnus Support.
5 
6    This file is part of GNU Binutils.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21    02110-1301, USA.  */
22 
23 /* This file contains functions to convert between the binary resource
24    format and the internal structures that we want to use.  The same
25    binary resource format is used in both res and COFF files.  */
26 
27 #include "bfd.h"
28 #include "bucomm.h"
29 #include "libiberty.h"
30 #include "windres.h"
31 
32 /* Macros to swap in values.  */
33 
34 #define get_8(s)      (*((unsigned char *)(s)))
35 #define get_16(be, s) ((be) ? bfd_getb16 (s) : bfd_getl16 (s))
36 #define get_32(be, s) ((be) ? bfd_getb32 (s) : bfd_getl32 (s))
37 
38 /* Local functions.  */
39 
40 static void toosmall (const char *);
41 
42 static unichar *get_unicode
43   (const unsigned char *, unsigned long, int, int *);
44 static int get_resid
45   (struct res_id *, const unsigned char *, unsigned long, int);
46 static struct res_resource *bin_to_res_generic
47   (enum res_type, const unsigned char *, unsigned long);
48 static struct res_resource *bin_to_res_cursor
49   (const unsigned char *, unsigned long, int);
50 static struct res_resource *bin_to_res_menu
51   (const unsigned char *, unsigned long, int);
52 static struct menuitem *bin_to_res_menuitems
53   (const unsigned char *, unsigned long, int, int *);
54 static struct menuitem *bin_to_res_menuexitems
55   (const unsigned char *, unsigned long, int, int *);
56 static struct res_resource *bin_to_res_dialog
57   (const unsigned char *, unsigned long, int);
58 static struct res_resource *bin_to_res_string
59   (const unsigned char *, unsigned long, int);
60 static struct res_resource *bin_to_res_fontdir
61   (const unsigned char *, unsigned long, int);
62 static struct res_resource *bin_to_res_accelerators
63   (const unsigned char *, unsigned long, int);
64 static struct res_resource *bin_to_res_rcdata
65   (const unsigned char *, unsigned long, int);
66 static struct res_resource *bin_to_res_group_cursor
67   (const unsigned char *, unsigned long, int);
68 static struct res_resource *bin_to_res_group_icon
69   (const unsigned char *, unsigned long, int);
70 static struct res_resource *bin_to_res_version
71   (const unsigned char *, unsigned long, int);
72 static struct res_resource *bin_to_res_userdata
73   (const unsigned char *, unsigned long, int);
74 static void get_version_header
75   (const unsigned char *, unsigned long, int, const char *,
76    unichar **, int *, int *, int *, int *);
77 
78 /* Given a resource type ID, a pointer to data, a length, return a
79    res_resource structure which represents that resource.  The caller
80    is responsible for initializing the res_info and coff_info fields
81    of the returned structure.  */
82 
83 struct res_resource *
84 bin_to_res (struct res_id type, const unsigned char *data,
85 	    unsigned long length, int big_endian)
86 {
87   if (type.named)
88     return bin_to_res_userdata (data, length, big_endian);
89   else
90     {
91       switch (type.u.id)
92 	{
93 	default:
94 	  return bin_to_res_userdata (data, length, big_endian);
95 	case RT_CURSOR:
96 	  return bin_to_res_cursor (data, length, big_endian);
97 	case RT_BITMAP:
98 	  return bin_to_res_generic (RES_TYPE_BITMAP, data, length);
99 	case RT_ICON:
100 	  return bin_to_res_generic (RES_TYPE_ICON, data, length);
101 	case RT_MENU:
102 	  return bin_to_res_menu (data, length, big_endian);
103 	case RT_DIALOG:
104 	  return bin_to_res_dialog (data, length, big_endian);
105 	case RT_STRING:
106 	  return bin_to_res_string (data, length, big_endian);
107 	case RT_FONTDIR:
108 	  return bin_to_res_fontdir (data, length, big_endian);
109 	case RT_FONT:
110 	  return bin_to_res_generic (RES_TYPE_FONT, data, length);
111 	case RT_ACCELERATOR:
112 	  return bin_to_res_accelerators (data, length, big_endian);
113 	case RT_RCDATA:
114 	  return bin_to_res_rcdata (data, length, big_endian);
115 	case RT_MESSAGETABLE:
116 	  return bin_to_res_generic (RES_TYPE_MESSAGETABLE, data, length);
117 	case RT_GROUP_CURSOR:
118 	  return bin_to_res_group_cursor (data, length, big_endian);
119 	case RT_GROUP_ICON:
120 	  return bin_to_res_group_icon (data, length, big_endian);
121 	case RT_VERSION:
122 	  return bin_to_res_version (data, length, big_endian);
123 	}
124     }
125 }
126 
127 /* Give an error if the binary data is too small.  */
128 
129 static void
130 toosmall (const char *msg)
131 {
132   fatal (_("%s: not enough binary data"), msg);
133 }
134 
135 /* Swap in a NULL terminated unicode string.  */
136 
137 static unichar *
138 get_unicode (const unsigned char *data, unsigned long length,
139 	     int big_endian, int *retlen)
140 {
141   int c, i;
142   unichar *ret;
143 
144   c = 0;
145   while (1)
146     {
147       if (length < (unsigned long) c * 2 + 2)
148 	toosmall (_("null terminated unicode string"));
149       if (get_16 (big_endian, data + c * 2) == 0)
150 	break;
151       ++c;
152     }
153 
154   ret = (unichar *) res_alloc ((c + 1) * sizeof (unichar));
155 
156   for (i = 0; i < c; i++)
157     ret[i] = get_16 (big_endian, data + i * 2);
158   ret[i] = 0;
159 
160   if (retlen != NULL)
161     *retlen = c;
162 
163   return ret;
164 }
165 
166 /* Get a resource identifier.  This returns the number of bytes used.  */
167 
168 static int
169 get_resid (struct res_id *id, const unsigned char *data,
170 	   unsigned long length, int big_endian)
171 {
172   int first;
173 
174   if (length < 2)
175     toosmall (_("resource ID"));
176 
177   first = get_16 (big_endian, data);
178   if (first == 0xffff)
179     {
180       if (length < 4)
181 	toosmall (_("resource ID"));
182       id->named = 0;
183       id->u.id = get_16 (big_endian, data + 2);
184       return 4;
185     }
186   else
187     {
188       id->named = 1;
189       id->u.n.name = get_unicode (data, length, big_endian, &id->u.n.length);
190       return id->u.n.length * 2 + 2;
191     }
192 }
193 
194 /* Convert a resource which just stores uninterpreted data from
195    binary.  */
196 
197 struct res_resource *
198 bin_to_res_generic (enum res_type type, const unsigned char *data,
199 		    unsigned long length)
200 {
201   struct res_resource *r;
202 
203   r = (struct res_resource *) res_alloc (sizeof *r);
204   r->type = type;
205   r->u.data.data = data;
206   r->u.data.length = length;
207 
208   return r;
209 }
210 
211 /* Convert a cursor resource from binary.  */
212 
213 struct res_resource *
214 bin_to_res_cursor (const unsigned char *data, unsigned long length,
215 		   int big_endian)
216 {
217   struct cursor *c;
218   struct res_resource *r;
219 
220   if (length < 4)
221     toosmall (_("cursor"));
222 
223   c = (struct cursor *) res_alloc (sizeof *c);
224   c->xhotspot = get_16 (big_endian, data);
225   c->yhotspot = get_16 (big_endian, data + 2);
226   c->length = length - 4;
227   c->data = data + 4;
228 
229   r = (struct res_resource *) res_alloc (sizeof *r);
230   r->type = RES_TYPE_CURSOR;
231   r->u.cursor = c;
232 
233   return r;
234 }
235 
236 /* Convert a menu resource from binary.  */
237 
238 struct res_resource *
239 bin_to_res_menu (const unsigned char *data, unsigned long length,
240 		 int big_endian)
241 {
242   struct res_resource *r;
243   struct menu *m;
244   int version, read;
245 
246   r = (struct res_resource *) res_alloc (sizeof *r);
247   r->type = RES_TYPE_MENU;
248 
249   m = (struct menu *) res_alloc (sizeof *m);
250   r->u.menu = m;
251 
252   if (length < 2)
253     toosmall (_("menu header"));
254 
255   version = get_16 (big_endian, data);
256 
257   if (version == 0)
258     {
259       if (length < 4)
260 	toosmall (_("menu header"));
261       m->help = 0;
262       m->items = bin_to_res_menuitems (data + 4, length - 4, big_endian,
263 				       &read);
264     }
265   else if (version == 1)
266     {
267       unsigned int offset;
268 
269       if (length < 8)
270 	toosmall (_("menuex header"));
271       m->help = get_32 (big_endian, data + 4);
272       offset = get_16 (big_endian, data + 2);
273       if (offset + 4 >= length)
274 	toosmall (_("menuex offset"));
275       m->items = bin_to_res_menuexitems (data + 4 + offset,
276 					 length - (4 + offset),
277 					 big_endian,
278 					 &read);
279     }
280   else
281     fatal (_("unsupported menu version %d"), version);
282 
283   return r;
284 }
285 
286 /* Convert menu items from binary.  */
287 
288 static struct menuitem *
289 bin_to_res_menuitems (const unsigned char *data, unsigned long length,
290 		      int big_endian, int *read)
291 {
292   struct menuitem *first, **pp;
293 
294   first = NULL;
295   pp = &first;
296 
297   *read = 0;
298 
299   while (length > 0)
300     {
301       int flags, slen, itemlen;
302       unsigned int stroff;
303       struct menuitem *mi;
304 
305       if (length < 4)
306 	toosmall (_("menuitem header"));
307 
308       mi = (struct menuitem *) res_alloc (sizeof *mi);
309       mi->state = 0;
310       mi->help = 0;
311 
312       flags = get_16 (big_endian, data);
313       mi->type = flags &~ (MENUITEM_POPUP | MENUITEM_ENDMENU);
314 
315       if ((flags & MENUITEM_POPUP) == 0)
316 	stroff = 4;
317       else
318 	stroff = 2;
319 
320       if (length < stroff + 2)
321 	toosmall (_("menuitem header"));
322 
323       if (get_16 (big_endian, data + stroff) == 0)
324 	{
325 	  slen = 0;
326 	  mi->text = NULL;
327 	}
328       else
329 	mi->text = get_unicode (data + stroff, length - stroff, big_endian,
330 				&slen);
331 
332       itemlen = stroff + slen * 2 + 2;
333 
334       if ((flags & MENUITEM_POPUP) == 0)
335 	{
336 	  mi->popup = NULL;
337 	  mi->id = get_16 (big_endian, data + 2);
338 	}
339       else
340 	{
341 	  int subread;
342 
343 	  mi->id = 0;
344 	  mi->popup = bin_to_res_menuitems (data + itemlen, length - itemlen,
345 					    big_endian, &subread);
346 	  itemlen += subread;
347 	}
348 
349       mi->next = NULL;
350       *pp = mi;
351       pp = &mi->next;
352 
353       data += itemlen;
354       length -= itemlen;
355       *read += itemlen;
356 
357       if ((flags & MENUITEM_ENDMENU) != 0)
358 	return first;
359     }
360 
361   return first;
362 }
363 
364 /* Convert menuex items from binary.  */
365 
366 static struct menuitem *
367 bin_to_res_menuexitems (const unsigned char *data, unsigned long length,
368 			int big_endian, int *read)
369 {
370   struct menuitem *first, **pp;
371 
372   first = NULL;
373   pp = &first;
374 
375   *read = 0;
376 
377   while (length > 0)
378     {
379       int flags, slen;
380       unsigned int itemlen;
381       struct menuitem *mi;
382 
383       if (length < 14)
384 	toosmall (_("menuitem header"));
385 
386       mi = (struct menuitem *) res_alloc (sizeof *mi);
387       mi->type = get_32 (big_endian, data);
388       mi->state = get_32 (big_endian, data + 4);
389       mi->id = get_16 (big_endian, data + 8);
390 
391       flags = get_16 (big_endian, data + 10);
392 
393       if (get_16 (big_endian, data + 12) == 0)
394 	{
395 	  slen = 0;
396 	  mi->text = NULL;
397 	}
398       else
399 	mi->text = get_unicode (data + 12, length - 12, big_endian, &slen);
400 
401       itemlen = 12 + slen * 2 + 2;
402       itemlen = (itemlen + 3) &~ 3;
403 
404       if ((flags & 1) == 0)
405 	{
406 	  mi->popup = NULL;
407 	  mi->help = 0;
408 	}
409       else
410 	{
411 	  int subread;
412 
413 	  if (length < itemlen + 4)
414 	    toosmall (_("menuitem"));
415 	  mi->help = get_32 (big_endian, data + itemlen);
416 	  itemlen += 4;
417 
418 	  mi->popup = bin_to_res_menuexitems (data + itemlen,
419 					      length - itemlen,
420 					      big_endian, &subread);
421 	  itemlen += subread;
422 	}
423 
424       mi->next = NULL;
425       *pp = mi;
426       pp = &mi->next;
427 
428       data += itemlen;
429       length -= itemlen;
430       *read += itemlen;
431 
432       if ((flags & 0x80) != 0)
433 	return first;
434     }
435 
436   return first;
437 }
438 
439 /* Convert a dialog resource from binary.  */
440 
441 static struct res_resource *
442 bin_to_res_dialog (const unsigned char *data, unsigned long length,
443 		   int big_endian)
444 {
445   int signature;
446   struct dialog *d;
447   int c, sublen, i;
448   unsigned int off;
449   struct dialog_control **pp;
450   struct res_resource *r;
451 
452   if (length < 18)
453     toosmall (_("dialog header"));
454 
455   d = (struct dialog *) res_alloc (sizeof *d);
456 
457   signature = get_16 (big_endian, data + 2);
458   if (signature != 0xffff)
459     {
460       d->ex = NULL;
461       d->style = get_32 (big_endian, data);
462       d->exstyle = get_32 (big_endian, data + 4);
463       off = 8;
464     }
465   else
466     {
467       int version;
468 
469       version = get_16 (big_endian, data);
470       if (version != 1)
471 	fatal (_("unexpected DIALOGEX version %d"), version);
472 
473       d->ex = (struct dialog_ex *) res_alloc (sizeof (struct dialog_ex));
474       d->ex->help = get_32 (big_endian, data + 4);
475       d->exstyle = get_32 (big_endian, data + 8);
476       d->style = get_32 (big_endian, data + 12);
477       off = 16;
478     }
479 
480   if (length < off + 10)
481     toosmall (_("dialog header"));
482 
483   c = get_16 (big_endian, data + off);
484   d->x = get_16  (big_endian, data + off + 2);
485   d->y = get_16 (big_endian, data + off + 4);
486   d->width = get_16 (big_endian, data + off + 6);
487   d->height = get_16 (big_endian, data + off + 8);
488 
489   off += 10;
490 
491   sublen = get_resid (&d->menu, data + off, length - off, big_endian);
492   off += sublen;
493 
494   sublen = get_resid (&d->class, data + off, length - off, big_endian);
495   off += sublen;
496 
497   d->caption = get_unicode (data + off, length - off, big_endian, &sublen);
498   off += sublen * 2 + 2;
499   if (sublen == 0)
500     d->caption = NULL;
501 
502   if ((d->style & DS_SETFONT) == 0)
503     {
504       d->pointsize = 0;
505       d->font = NULL;
506       if (d->ex != NULL)
507 	{
508 	  d->ex->weight = 0;
509 	  d->ex->italic = 0;
510 	  d->ex->charset = 1; /* Default charset.  */
511 	}
512     }
513   else
514     {
515       if (length < off + 2)
516 	toosmall (_("dialog font point size"));
517 
518       d->pointsize = get_16 (big_endian, data + off);
519       off += 2;
520 
521       if (d->ex != NULL)
522 	{
523 	  if (length < off + 4)
524 	    toosmall (_("dialogex font information"));
525 	  d->ex->weight = get_16 (big_endian, data + off);
526 	  d->ex->italic = get_8 (data + off + 2);
527 	  d->ex->charset = get_8 (data + off + 3);
528 	  off += 4;
529 	}
530 
531       d->font = get_unicode (data + off, length - off, big_endian, &sublen);
532       off += sublen * 2 + 2;
533     }
534 
535   d->controls = NULL;
536   pp = &d->controls;
537 
538   for (i = 0; i < c; i++)
539     {
540       struct dialog_control *dc;
541       int datalen;
542 
543       off = (off + 3) &~ 3;
544 
545       dc = (struct dialog_control *) res_alloc (sizeof *dc);
546 
547       if (d->ex == NULL)
548 	{
549 	  if (length < off + 8)
550 	    toosmall (_("dialog control"));
551 
552 	  dc->style = get_32 (big_endian, data + off);
553 	  dc->exstyle = get_32 (big_endian, data + off + 4);
554 	  dc->help = 0;
555 	  off += 8;
556 	}
557       else
558 	{
559 	  if (length < off + 12)
560 	    toosmall (_("dialogex control"));
561 	  dc->help = get_32 (big_endian, data + off);
562 	  dc->exstyle = get_32 (big_endian, data + off + 4);
563 	  dc->style = get_32 (big_endian, data + off + 8);
564 	  off += 12;
565 	}
566 
567       if (length < off + 10)
568 	toosmall (_("dialog control"));
569 
570       dc->x = get_16 (big_endian, data + off);
571       dc->y = get_16 (big_endian, data + off + 2);
572       dc->width = get_16 (big_endian, data + off + 4);
573       dc->height = get_16 (big_endian, data + off + 6);
574 
575       if (d->ex != NULL)
576 	dc->id = get_32 (big_endian, data + off + 8);
577       else
578 	dc->id = get_16 (big_endian, data + off + 8);
579 
580       off += 10 + (d->ex != NULL ? 2 : 0);
581 
582       sublen = get_resid (&dc->class, data + off, length - off, big_endian);
583       off += sublen;
584 
585       sublen = get_resid (&dc->text, data + off, length - off, big_endian);
586       off += sublen;
587 
588       if (length < off + 2)
589 	toosmall (_("dialog control end"));
590 
591       datalen = get_16 (big_endian, data + off);
592       off += 2;
593 
594       if (datalen == 0)
595 	dc->data = NULL;
596       else
597 	{
598 	  off = (off + 3) &~ 3;
599 
600 	  if (length < off + datalen)
601 	    toosmall (_("dialog control data"));
602 
603 	  dc->data = ((struct rcdata_item *)
604 		      res_alloc (sizeof (struct rcdata_item)));
605 	  dc->data->next = NULL;
606 	  dc->data->type = RCDATA_BUFFER;
607 	  dc->data->u.buffer.length = datalen;
608 	  dc->data->u.buffer.data = data + off;
609 
610 	  off += datalen;
611 	}
612 
613       dc->next = NULL;
614       *pp = dc;
615       pp = &dc->next;
616     }
617 
618   r = (struct res_resource *) res_alloc (sizeof *r);
619   r->type = RES_TYPE_DIALOG;
620   r->u.dialog = d;
621 
622   return r;
623 }
624 
625 /* Convert a stringtable resource from binary.  */
626 
627 static struct res_resource *
628 bin_to_res_string (const unsigned char *data, unsigned long length,
629 		   int big_endian)
630 {
631   struct stringtable *st;
632   int i;
633   struct res_resource *r;
634 
635   st = (struct stringtable *) res_alloc (sizeof *st);
636 
637   for (i = 0; i < 16; i++)
638     {
639       unsigned int slen;
640 
641       if (length < 2)
642 	toosmall (_("stringtable string length"));
643       slen = get_16 (big_endian, data);
644       st->strings[i].length = slen;
645 
646       if (slen > 0)
647 	{
648 	  unichar *s;
649 	  unsigned int j;
650 
651 	  if (length < 2 + 2 * slen)
652 	    toosmall (_("stringtable string"));
653 
654 	  s = (unichar *) res_alloc (slen * sizeof (unichar));
655 	  st->strings[i].string = s;
656 
657 	  for (j = 0; j < slen; j++)
658 	    s[j] = get_16 (big_endian, data + 2 + j * 2);
659 	}
660 
661       data += 2 + 2 * slen;
662       length -= 2 + 2 * slen;
663     }
664 
665   r = (struct res_resource *) res_alloc (sizeof *r);
666   r->type = RES_TYPE_STRINGTABLE;
667   r->u.stringtable = st;
668 
669   return r;
670 }
671 
672 /* Convert a fontdir resource from binary.  */
673 
674 static struct res_resource *
675 bin_to_res_fontdir (const unsigned char *data, unsigned long length,
676 		    int big_endian)
677 {
678   int c, i;
679   struct fontdir *first, **pp;
680   struct res_resource *r;
681 
682   if (length < 2)
683     toosmall (_("fontdir header"));
684 
685   c = get_16 (big_endian, data);
686 
687   first = NULL;
688   pp = &first;
689 
690   for (i = 0; i < c; i++)
691     {
692       struct fontdir *fd;
693       unsigned int off;
694 
695       if (length < 56)
696 	toosmall (_("fontdir"));
697 
698       fd = (struct fontdir *) res_alloc (sizeof *fd);
699       fd->index = get_16 (big_endian, data);
700 
701       /* To work out the length of the fontdir data, we must get the
702          length of the device name and face name strings, even though
703          we don't store them in the fontdir structure.  The
704          documentation says that these are NULL terminated char
705          strings, not Unicode strings.  */
706 
707       off = 56;
708 
709       while (off < length && data[off] != '\0')
710 	++off;
711       if (off >= length)
712 	toosmall (_("fontdir device name"));
713       ++off;
714 
715       while (off < length && data[off] != '\0')
716 	++off;
717       if (off >= length)
718 	toosmall (_("fontdir face name"));
719       ++off;
720 
721       fd->length = off;
722       fd->data = data;
723 
724       fd->next = NULL;
725       *pp = fd;
726       pp = &fd->next;
727 
728       /* The documentation does not indicate that any rounding is
729          required.  */
730 
731       data += off;
732       length -= off;
733     }
734 
735   r = (struct res_resource *) res_alloc (sizeof *r);
736   r->type = RES_TYPE_FONTDIR;
737   r->u.fontdir = first;
738 
739   return r;
740 }
741 
742 /* Convert an accelerators resource from binary.  */
743 
744 static struct res_resource *
745 bin_to_res_accelerators (const unsigned char *data, unsigned long length,
746 			 int big_endian)
747 {
748   struct accelerator *first, **pp;
749   struct res_resource *r;
750 
751   first = NULL;
752   pp = &first;
753 
754   while (1)
755     {
756       struct accelerator *a;
757 
758       if (length < 8)
759 	toosmall (_("accelerator"));
760 
761       a = (struct accelerator *) res_alloc (sizeof *a);
762 
763       a->flags = get_16 (big_endian, data);
764       a->key = get_16 (big_endian, data + 2);
765       a->id = get_16 (big_endian, data + 4);
766 
767       a->next = NULL;
768       *pp = a;
769       pp = &a->next;
770 
771       if ((a->flags & ACC_LAST) != 0)
772 	break;
773 
774       data += 8;
775       length -= 8;
776     }
777 
778   r = (struct res_resource *) res_alloc (sizeof *r);
779   r->type = RES_TYPE_ACCELERATOR;
780   r->u.acc = first;
781 
782   return r;
783 }
784 
785 /* Convert an rcdata resource from binary.  */
786 
787 static struct res_resource *
788 bin_to_res_rcdata (const unsigned char *data, unsigned long length,
789 		   int big_endian ATTRIBUTE_UNUSED)
790 {
791   struct rcdata_item *ri;
792   struct res_resource *r;
793 
794   ri = (struct rcdata_item *) res_alloc (sizeof *ri);
795 
796   ri->next = NULL;
797   ri->type = RCDATA_BUFFER;
798   ri->u.buffer.length = length;
799   ri->u.buffer.data = data;
800 
801   r = (struct res_resource *) res_alloc (sizeof *r);
802   r->type = RES_TYPE_RCDATA;
803   r->u.rcdata = ri;
804 
805   return r;
806 }
807 
808 /* Convert a group cursor resource from binary.  */
809 
810 static struct res_resource *
811 bin_to_res_group_cursor (const unsigned char *data, unsigned long length,
812 			 int big_endian)
813 {
814   int type, c, i;
815   struct group_cursor *first, **pp;
816   struct res_resource *r;
817 
818   if (length < 6)
819     toosmall (_("group cursor header"));
820 
821   type = get_16 (big_endian, data + 2);
822   if (type != 2)
823     fatal (_("unexpected group cursor type %d"), type);
824 
825   c = get_16 (big_endian, data + 4);
826 
827   data += 6;
828   length -= 6;
829 
830   first = NULL;
831   pp = &first;
832 
833   for (i = 0; i < c; i++)
834     {
835       struct group_cursor *gc;
836 
837       if (length < 14)
838 	toosmall (_("group cursor"));
839 
840       gc = (struct group_cursor *) res_alloc (sizeof *gc);
841 
842       gc->width = get_16 (big_endian, data);
843       gc->height = get_16 (big_endian, data + 2);
844       gc->planes = get_16 (big_endian, data + 4);
845       gc->bits = get_16 (big_endian, data + 6);
846       gc->bytes = get_32 (big_endian, data + 8);
847       gc->index = get_16 (big_endian, data + 12);
848 
849       gc->next = NULL;
850       *pp = gc;
851       pp = &gc->next;
852 
853       data += 14;
854       length -= 14;
855     }
856 
857   r = (struct res_resource *) res_alloc (sizeof *r);
858   r->type = RES_TYPE_GROUP_CURSOR;
859   r->u.group_cursor = first;
860 
861   return r;
862 }
863 
864 /* Convert a group icon resource from binary.  */
865 
866 static struct res_resource *
867 bin_to_res_group_icon (const unsigned char *data, unsigned long length,
868 		       int big_endian)
869 {
870   int type, c, i;
871   struct group_icon *first, **pp;
872   struct res_resource *r;
873 
874   if (length < 6)
875     toosmall (_("group icon header"));
876 
877   type = get_16 (big_endian, data + 2);
878   if (type != 1)
879     fatal (_("unexpected group icon type %d"), type);
880 
881   c = get_16 (big_endian, data + 4);
882 
883   data += 6;
884   length -= 6;
885 
886   first = NULL;
887   pp = &first;
888 
889   for (i = 0; i < c; i++)
890     {
891       struct group_icon *gi;
892 
893       if (length < 14)
894 	toosmall (_("group icon"));
895 
896       gi = (struct group_icon *) res_alloc (sizeof *gi);
897 
898       gi->width = data[0];
899       gi->height = data[1];
900       gi->colors = data[2];
901       gi->planes = get_16 (big_endian, data + 4);
902       gi->bits = get_16 (big_endian, data + 6);
903       gi->bytes = get_32 (big_endian, data + 8);
904       gi->index = get_16 (big_endian, data + 12);
905 
906       gi->next = NULL;
907       *pp = gi;
908       pp = &gi->next;
909 
910       data += 14;
911       length -= 14;
912     }
913 
914   r = (struct res_resource *) res_alloc (sizeof *r);
915   r->type = RES_TYPE_GROUP_ICON;
916   r->u.group_icon = first;
917 
918   return r;
919 }
920 
921 /* Extract data from a version header.  If KEY is not NULL, then the
922    key must be KEY; otherwise, the key is returned in *PKEY.  This
923    sets *LEN to the total length, *VALLEN to the value length, *TYPE
924    to the type, and *OFF to the offset to the children.  */
925 
926 static void
927 get_version_header (const unsigned char *data, unsigned long length,
928 		    int big_endian, const char *key, unichar **pkey,
929 		    int *len, int *vallen, int *type, int *off)
930 {
931   if (length < 8)
932     toosmall (key);
933 
934   *len = get_16 (big_endian, data);
935   *vallen = get_16 (big_endian, data + 2);
936   *type = get_16 (big_endian, data + 4);
937 
938   *off = 6;
939 
940   length -= 6;
941   data += 6;
942 
943   if (key == NULL)
944     {
945       int sublen;
946 
947       *pkey = get_unicode (data, length, big_endian, &sublen);
948       *off += sublen * 2 + 2;
949     }
950   else
951     {
952       while (1)
953 	{
954 	  if (length < 2)
955 	    toosmall (key);
956 	  if (get_16 (big_endian, data) != (unsigned char) *key)
957 	    fatal (_("unexpected version string"));
958 
959 	  *off += 2;
960 	  length -= 2;
961 	  data += 2;
962 
963 	  if (*key == '\0')
964 	    break;
965 
966 	  ++key;
967 	}
968     }
969 
970   *off = (*off + 3) &~ 3;
971 }
972 
973 /* Convert a version resource from binary.  */
974 
975 static struct res_resource *
976 bin_to_res_version (const unsigned char *data, unsigned long length,
977 		    int big_endian)
978 {
979   int verlen, vallen, type, off;
980   struct fixed_versioninfo *fi;
981   struct ver_info *first, **pp;
982   struct versioninfo *v;
983   struct res_resource *r;
984 
985   get_version_header (data, length, big_endian, "VS_VERSION_INFO",
986 		      (unichar **) NULL, &verlen, &vallen, &type, &off);
987 
988   if ((unsigned int) verlen != length)
989     fatal (_("version length %d does not match resource length %lu"),
990 	   verlen, length);
991 
992   if (type != 0)
993     fatal (_("unexpected version type %d"), type);
994 
995   data += off;
996   length -= off;
997 
998   if (vallen == 0)
999     fi = NULL;
1000   else
1001     {
1002       unsigned long signature, fiv;
1003 
1004       if (vallen != 52)
1005 	fatal (_("unexpected fixed version information length %d"), vallen);
1006 
1007       if (length < 52)
1008 	toosmall (_("fixed version info"));
1009 
1010       signature = get_32 (big_endian, data);
1011       if (signature != 0xfeef04bd)
1012 	fatal (_("unexpected fixed version signature %lu"), signature);
1013 
1014       fiv = get_32 (big_endian, data + 4);
1015       if (fiv != 0 && fiv != 0x10000)
1016 	fatal (_("unexpected fixed version info version %lu"), fiv);
1017 
1018       fi = (struct fixed_versioninfo *) res_alloc (sizeof *fi);
1019 
1020       fi->file_version_ms = get_32 (big_endian, data + 8);
1021       fi->file_version_ls = get_32 (big_endian, data + 12);
1022       fi->product_version_ms = get_32 (big_endian, data + 16);
1023       fi->product_version_ls = get_32 (big_endian, data + 20);
1024       fi->file_flags_mask = get_32 (big_endian, data + 24);
1025       fi->file_flags = get_32 (big_endian, data + 28);
1026       fi->file_os = get_32 (big_endian, data + 32);
1027       fi->file_type = get_32 (big_endian, data + 36);
1028       fi->file_subtype = get_32 (big_endian, data + 40);
1029       fi->file_date_ms = get_32 (big_endian, data + 44);
1030       fi->file_date_ls = get_32 (big_endian, data + 48);
1031 
1032       data += 52;
1033       length -= 52;
1034     }
1035 
1036   first = NULL;
1037   pp = &first;
1038 
1039   while (length > 0)
1040     {
1041       struct ver_info *vi;
1042       int ch;
1043 
1044       if (length < 8)
1045 	toosmall (_("version var info"));
1046 
1047       vi = (struct ver_info *) res_alloc (sizeof *vi);
1048 
1049       ch = get_16 (big_endian, data + 6);
1050 
1051       if (ch == 'S')
1052 	{
1053 	  struct ver_stringinfo **ppvs;
1054 
1055 	  vi->type = VERINFO_STRING;
1056 
1057 	  get_version_header (data, length, big_endian, "StringFileInfo",
1058 			      (unichar **) NULL, &verlen, &vallen, &type,
1059 			      &off);
1060 
1061 	  if (vallen != 0)
1062 	    fatal (_("unexpected stringfileinfo value length %d"), vallen);
1063 
1064 	  data += off;
1065 	  length -= off;
1066 
1067 	  get_version_header (data, length, big_endian, (const char *) NULL,
1068 			      &vi->u.string.language, &verlen, &vallen,
1069 			      &type, &off);
1070 
1071 	  if (vallen != 0)
1072 	    fatal (_("unexpected version stringtable value length %d"), vallen);
1073 
1074 	  data += off;
1075 	  length -= off;
1076 	  verlen -= off;
1077 
1078 	  vi->u.string.strings = NULL;
1079 	  ppvs = &vi->u.string.strings;
1080 
1081 	  /* It's convenient to round verlen to a 4 byte alignment,
1082              since we round the subvariables in the loop.  */
1083 	  verlen = (verlen + 3) &~ 3;
1084 
1085 	  while (verlen > 0)
1086 	    {
1087 	      struct ver_stringinfo *vs;
1088 	      int subverlen, vslen, valoff;
1089 
1090 	      vs = (struct ver_stringinfo *) res_alloc (sizeof *vs);
1091 
1092 	      get_version_header (data, length, big_endian,
1093 				  (const char *) NULL, &vs->key, &subverlen,
1094 				  &vallen, &type, &off);
1095 
1096 	      subverlen = (subverlen + 3) &~ 3;
1097 
1098 	      data += off;
1099 	      length -= off;
1100 
1101 	      vs->value = get_unicode (data, length, big_endian, &vslen);
1102 	      valoff = vslen * 2 + 2;
1103 	      valoff = (valoff + 3) &~ 3;
1104 
1105 	      if (off + valoff != subverlen)
1106 		fatal (_("unexpected version string length %d != %d + %d"),
1107 		       subverlen, off, valoff);
1108 
1109 	      vs->next = NULL;
1110 	      *ppvs = vs;
1111 	      ppvs = &vs->next;
1112 
1113 	      data += valoff;
1114 	      length -= valoff;
1115 
1116 	      if (verlen < subverlen)
1117 		fatal (_("unexpected version string length %d < %d"),
1118 		       verlen, subverlen);
1119 
1120 	      verlen -= subverlen;
1121 	    }
1122 	}
1123       else if (ch == 'V')
1124 	{
1125 	  struct ver_varinfo **ppvv;
1126 
1127 	  vi->type = VERINFO_VAR;
1128 
1129 	  get_version_header (data, length, big_endian, "VarFileInfo",
1130 			      (unichar **) NULL, &verlen, &vallen, &type,
1131 			      &off);
1132 
1133 	  if (vallen != 0)
1134 	    fatal (_("unexpected varfileinfo value length %d"), vallen);
1135 
1136 	  data += off;
1137 	  length -= off;
1138 
1139 	  get_version_header (data, length, big_endian, (const char *) NULL,
1140 			      &vi->u.var.key, &verlen, &vallen, &type, &off);
1141 
1142 	  data += off;
1143 	  length -= off;
1144 
1145 	  vi->u.var.var = NULL;
1146 	  ppvv = &vi->u.var.var;
1147 
1148 	  while (vallen > 0)
1149 	    {
1150 	      struct ver_varinfo *vv;
1151 
1152 	      if (length < 4)
1153 		toosmall (_("version varfileinfo"));
1154 
1155 	      vv = (struct ver_varinfo *) res_alloc (sizeof *vv);
1156 
1157 	      vv->language = get_16 (big_endian, data);
1158 	      vv->charset = get_16 (big_endian, data + 2);
1159 
1160 	      vv->next = NULL;
1161 	      *ppvv = vv;
1162 	      ppvv = &vv->next;
1163 
1164 	      data += 4;
1165 	      length -= 4;
1166 
1167 	      if (vallen < 4)
1168 		fatal (_("unexpected version value length %d"), vallen);
1169 
1170 	      vallen -= 4;
1171 	    }
1172 	}
1173       else
1174 	fatal (_("unexpected version string"));
1175 
1176       vi->next = NULL;
1177       *pp = vi;
1178       pp = &vi->next;
1179     }
1180 
1181   v = (struct versioninfo *) res_alloc (sizeof *v);
1182   v->fixed = fi;
1183   v->var = first;
1184 
1185   r = (struct res_resource *) res_alloc (sizeof *r);
1186   r->type = RES_TYPE_VERSIONINFO;
1187   r->u.versioninfo = v;
1188 
1189   return r;
1190 }
1191 
1192 /* Convert an arbitrary user defined resource from binary.  */
1193 
1194 static struct res_resource *
1195 bin_to_res_userdata (const unsigned char *data, unsigned long length,
1196 		     int big_endian ATTRIBUTE_UNUSED)
1197 {
1198   struct rcdata_item *ri;
1199   struct res_resource *r;
1200 
1201   ri = (struct rcdata_item *) res_alloc (sizeof *ri);
1202 
1203   ri->next = NULL;
1204   ri->type = RCDATA_BUFFER;
1205   ri->u.buffer.length = length;
1206   ri->u.buffer.data = data;
1207 
1208   r = (struct res_resource *) res_alloc (sizeof *r);
1209   r->type = RES_TYPE_USERDATA;
1210   r->u.rcdata = ri;
1211 
1212   return r;
1213 }
1214 
1215 /* Macros to swap out values.  */
1216 
1217 #define put_8(v, s)      (*((unsigned char *) (s)) = (unsigned char) (v))
1218 #define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
1219 #define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
1220 
1221 /* Local functions used to convert resources to binary format.  */
1222 
1223 static void dword_align_bin (struct bindata ***, unsigned long *);
1224 static struct bindata *resid_to_bin (struct res_id, int);
1225 static struct bindata *unicode_to_bin (const unichar *, int);
1226 static struct bindata *res_to_bin_accelerator
1227   (const struct accelerator *, int);
1228 static struct bindata *res_to_bin_cursor
1229   (const struct cursor *, int);
1230 static struct bindata *res_to_bin_group_cursor
1231   (const struct group_cursor *, int);
1232 static struct bindata *res_to_bin_dialog
1233   (const struct dialog *, int);
1234 static struct bindata *res_to_bin_fontdir
1235   (const struct fontdir *, int);
1236 static struct bindata *res_to_bin_group_icon
1237   (const struct group_icon *, int);
1238 static struct bindata *res_to_bin_menu
1239   (const struct menu *, int);
1240 static struct bindata *res_to_bin_menuitems
1241   (const struct menuitem *, int);
1242 static struct bindata *res_to_bin_menuexitems
1243   (const struct menuitem *, int);
1244 static struct bindata *res_to_bin_rcdata
1245   (const struct rcdata_item *, int);
1246 static struct bindata *res_to_bin_stringtable
1247   (const struct stringtable *, int);
1248 static struct bindata *string_to_unicode_bin (const char *, int);
1249 static struct bindata *res_to_bin_versioninfo
1250   (const struct versioninfo *, int);
1251 static struct bindata *res_to_bin_generic
1252   (unsigned long, const unsigned char *);
1253 
1254 /* Convert a resource to binary.  */
1255 
1256 struct bindata *
1257 res_to_bin (const struct res_resource *res, int big_endian)
1258 {
1259   switch (res->type)
1260     {
1261     default:
1262       abort ();
1263     case RES_TYPE_BITMAP:
1264     case RES_TYPE_FONT:
1265     case RES_TYPE_ICON:
1266     case RES_TYPE_MESSAGETABLE:
1267       return res_to_bin_generic (res->u.data.length, res->u.data.data);
1268     case RES_TYPE_ACCELERATOR:
1269       return res_to_bin_accelerator (res->u.acc, big_endian);
1270     case RES_TYPE_CURSOR:
1271       return res_to_bin_cursor (res->u.cursor, big_endian);
1272     case RES_TYPE_GROUP_CURSOR:
1273       return res_to_bin_group_cursor (res->u.group_cursor, big_endian);
1274     case RES_TYPE_DIALOG:
1275       return res_to_bin_dialog (res->u.dialog, big_endian);
1276     case RES_TYPE_FONTDIR:
1277       return res_to_bin_fontdir (res->u.fontdir, big_endian);
1278     case RES_TYPE_GROUP_ICON:
1279       return res_to_bin_group_icon (res->u.group_icon, big_endian);
1280     case RES_TYPE_MENU:
1281       return res_to_bin_menu (res->u.menu, big_endian);
1282     case RES_TYPE_RCDATA:
1283       return res_to_bin_rcdata (res->u.rcdata, big_endian);
1284     case RES_TYPE_STRINGTABLE:
1285       return res_to_bin_stringtable (res->u.stringtable, big_endian);
1286     case RES_TYPE_USERDATA:
1287       return res_to_bin_rcdata (res->u.rcdata, big_endian);
1288     case RES_TYPE_VERSIONINFO:
1289       return res_to_bin_versioninfo (res->u.versioninfo, big_endian);
1290     }
1291 }
1292 
1293 /* Align to a 32 bit boundary.  PPP points to the of a list of bindata
1294    structures.  LENGTH points to the length of the structures.  If
1295    necessary, this adds a new bindata to bring length up to a 32 bit
1296    boundary.  It updates *PPP and *LENGTH.  */
1297 
1298 static void
1299 dword_align_bin (struct bindata ***ppp, unsigned long *length)
1300 {
1301   int add;
1302   struct bindata *d;
1303 
1304   if ((*length & 3) == 0)
1305     return;
1306 
1307   add = 4 - (*length & 3);
1308 
1309   d = (struct bindata *) reswr_alloc (sizeof *d);
1310   d->length = add;
1311   d->data = (unsigned char *) reswr_alloc (add);
1312   memset (d->data, 0, add);
1313 
1314   d->next = NULL;
1315   **ppp = d;
1316   *ppp = &(**ppp)->next;
1317 
1318   *length += add;
1319 }
1320 
1321 /* Convert a resource ID to binary.  This always returns exactly one
1322    bindata structure.  */
1323 
1324 static struct bindata *
1325 resid_to_bin (struct res_id id, int big_endian)
1326 {
1327   struct bindata *d;
1328 
1329   d = (struct bindata *) reswr_alloc (sizeof *d);
1330 
1331   if (! id.named)
1332     {
1333       d->length = 4;
1334       d->data = (unsigned char *) reswr_alloc (d->length);
1335       put_16 (big_endian, 0xffff, d->data);
1336       put_16 (big_endian, id.u.id, d->data + 2);
1337     }
1338   else
1339     {
1340       int i;
1341 
1342       d->length = id.u.n.length * 2 + 2;
1343       d->data = (unsigned char *) reswr_alloc (d->length);
1344       for (i = 0; i < id.u.n.length; i++)
1345 	put_16 (big_endian, id.u.n.name[i], d->data + i * 2);
1346       put_16 (big_endian, 0, d->data + i * 2);
1347     }
1348 
1349   d->next = NULL;
1350 
1351   return d;
1352 }
1353 
1354 /* Convert a null terminated unicode string to binary.  This always
1355    returns exactly one bindata structure.  */
1356 
1357 static struct bindata *
1358 unicode_to_bin (const unichar *str, int big_endian)
1359 {
1360   int len;
1361   struct bindata *d;
1362 
1363   len = 0;
1364   if (str != NULL)
1365     {
1366       const unichar *s;
1367 
1368       for (s = str; *s != 0; s++)
1369 	++len;
1370     }
1371 
1372   d = (struct bindata *) reswr_alloc (sizeof *d);
1373   d->length = len * 2 + 2;
1374   d->data = (unsigned char *) reswr_alloc (d->length);
1375 
1376   if (str == NULL)
1377     put_16 (big_endian, 0, d->data);
1378   else
1379     {
1380       const unichar *s;
1381       int i;
1382 
1383       for (s = str, i = 0; *s != 0; s++, i++)
1384 	put_16 (big_endian, *s, d->data + i * 2);
1385       put_16 (big_endian, 0, d->data + i * 2);
1386     }
1387 
1388   d->next = NULL;
1389 
1390   return d;
1391 }
1392 
1393 /* Convert an accelerator resource to binary.  */
1394 
1395 static struct bindata *
1396 res_to_bin_accelerator (const struct accelerator *accelerators,
1397 			int big_endian)
1398 {
1399   struct bindata *first, **pp;
1400   const struct accelerator *a;
1401 
1402   first = NULL;
1403   pp = &first;
1404 
1405   for (a = accelerators; a != NULL; a = a->next)
1406     {
1407       struct bindata *d;
1408 
1409       d = (struct bindata *) reswr_alloc (sizeof *d);
1410       d->length = 8;
1411       d->data = (unsigned char *) reswr_alloc (d->length);
1412 
1413       put_16 (big_endian,
1414 	      a->flags | (a->next != NULL ? 0 : ACC_LAST),
1415 	      d->data);
1416       put_16 (big_endian, a->key, d->data + 2);
1417       put_16 (big_endian, a->id, d->data + 4);
1418       put_16 (big_endian, 0, d->data + 6);
1419 
1420       d->next = NULL;
1421       *pp = d;
1422       pp = &d->next;
1423     }
1424 
1425   return first;
1426 }
1427 
1428 /* Convert a cursor resource to binary.  */
1429 
1430 static struct bindata *
1431 res_to_bin_cursor (const struct cursor *c, int big_endian)
1432 {
1433   struct bindata *d;
1434 
1435   d = (struct bindata *) reswr_alloc (sizeof *d);
1436   d->length = 4;
1437   d->data = (unsigned char *) reswr_alloc (d->length);
1438 
1439   put_16 (big_endian, c->xhotspot, d->data);
1440   put_16 (big_endian, c->yhotspot, d->data + 2);
1441 
1442   d->next = (struct bindata *) reswr_alloc (sizeof *d);
1443   d->next->length = c->length;
1444   d->next->data = (unsigned char *) c->data;
1445   d->next->next = NULL;
1446 
1447   return d;
1448 }
1449 
1450 /* Convert a group cursor resource to binary.  */
1451 
1452 static struct bindata *
1453 res_to_bin_group_cursor (const struct group_cursor *group_cursors,
1454 			 int big_endian)
1455 {
1456   struct bindata *first, **pp;
1457   int c;
1458   const struct group_cursor *gc;
1459 
1460   first = (struct bindata *) reswr_alloc (sizeof *first);
1461   first->length = 6;
1462   first->data = (unsigned char *) reswr_alloc (first->length);
1463 
1464   put_16 (big_endian, 0, first->data);
1465   put_16 (big_endian, 2, first->data + 2);
1466 
1467   first->next = NULL;
1468   pp = &first->next;
1469 
1470   c = 0;
1471   for (gc = group_cursors; gc != NULL; gc = gc->next)
1472     {
1473       struct bindata *d;
1474 
1475       ++c;
1476 
1477       d = (struct bindata *) reswr_alloc (sizeof *d);
1478       d->length = 14;
1479       d->data = (unsigned char *) reswr_alloc (d->length);
1480 
1481       put_16 (big_endian, gc->width, d->data);
1482       put_16 (big_endian, gc->height, d->data + 2);
1483       put_16 (big_endian, gc->planes, d->data + 4);
1484       put_16 (big_endian, gc->bits, d->data + 6);
1485       put_32 (big_endian, gc->bytes, d->data + 8);
1486       put_16 (big_endian, gc->index, d->data + 12);
1487 
1488       d->next = NULL;
1489       *pp = d;
1490       pp = &d->next;
1491     }
1492 
1493   put_16 (big_endian, c, first->data + 4);
1494 
1495   return first;
1496 }
1497 
1498 /* Convert a dialog resource to binary.  */
1499 
1500 static struct bindata *
1501 res_to_bin_dialog (const struct dialog *dialog, int big_endian)
1502 {
1503   int dialogex;
1504   struct bindata *first, **pp;
1505   unsigned long length;
1506   int off, c;
1507   struct dialog_control *dc;
1508 
1509   dialogex = extended_dialog (dialog);
1510 
1511   first = (struct bindata *) reswr_alloc (sizeof *first);
1512   first->length = dialogex ? 26 : 18;
1513   first->data = (unsigned char *) reswr_alloc (first->length);
1514 
1515   length = first->length;
1516 
1517   if (! dialogex)
1518     {
1519       put_32 (big_endian, dialog->style, first->data);
1520       put_32 (big_endian, dialog->exstyle, first->data + 4);
1521       off = 8;
1522     }
1523   else
1524     {
1525       put_16 (big_endian, 1, first->data);
1526       put_16 (big_endian, 0xffff, first->data + 2);
1527 
1528       if (dialog->ex == NULL)
1529 	put_32 (big_endian, 0, first->data + 4);
1530       else
1531 	put_32 (big_endian, dialog->ex->help, first->data + 4);
1532       put_32 (big_endian, dialog->exstyle, first->data + 8);
1533       put_32 (big_endian, dialog->style, first->data + 12);
1534       off = 16;
1535     }
1536 
1537   put_16 (big_endian, dialog->x, first->data + off + 2);
1538   put_16 (big_endian, dialog->y, first->data + off + 4);
1539   put_16 (big_endian, dialog->width, first->data + off + 6);
1540   put_16 (big_endian, dialog->height, first->data + off + 8);
1541 
1542   pp = &first->next;
1543 
1544   *pp = resid_to_bin (dialog->menu, big_endian);
1545   length += (*pp)->length;
1546   pp = &(*pp)->next;
1547 
1548   *pp = resid_to_bin (dialog->class, big_endian);
1549   length += (*pp)->length;
1550   pp = &(*pp)->next;
1551 
1552   *pp = unicode_to_bin (dialog->caption, big_endian);
1553   length += (*pp)->length;
1554   pp = &(*pp)->next;
1555 
1556   if ((dialog->style & DS_SETFONT) != 0)
1557     {
1558       struct bindata *d;
1559 
1560       d = (struct bindata *) reswr_alloc (sizeof *d);
1561       d->length = dialogex ? 6 : 2;
1562       d->data = (unsigned char *) reswr_alloc (d->length);
1563 
1564       length += d->length;
1565 
1566       put_16 (big_endian, dialog->pointsize, d->data);
1567 
1568       if (dialogex)
1569 	{
1570 	  if (dialog->ex == NULL)
1571 	    {
1572 	      put_16 (big_endian, 0, d->data + 2);
1573 	      put_8 (0, d->data + 4);
1574 	      put_8 (1, d->data + 5);
1575 	    }
1576 	  else
1577 	    {
1578 	      put_16 (big_endian, dialog->ex->weight, d->data + 2);
1579 	      put_8 (dialog->ex->italic, d->data + 4);
1580 	      put_8 (dialog->ex->charset, d->data + 5);
1581 	    }
1582 	}
1583 
1584       *pp = d;
1585       pp = &d->next;
1586 
1587       *pp = unicode_to_bin (dialog->font, big_endian);
1588       length += (*pp)->length;
1589       pp = &(*pp)->next;
1590     }
1591 
1592   c = 0;
1593   for (dc = dialog->controls; dc != NULL; dc = dc->next)
1594     {
1595       struct bindata *d;
1596       int dcoff;
1597 
1598       ++c;
1599 
1600       dword_align_bin (&pp, &length);
1601 
1602       d = (struct bindata *) reswr_alloc (sizeof *d);
1603       d->length = dialogex ? 24 : 18;
1604       d->data = (unsigned char *) reswr_alloc (d->length);
1605 
1606       length += d->length;
1607 
1608       if (! dialogex)
1609 	{
1610 	  put_32 (big_endian, dc->style, d->data);
1611 	  put_32 (big_endian, dc->exstyle, d->data + 4);
1612 	  dcoff = 8;
1613 	}
1614       else
1615 	{
1616 	  put_32 (big_endian, dc->help, d->data);
1617 	  put_32 (big_endian, dc->exstyle, d->data + 4);
1618 	  put_32 (big_endian, dc->style, d->data + 8);
1619 	  dcoff = 12;
1620 	}
1621 
1622       put_16 (big_endian, dc->x, d->data + dcoff);
1623       put_16 (big_endian, dc->y, d->data + dcoff + 2);
1624       put_16 (big_endian, dc->width, d->data + dcoff + 4);
1625       put_16 (big_endian, dc->height, d->data + dcoff + 6);
1626 
1627       if (dialogex)
1628 	put_32 (big_endian, dc->id, d->data + dcoff + 8);
1629       else
1630 	put_16 (big_endian, dc->id, d->data + dcoff + 8);
1631 
1632       *pp = d;
1633       pp = &d->next;
1634 
1635       *pp = resid_to_bin (dc->class, big_endian);
1636       length += (*pp)->length;
1637       pp = &(*pp)->next;
1638 
1639       *pp = resid_to_bin (dc->text, big_endian);
1640       length += (*pp)->length;
1641       pp = &(*pp)->next;
1642 
1643       d = (struct bindata *) reswr_alloc (sizeof *d);
1644       d->length = 2;
1645       d->data = (unsigned char *) reswr_alloc (d->length);
1646 
1647       length += 2;
1648 
1649       d->next = NULL;
1650       *pp = d;
1651       pp = &d->next;
1652 
1653       if (dc->data == NULL)
1654 	put_16 (big_endian, 0, d->data);
1655       else
1656 	{
1657 	  unsigned long sublen;
1658 
1659 	  dword_align_bin (&pp, &length);
1660 
1661 	  *pp = res_to_bin_rcdata (dc->data, big_endian);
1662 	  sublen = 0;
1663 	  while (*pp != NULL)
1664 	    {
1665 	      sublen += (*pp)->length;
1666 	      pp = &(*pp)->next;
1667 	    }
1668 
1669 	  put_16 (big_endian, sublen, d->data);
1670 
1671 	  length += sublen;
1672 	}
1673     }
1674   put_16 (big_endian, c, first->data + off);
1675 
1676   return first;
1677 }
1678 
1679 /* Convert a fontdir resource to binary.  */
1680 
1681 static struct bindata *
1682 res_to_bin_fontdir (const struct fontdir *fontdirs, int big_endian)
1683 {
1684   struct bindata *first, **pp;
1685   int c;
1686   const struct fontdir *fd;
1687 
1688   first = (struct bindata *) reswr_alloc (sizeof *first);
1689   first->length = 2;
1690   first->data = (unsigned char *) reswr_alloc (first->length);
1691 
1692   first->next = NULL;
1693   pp = &first->next;
1694 
1695   c = 0;
1696   for (fd = fontdirs; fd != NULL; fd = fd->next)
1697     {
1698       struct bindata *d;
1699 
1700       ++c;
1701 
1702       d = (struct bindata *) reswr_alloc (sizeof *d);
1703       d->length = 2;
1704       d->data = (unsigned char *) reswr_alloc (d->length);
1705 
1706       put_16 (big_endian, fd->index, d->data);
1707 
1708       *pp = d;
1709       pp = &d->next;
1710 
1711       d = (struct bindata *) reswr_alloc (sizeof *d);
1712       d->length = fd->length;
1713       d->data = (unsigned char *) fd->data;
1714 
1715       d->next = NULL;
1716       *pp = d;
1717       pp = &d->next;
1718     }
1719 
1720   put_16 (big_endian, c, first->data);
1721 
1722   return first;
1723 }
1724 
1725 /* Convert a group icon resource to binary.  */
1726 
1727 static struct bindata *
1728 res_to_bin_group_icon (const struct group_icon *group_icons, int big_endian)
1729 {
1730   struct bindata *first, **pp;
1731   int c;
1732   const struct group_icon *gi;
1733 
1734   first = (struct bindata *) reswr_alloc (sizeof *first);
1735   first->length = 6;
1736   first->data = (unsigned char *) reswr_alloc (first->length);
1737 
1738   put_16 (big_endian, 0, first->data);
1739   put_16 (big_endian, 1, first->data + 2);
1740 
1741   first->next = NULL;
1742   pp = &first->next;
1743 
1744   c = 0;
1745   for (gi = group_icons; gi != NULL; gi = gi->next)
1746     {
1747       struct bindata *d;
1748 
1749       ++c;
1750 
1751       d = (struct bindata *) reswr_alloc (sizeof *d);
1752       d->length = 14;
1753       d->data = (unsigned char *) reswr_alloc (d->length);
1754 
1755       d->data[0] = gi->width;
1756       d->data[1] = gi->height;
1757       d->data[2] = gi->colors;
1758       d->data[3] = 0;
1759       put_16 (big_endian, gi->planes, d->data + 4);
1760       put_16 (big_endian, gi->bits, d->data + 6);
1761       put_32 (big_endian, gi->bytes, d->data + 8);
1762       put_16 (big_endian, gi->index, d->data + 12);
1763 
1764       d->next = NULL;
1765       *pp = d;
1766       pp = &d->next;
1767     }
1768 
1769   put_16 (big_endian, c, first->data + 4);
1770 
1771   return first;
1772 }
1773 
1774 /* Convert a menu resource to binary.  */
1775 
1776 static struct bindata *
1777 res_to_bin_menu (const struct menu *menu, int big_endian)
1778 {
1779   int menuex;
1780   struct bindata *d;
1781 
1782   menuex = extended_menu (menu);
1783 
1784   d = (struct bindata *) reswr_alloc (sizeof *d);
1785   d->length = menuex ? 8 : 4;
1786   d->data = (unsigned char *) reswr_alloc (d->length);
1787 
1788   if (! menuex)
1789     {
1790       put_16 (big_endian, 0, d->data);
1791       put_16 (big_endian, 0, d->data + 2);
1792 
1793       d->next = res_to_bin_menuitems (menu->items, big_endian);
1794     }
1795   else
1796     {
1797       put_16 (big_endian, 1, d->data);
1798       put_16 (big_endian, 4, d->data + 2);
1799       put_32 (big_endian, menu->help, d->data + 4);
1800 
1801       d->next = res_to_bin_menuexitems (menu->items, big_endian);
1802     }
1803 
1804   return d;
1805 }
1806 
1807 /* Convert menu items to binary.  */
1808 
1809 static struct bindata *
1810 res_to_bin_menuitems (const struct menuitem *items, int big_endian)
1811 {
1812   struct bindata *first, **pp;
1813   const struct menuitem *mi;
1814 
1815   first = NULL;
1816   pp = &first;
1817 
1818   for (mi = items; mi != NULL; mi = mi->next)
1819     {
1820       struct bindata *d;
1821       int flags;
1822 
1823       d = (struct bindata *) reswr_alloc (sizeof *d);
1824       d->length = mi->popup == NULL ? 4 : 2;
1825       d->data = (unsigned char *) reswr_alloc (d->length);
1826 
1827       flags = mi->type;
1828       if (mi->next == NULL)
1829 	flags |= MENUITEM_ENDMENU;
1830       if (mi->popup != NULL)
1831 	flags |= MENUITEM_POPUP;
1832 
1833       put_16 (big_endian, flags, d->data);
1834 
1835       if (mi->popup == NULL)
1836 	put_16 (big_endian, mi->id, d->data + 2);
1837 
1838       *pp = d;
1839       pp = &d->next;
1840 
1841       *pp = unicode_to_bin (mi->text, big_endian);
1842       pp = &(*pp)->next;
1843 
1844       if (mi->popup != NULL)
1845 	{
1846 	  *pp = res_to_bin_menuitems (mi->popup, big_endian);
1847 	  while (*pp != NULL)
1848 	    pp = &(*pp)->next;
1849 	}
1850     }
1851 
1852   return first;
1853 }
1854 
1855 /* Convert menuex items to binary.  */
1856 
1857 static struct bindata *
1858 res_to_bin_menuexitems (const struct menuitem *items, int big_endian)
1859 {
1860   struct bindata *first, **pp;
1861   unsigned long length;
1862   const struct menuitem *mi;
1863 
1864   first = NULL;
1865   pp = &first;
1866 
1867   length = 0;
1868 
1869   for (mi = items; mi != NULL; mi = mi->next)
1870     {
1871       struct bindata *d;
1872       int flags;
1873 
1874       dword_align_bin (&pp, &length);
1875 
1876       d = (struct bindata *) reswr_alloc (sizeof *d);
1877       d->length = 12;
1878       d->data = (unsigned char *) reswr_alloc (d->length);
1879 
1880       length += 12;
1881 
1882       put_32 (big_endian, mi->type, d->data);
1883       put_32 (big_endian, mi->state, d->data + 4);
1884       put_16 (big_endian, mi->id, d->data + 8);
1885 
1886       flags = 0;
1887       if (mi->next == NULL)
1888 	flags |= 0x80;
1889       if (mi->popup != NULL)
1890 	flags |= 1;
1891       put_16 (big_endian, flags, d->data + 10);
1892 
1893       *pp = d;
1894       pp = &d->next;
1895 
1896       *pp = unicode_to_bin (mi->text, big_endian);
1897       length += (*pp)->length;
1898       pp = &(*pp)->next;
1899 
1900       if (mi->popup != NULL)
1901 	{
1902 	  dword_align_bin (&pp, &length);
1903 
1904 	  d = (struct bindata *) reswr_alloc (sizeof *d);
1905 	  d->length = 4;
1906 	  d->data = (unsigned char *) reswr_alloc (d->length);
1907 
1908 	  put_32 (big_endian, mi->help, d->data);
1909 
1910 	  *pp = d;
1911 	  pp = &d->next;
1912 
1913 	  *pp = res_to_bin_menuexitems (mi->popup, big_endian);
1914 	  while (*pp != NULL)
1915 	    {
1916 	      length += (*pp)->length;
1917 	      pp = &(*pp)->next;
1918 	    }
1919 	}
1920     }
1921 
1922   return first;
1923 }
1924 
1925 /* Convert an rcdata resource to binary.  This is also used to convert
1926    other information which happens to be stored in rcdata_item lists
1927    to binary.  */
1928 
1929 static struct bindata *
1930 res_to_bin_rcdata (const struct rcdata_item *items, int big_endian)
1931 {
1932   struct bindata *first, **pp;
1933   const struct rcdata_item *ri;
1934 
1935   first = NULL;
1936   pp = &first;
1937 
1938   for (ri = items; ri != NULL; ri = ri->next)
1939     {
1940       struct bindata *d;
1941 
1942       d = (struct bindata *) reswr_alloc (sizeof *d);
1943 
1944       switch (ri->type)
1945 	{
1946 	default:
1947 	  abort ();
1948 
1949 	case RCDATA_WORD:
1950 	  d->length = 2;
1951 	  d->data = (unsigned char *) reswr_alloc (d->length);
1952 	  put_16 (big_endian, ri->u.word, d->data);
1953 	  break;
1954 
1955 	case RCDATA_DWORD:
1956 	  d->length = 4;
1957 	  d->data = (unsigned char *) reswr_alloc (d->length);
1958 	  put_32 (big_endian, ri->u.dword, d->data);
1959 	  break;
1960 
1961 	case RCDATA_STRING:
1962 	  d->length = ri->u.string.length;
1963 	  d->data = (unsigned char *) ri->u.string.s;
1964 	  break;
1965 
1966 	case RCDATA_WSTRING:
1967 	  {
1968 	    unsigned long i;
1969 
1970 	    d->length = ri->u.wstring.length * 2;
1971 	    d->data = (unsigned char *) reswr_alloc (d->length);
1972 	    for (i = 0; i < ri->u.wstring.length; i++)
1973 	      put_16 (big_endian, ri->u.wstring.w[i], d->data + i * 2);
1974 	    break;
1975 	  }
1976 
1977 	case RCDATA_BUFFER:
1978 	  d->length = ri->u.buffer.length;
1979 	  d->data = (unsigned char *) ri->u.buffer.data;
1980 	  break;
1981 	}
1982 
1983       d->next = NULL;
1984       *pp = d;
1985       pp = &d->next;
1986     }
1987 
1988   return first;
1989 }
1990 
1991 /* Convert a stringtable resource to binary.  */
1992 
1993 static struct bindata *
1994 res_to_bin_stringtable (const struct stringtable *st, int big_endian)
1995 {
1996   struct bindata *first, **pp;
1997   int i;
1998 
1999   first = NULL;
2000   pp = &first;
2001 
2002   for (i = 0; i < 16; i++)
2003     {
2004       int slen, j;
2005       struct bindata *d;
2006       unichar *s;
2007 
2008       slen = st->strings[i].length;
2009       s = st->strings[i].string;
2010 
2011       d = (struct bindata *) reswr_alloc (sizeof *d);
2012       d->length = 2 + slen * 2;
2013       d->data = (unsigned char *) reswr_alloc (d->length);
2014 
2015       put_16 (big_endian, slen, d->data);
2016 
2017       for (j = 0; j < slen; j++)
2018 	put_16 (big_endian, s[j], d->data + 2 + j * 2);
2019 
2020       d->next = NULL;
2021       *pp = d;
2022       pp = &d->next;
2023     }
2024 
2025   return first;
2026 }
2027 
2028 /* Convert an ASCII string to a unicode binary string.  This always
2029    returns exactly one bindata structure.  */
2030 
2031 static struct bindata *
2032 string_to_unicode_bin (const char *s, int big_endian)
2033 {
2034   size_t len, i;
2035   struct bindata *d;
2036 
2037   len = strlen (s);
2038 
2039   d = (struct bindata *) reswr_alloc (sizeof *d);
2040   d->length = len * 2 + 2;
2041   d->data = (unsigned char *) reswr_alloc (d->length);
2042 
2043   for (i = 0; i < len; i++)
2044     put_16 (big_endian, s[i], d->data + i * 2);
2045   put_16 (big_endian, 0, d->data + i * 2);
2046 
2047   d->next = NULL;
2048 
2049   return d;
2050 }
2051 
2052 /* Convert a versioninfo resource to binary.  */
2053 
2054 static struct bindata *
2055 res_to_bin_versioninfo (const struct versioninfo *versioninfo, int big_endian)
2056 {
2057   struct bindata *first, **pp;
2058   unsigned long length;
2059   struct ver_info *vi;
2060 
2061   first = (struct bindata *) reswr_alloc (sizeof *first);
2062   first->length = 6;
2063   first->data = (unsigned char *) reswr_alloc (first->length);
2064 
2065   length = 6;
2066 
2067   if (versioninfo->fixed == NULL)
2068     put_16 (big_endian, 0, first->data + 2);
2069   else
2070     put_16 (big_endian, 52, first->data + 2);
2071 
2072   put_16 (big_endian, 0, first->data + 4);
2073 
2074   pp = &first->next;
2075 
2076   *pp = string_to_unicode_bin ("VS_VERSION_INFO", big_endian);
2077   length += (*pp)->length;
2078   pp = &(*pp)->next;
2079 
2080   dword_align_bin (&pp, &length);
2081 
2082   if (versioninfo->fixed != NULL)
2083     {
2084       const struct fixed_versioninfo *fi;
2085       struct bindata *d;
2086 
2087       d = (struct bindata *) reswr_alloc (sizeof *d);
2088       d->length = 52;
2089       d->data = (unsigned char *) reswr_alloc (d->length);
2090 
2091       length += 52;
2092 
2093       fi = versioninfo->fixed;
2094 
2095       put_32 (big_endian, 0xfeef04bd, d->data);
2096       put_32 (big_endian, 0x10000, d->data + 4);
2097       put_32 (big_endian, fi->file_version_ms, d->data + 8);
2098       put_32 (big_endian, fi->file_version_ls, d->data + 12);
2099       put_32 (big_endian, fi->product_version_ms, d->data + 16);
2100       put_32 (big_endian, fi->product_version_ls, d->data + 20);
2101       put_32 (big_endian, fi->file_flags_mask, d->data + 24);
2102       put_32 (big_endian, fi->file_flags, d->data + 28);
2103       put_32 (big_endian, fi->file_os, d->data + 32);
2104       put_32 (big_endian, fi->file_type, d->data + 36);
2105       put_32 (big_endian, fi->file_subtype, d->data + 40);
2106       put_32 (big_endian, fi->file_date_ms, d->data + 44);
2107       put_32 (big_endian, fi->file_date_ls, d->data + 48);
2108 
2109       d->next = NULL;
2110       *pp = d;
2111       pp = &d->next;
2112     }
2113 
2114   for (vi = versioninfo->var; vi != NULL; vi = vi->next)
2115     {
2116       struct bindata *vid;
2117       unsigned long vilen;
2118 
2119       dword_align_bin (&pp, &length);
2120 
2121       vid = (struct bindata *) reswr_alloc (sizeof *vid);
2122       vid->length = 6;
2123       vid->data = (unsigned char *) reswr_alloc (vid->length);
2124 
2125       length += 6;
2126       vilen = 6;
2127 
2128       put_16 (big_endian, 0, vid->data + 2);
2129       put_16 (big_endian, 0, vid->data + 4);
2130 
2131       *pp = vid;
2132       pp = &vid->next;
2133 
2134       switch (vi->type)
2135 	{
2136 	default:
2137 	  abort ();
2138 
2139 	case VERINFO_STRING:
2140 	  {
2141 	    unsigned long hold, vslen;
2142 	    struct bindata *vsd;
2143 	    const struct ver_stringinfo *vs;
2144 
2145 	    *pp = string_to_unicode_bin ("StringFileInfo", big_endian);
2146 	    length += (*pp)->length;
2147 	    vilen += (*pp)->length;
2148 	    pp = &(*pp)->next;
2149 
2150 	    hold = length;
2151 	    dword_align_bin (&pp, &length);
2152 	    vilen += length - hold;
2153 
2154 	    vsd = (struct bindata *) reswr_alloc (sizeof *vsd);
2155 	    vsd->length = 6;
2156 	    vsd->data = (unsigned char *) reswr_alloc (vsd->length);
2157 
2158 	    length += 6;
2159 	    vilen += 6;
2160 	    vslen = 6;
2161 
2162 	    put_16 (big_endian, 0, vsd->data + 2);
2163 	    put_16 (big_endian, 0, vsd->data + 4);
2164 
2165 	    *pp = vsd;
2166 	    pp = &vsd->next;
2167 
2168 	    *pp = unicode_to_bin (vi->u.string.language, big_endian);
2169 	    length += (*pp)->length;
2170 	    vilen += (*pp)->length;
2171 	    vslen += (*pp)->length;
2172 	    pp = &(*pp)->next;
2173 
2174 	    for (vs = vi->u.string.strings; vs != NULL; vs = vs->next)
2175 	      {
2176 		struct bindata *vssd;
2177 		unsigned long vsslen;
2178 
2179 		hold = length;
2180 		dword_align_bin (&pp, &length);
2181 		vilen += length - hold;
2182 		vslen += length - hold;
2183 
2184 		vssd = (struct bindata *) reswr_alloc (sizeof *vssd);
2185 		vssd->length = 6;
2186 		vssd->data = (unsigned char *) reswr_alloc (vssd->length);
2187 
2188 		length += 6;
2189 		vilen += 6;
2190 		vslen += 6;
2191 		vsslen = 6;
2192 
2193 		put_16 (big_endian, 1, vssd->data + 4);
2194 
2195 		*pp = vssd;
2196 		pp = &vssd->next;
2197 
2198 		*pp = unicode_to_bin (vs->key, big_endian);
2199 		length += (*pp)->length;
2200 		vilen += (*pp)->length;
2201 		vslen += (*pp)->length;
2202 		vsslen += (*pp)->length;
2203 		pp = &(*pp)->next;
2204 
2205 		hold = length;
2206 		dword_align_bin (&pp, &length);
2207 		vilen += length - hold;
2208 		vslen += length - hold;
2209 		vsslen += length - hold;
2210 
2211 		*pp = unicode_to_bin (vs->value, big_endian);
2212 		put_16 (big_endian, (*pp)->length / 2, vssd->data + 2);
2213 		length += (*pp)->length;
2214 		vilen += (*pp)->length;
2215 		vslen += (*pp)->length;
2216 		vsslen += (*pp)->length;
2217 		pp = &(*pp)->next;
2218 
2219 		put_16 (big_endian, vsslen, vssd->data);
2220 	      }
2221 
2222 	    put_16 (big_endian, vslen, vsd->data);
2223 
2224 	    break;
2225 	  }
2226 
2227 	case VERINFO_VAR:
2228 	  {
2229 	    unsigned long hold, vvlen, vvvlen;
2230 	    struct bindata *vvd;
2231 	    const struct ver_varinfo *vv;
2232 
2233 	    *pp = string_to_unicode_bin ("VarFileInfo", big_endian);
2234 	    length += (*pp)->length;
2235 	    vilen += (*pp)->length;
2236 	    pp = &(*pp)->next;
2237 
2238 	    hold = length;
2239 	    dword_align_bin (&pp, &length);
2240 	    vilen += length - hold;
2241 
2242 	    vvd = (struct bindata *) reswr_alloc (sizeof *vvd);
2243 	    vvd->length = 6;
2244 	    vvd->data = (unsigned char *) reswr_alloc (vvd->length);
2245 
2246 	    length += 6;
2247 	    vilen += 6;
2248 	    vvlen = 6;
2249 
2250 	    put_16 (big_endian, 0, vvd->data + 4);
2251 
2252 	    *pp = vvd;
2253 	    pp = &vvd->next;
2254 
2255 	    *pp = unicode_to_bin (vi->u.var.key, big_endian);
2256 	    length += (*pp)->length;
2257 	    vilen += (*pp)->length;
2258 	    vvlen += (*pp)->length;
2259 	    pp = &(*pp)->next;
2260 
2261 	    hold = length;
2262 	    dword_align_bin (&pp, &length);
2263 	    vilen += length - hold;
2264 	    vvlen += length - hold;
2265 
2266 	    vvvlen = 0;
2267 
2268 	    for (vv = vi->u.var.var; vv != NULL; vv = vv->next)
2269 	      {
2270 		struct bindata *vvsd;
2271 
2272 		vvsd = (struct bindata *) reswr_alloc (sizeof *vvsd);
2273 		vvsd->length = 4;
2274 		vvsd->data = (unsigned char *) reswr_alloc (vvsd->length);
2275 
2276 		length += 4;
2277 		vilen += 4;
2278 		vvlen += 4;
2279 		vvvlen += 4;
2280 
2281 		put_16 (big_endian, vv->language, vvsd->data);
2282 		put_16 (big_endian, vv->charset, vvsd->data + 2);
2283 
2284 		vvsd->next = NULL;
2285 		*pp = vvsd;
2286 		pp = &vvsd->next;
2287 	      }
2288 
2289 	    put_16 (big_endian, vvlen, vvd->data);
2290 	    put_16 (big_endian, vvvlen, vvd->data + 2);
2291 
2292 	    break;
2293 	  }
2294 	}
2295 
2296       put_16 (big_endian, vilen, vid->data);
2297     }
2298 
2299   put_16 (big_endian, length, first->data);
2300 
2301   return first;
2302 }
2303 
2304 /* Convert a generic resource to binary.  */
2305 
2306 static struct bindata *
2307 res_to_bin_generic (unsigned long length, const unsigned char *data)
2308 {
2309   struct bindata *d;
2310 
2311   d = (struct bindata *) reswr_alloc (sizeof *d);
2312   d->length = length;
2313   d->data = (unsigned char *) data;
2314 
2315   d->next = NULL;
2316 
2317   return d;
2318 }
2319