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