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