summaryrefslogtreecommitdiff
path: root/binutils/resbin.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils/resbin.c')
-rw-r--r--binutils/resbin.c2387
1 files changed, 0 insertions, 2387 deletions
diff --git a/binutils/resbin.c b/binutils/resbin.c
deleted file mode 100644
index 8fc07fbb292..00000000000
--- a/binutils/resbin.c
+++ /dev/null
@@ -1,2387 +0,0 @@
-/* resbin.c -- manipulate the Windows binary resource format.
- Copyright 1997, 1998 Free Software Foundation, Inc.
- Written by Ian Lance Taylor, Cygnus Support.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-/* This file contains functions to convert between the binary resource
- format and the internal structures that we want to use. The same
- binary resource format is used in both res and COFF files. */
-
-#include "bfd.h"
-#include "bucomm.h"
-#include "libiberty.h"
-#include "windres.h"
-
-/* Macros to swap in values. */
-
-#define get_16(be, s) ((be) ? bfd_getb16 (s) : bfd_getl16 (s))
-#define get_32(be, s) ((be) ? bfd_getb32 (s) : bfd_getl32 (s))
-
-/* Local functions. */
-
-static void toosmall PARAMS ((const char *));
-static unichar *get_unicode
- PARAMS ((const unsigned char *, unsigned long, int, int *));
-static int get_resid
- PARAMS ((struct res_id *, const unsigned char *, unsigned long, int));
-static struct res_resource *bin_to_res_generic
- PARAMS ((enum res_type, const unsigned char *, unsigned long));
-static struct res_resource *bin_to_res_cursor
- PARAMS ((const unsigned char *, unsigned long, int));
-static struct res_resource *bin_to_res_menu
- PARAMS ((const unsigned char *, unsigned long, int));
-static struct menuitem *bin_to_res_menuitems
- PARAMS ((const unsigned char *, unsigned long, int, int *));
-static struct menuitem *bin_to_res_menuexitems
- PARAMS ((const unsigned char *, unsigned long, int, int *));
-static struct res_resource *bin_to_res_dialog
- PARAMS ((const unsigned char *, unsigned long, int));
-static struct res_resource *bin_to_res_string
- PARAMS ((const unsigned char *, unsigned long, int));
-static struct res_resource *bin_to_res_fontdir
- PARAMS ((const unsigned char *, unsigned long, int));
-static struct res_resource *bin_to_res_accelerators
- PARAMS ((const unsigned char *, unsigned long, int));
-static struct res_resource *bin_to_res_rcdata
- PARAMS ((const unsigned char *, unsigned long, int));
-static struct res_resource *bin_to_res_group_cursor
- PARAMS ((const unsigned char *, unsigned long, int));
-static struct res_resource *bin_to_res_group_icon
- PARAMS ((const unsigned char *, unsigned long, int));
-static struct res_resource *bin_to_res_version
- PARAMS ((const unsigned char *, unsigned long, int));
-static struct res_resource *bin_to_res_userdata
- PARAMS ((const unsigned char *, unsigned long, int));
-
-/* Given a resource type ID, a pointer to data, a length, return a
- res_resource structure which represents that resource. The caller
- is responsible for initializing the res_info and coff_info fields
- of the returned structure. */
-
-struct res_resource *
-bin_to_res (type, data, length, big_endian)
- struct res_id type;
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- if (type.named)
- return bin_to_res_userdata (data, length, big_endian);
- else
- {
- switch (type.u.id)
- {
- default:
- return bin_to_res_userdata (data, length, big_endian);
- case RT_CURSOR:
- return bin_to_res_cursor (data, length, big_endian);
- case RT_BITMAP:
- return bin_to_res_generic (RES_TYPE_BITMAP, data, length);
- case RT_ICON:
- return bin_to_res_generic (RES_TYPE_ICON, data, length);
- case RT_MENU:
- return bin_to_res_menu (data, length, big_endian);
- case RT_DIALOG:
- return bin_to_res_dialog (data, length, big_endian);
- case RT_STRING:
- return bin_to_res_string (data, length, big_endian);
- case RT_FONTDIR:
- return bin_to_res_fontdir (data, length, big_endian);
- case RT_FONT:
- return bin_to_res_generic (RES_TYPE_FONT, data, length);
- case RT_ACCELERATOR:
- return bin_to_res_accelerators (data, length, big_endian);
- case RT_RCDATA:
- return bin_to_res_rcdata (data, length, big_endian);
- case RT_MESSAGETABLE:
- return bin_to_res_generic (RES_TYPE_MESSAGETABLE, data, length);
- case RT_GROUP_CURSOR:
- return bin_to_res_group_cursor (data, length, big_endian);
- case RT_GROUP_ICON:
- return bin_to_res_group_icon (data, length, big_endian);
- case RT_VERSION:
- return bin_to_res_version (data, length, big_endian);
- }
- }
-}
-
-/* Give an error if the binary data is too small. */
-
-static void
-toosmall (msg)
- const char *msg;
-{
- fatal (_("%s: not enough binary data"), msg);
-}
-
-/* Swap in a NULL terminated unicode string. */
-
-static unichar *
-get_unicode (data, length, big_endian, retlen)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
- int *retlen;
-{
- int c, i;
- unichar *ret;
-
- c = 0;
- while (1)
- {
- if (length < (unsigned long) c * 2 + 2)
- toosmall (_("null terminated unicode string"));
- if (get_16 (big_endian, data + c * 2) == 0)
- break;
- ++c;
- }
-
- ret = (unichar *) res_alloc ((c + 1) * sizeof (unichar));
-
- for (i = 0; i < c; i++)
- ret[i] = get_16 (big_endian, data + i * 2);
- ret[i] = 0;
-
- if (retlen != NULL)
- *retlen = c;
-
- return ret;
-}
-
-/* Get a resource identifier. This returns the number of bytes used. */
-
-static int
-get_resid (id, data, length, big_endian)
- struct res_id *id;
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- int first;
-
- if (length < 2)
- toosmall (_("resource ID"));
-
- first = get_16 (big_endian, data);
- if (first == 0xffff)
- {
- if (length < 4)
- toosmall (_("resource ID"));
- id->named = 0;
- id->u.id = get_16 (big_endian, data + 2);
- return 4;
- }
- else
- {
- id->named = 1;
- id->u.n.name = get_unicode (data, length, big_endian, &id->u.n.length);
- return id->u.n.length * 2 + 2;
- }
-}
-
-/* Convert a resource which just stores uninterpreted data from
- binary. */
-
-struct res_resource *
-bin_to_res_generic (type, data, length)
- enum res_type type;
- const unsigned char *data;
- unsigned long length;
-{
- struct res_resource *r;
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = type;
- r->u.data.data = data;
- r->u.data.length = length;
-
- return r;
-}
-
-/* Convert a cursor resource from binary. */
-
-struct res_resource *
-bin_to_res_cursor (data, length, big_endian)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- struct cursor *c;
- struct res_resource *r;
-
- if (length < 4)
- toosmall (_("cursor"));
-
- c = (struct cursor *) res_alloc (sizeof *c);
- c->xhotspot = get_16 (big_endian, data);
- c->yhotspot = get_16 (big_endian, data + 2);
- c->length = length - 4;
- c->data = data + 4;
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = RES_TYPE_CURSOR;
- r->u.cursor = c;
-
- return r;
-}
-
-/* Convert a menu resource from binary. */
-
-struct res_resource *
-bin_to_res_menu (data, length, big_endian)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- struct res_resource *r;
- struct menu *m;
- int version, read;
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = RES_TYPE_MENU;
-
- m = (struct menu *) res_alloc (sizeof *m);
- r->u.menu = m;
-
- if (length < 2)
- toosmall (_("menu header"));
-
- version = get_16 (big_endian, data);
-
- if (version == 0)
- {
- if (length < 4)
- toosmall (_("menu header"));
- m->help = 0;
- m->items = bin_to_res_menuitems (data + 4, length - 4, big_endian,
- &read);
- }
- else if (version == 1)
- {
- unsigned int offset;
-
- if (length < 8)
- toosmall (_("menuex header"));
- m->help = get_32 (big_endian, data + 4);
- offset = get_16 (big_endian, data + 2);
- if (offset + 4 >= length)
- toosmall (_("menuex offset"));
- m->items = bin_to_res_menuexitems (data + 4 + offset,
- length - (4 + offset),
- big_endian,
- &read);
- }
- else
- fatal (_("unsupported menu version %d"), version);
-
- return r;
-}
-
-/* Convert menu items from binary. */
-
-static struct menuitem *
-bin_to_res_menuitems (data, length, big_endian, read)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
- int *read;
-{
- struct menuitem *first, **pp;
-
- first = NULL;
- pp = &first;
-
- *read = 0;
-
- while (length > 0)
- {
- int flags, slen, itemlen;
- unsigned int stroff;
- struct menuitem *mi;
-
- if (length < 4)
- toosmall (_("menuitem header"));
-
- mi = (struct menuitem *) res_alloc (sizeof *mi);
- mi->state = 0;
- mi->help = 0;
-
- flags = get_16 (big_endian, data);
- mi->type = flags &~ (MENUITEM_POPUP | MENUITEM_ENDMENU);
-
- if ((flags & MENUITEM_POPUP) == 0)
- stroff = 4;
- else
- stroff = 2;
-
- if (length < stroff + 2)
- toosmall (_("menuitem header"));
-
- if (get_16 (big_endian, data + stroff) == 0)
- {
- slen = 0;
- mi->text = NULL;
- }
- else
- mi->text = get_unicode (data + stroff, length - stroff, big_endian,
- &slen);
-
- itemlen = stroff + slen * 2 + 2;
-
- if ((flags & MENUITEM_POPUP) == 0)
- {
- mi->popup = NULL;
- mi->id = get_16 (big_endian, data + 2);
- }
- else
- {
- int subread;
-
- mi->id = 0;
- mi->popup = bin_to_res_menuitems (data + itemlen, length - itemlen,
- big_endian, &subread);
- itemlen += subread;
- }
-
- mi->next = NULL;
- *pp = mi;
- pp = &mi->next;
-
- data += itemlen;
- length -= itemlen;
- *read += itemlen;
-
- if ((flags & MENUITEM_ENDMENU) != 0)
- return first;
- }
-
- return first;
-}
-
-/* Convert menuex items from binary. */
-
-static struct menuitem *
-bin_to_res_menuexitems (data, length, big_endian, read)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
- int *read;
-{
- struct menuitem *first, **pp;
-
- first = NULL;
- pp = &first;
-
- *read = 0;
-
- while (length > 0)
- {
- int flags, slen;
- unsigned int itemlen;
- struct menuitem *mi;
-
- if (length < 14)
- toosmall (_("menuitem header"));
-
- mi = (struct menuitem *) res_alloc (sizeof *mi);
- mi->type = get_32 (big_endian, data);
- mi->state = get_32 (big_endian, data + 4);
- mi->id = get_16 (big_endian, data + 8);
-
- flags = get_16 (big_endian, data + 10);
-
- if (get_16 (big_endian, data + 12) == 0)
- {
- slen = 0;
- mi->text = NULL;
- }
- else
- mi->text = get_unicode (data + 12, length - 12, big_endian, &slen);
-
- itemlen = 12 + slen * 2 + 2;
- itemlen = (itemlen + 3) &~ 3;
-
- if ((flags & 1) == 0)
- {
- mi->popup = NULL;
- mi->help = 0;
- }
- else
- {
- int subread;
-
- if (length < itemlen + 4)
- toosmall (_("menuitem"));
- mi->help = get_32 (big_endian, data + itemlen);
- itemlen += 4;
-
- mi->popup = bin_to_res_menuexitems (data + itemlen,
- length - itemlen,
- big_endian, &subread);
- itemlen += subread;
- }
-
- mi->next = NULL;
- *pp = mi;
- pp = &mi->next;
-
- data += itemlen;
- length -= itemlen;
- *read += itemlen;
-
- if ((flags & 0x80) != 0)
- return first;
- }
-
- return first;
-}
-
-/* Convert a dialog resource from binary. */
-
-static struct res_resource *
-bin_to_res_dialog (data, length, big_endian)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- int version;
- struct dialog *d;
- int c, sublen, i;
- unsigned int off;
- struct dialog_control **pp;
- struct res_resource *r;
-
- if (length < 18)
- toosmall (_("dialog header"));
-
- d = (struct dialog *) res_alloc (sizeof *d);
-
- version = get_16 (big_endian, data);
- if (version != 1)
- {
- d->ex = NULL;
- d->style = get_32 (big_endian, data);
- d->exstyle = get_32 (big_endian, data + 4);
- off = 8;
- }
- else
- {
- int signature;
-
- signature = get_16 (big_endian, data + 2);
- if (signature != 0xffff)
- fatal (_("unexpected dialog signature %d"), signature);
-
- d->ex = (struct dialog_ex *) res_alloc (sizeof (struct dialog_ex));
- d->ex->help = get_32 (big_endian, data + 4);
- d->exstyle = get_32 (big_endian, data + 8);
- d->style = get_32 (big_endian, data + 12);
- off = 16;
- }
-
- if (length < off + 10)
- toosmall (_("dialog header"));
-
- c = get_16 (big_endian, data + off);
- d->x = get_16 (big_endian, data + off + 2);
- d->y = get_16 (big_endian, data + off + 4);
- d->width = get_16 (big_endian, data + off + 6);
- d->height = get_16 (big_endian, data + off + 8);
-
- off += 10;
-
- sublen = get_resid (&d->menu, data + off, length - off, big_endian);
- off += sublen;
-
- sublen = get_resid (&d->class, data + off, length - off, big_endian);
- off += sublen;
-
- d->caption = get_unicode (data + off, length - off, big_endian, &sublen);
- off += sublen * 2 + 2;
-
- if ((d->style & DS_SETFONT) == 0)
- {
- d->pointsize = 0;
- d->font = NULL;
- if (d->ex != NULL)
- {
- d->ex->weight = 0;
- d->ex->italic = 0;
- }
- }
- else
- {
- if (length < off + 2)
- toosmall (_("dialog font point size"));
-
- d->pointsize = get_16 (big_endian, data + off);
- off += 2;
-
- if (d->ex != NULL)
- {
- if (length < off + 4)
- toosmall (_("dialogex font information"));
- d->ex->weight = get_16 (big_endian, data + off);
- d->ex->italic = get_16 (big_endian, data + off + 2);
- off += 4;
- }
-
- d->font = get_unicode (data + off, length - off, big_endian, &sublen);
- off += sublen * 2 + 2;
- }
-
- d->controls = NULL;
- pp = &d->controls;
-
- for (i = 0; i < c; i++)
- {
- struct dialog_control *dc;
- int datalen;
-
- off = (off + 3) &~ 3;
-
- dc = (struct dialog_control *) res_alloc (sizeof *dc);
-
- if (d->ex == NULL)
- {
- if (length < off + 8)
- toosmall (_("dialog control"));
-
- dc->style = get_32 (big_endian, data + off);
- dc->exstyle = get_32 (big_endian, data + off + 4);
- dc->help = 0;
- off += 8;
- }
- else
- {
- if (length < off + 12)
- toosmall (_("dialogex control"));
- dc->help = get_32 (big_endian, data + off);
- dc->exstyle = get_32 (big_endian, data + off + 4);
- dc->style = get_32 (big_endian, data + off + 8);
- off += 12;
- }
-
- if (length < off + 10)
- toosmall (_("dialog control"));
-
- dc->x = get_16 (big_endian, data + off);
- dc->y = get_16 (big_endian, data + off + 2);
- dc->width = get_16 (big_endian, data + off + 4);
- dc->height = get_16 (big_endian, data + off + 6);
-
- if (d->ex != NULL)
- dc->id = get_32 (big_endian, data + off + 8);
- else
- dc->id = get_16 (big_endian, data + off + 8);
-
- off += 10 + (d->ex != NULL ? 2 : 0);
-
- sublen = get_resid (&dc->class, data + off, length - off, big_endian);
- off += sublen;
-
- sublen = get_resid (&dc->text, data + off, length - off, big_endian);
- off += sublen;
-
- if (length < off + 2)
- toosmall (_("dialog control end"));
-
- datalen = get_16 (big_endian, data + off);
- off += 2;
-
- if (datalen == 0)
- dc->data = NULL;
- else
- {
- off = (off + 3) &~ 3;
-
- if (length < off + datalen)
- toosmall (_("dialog control data"));
-
- dc->data = ((struct rcdata_item *)
- res_alloc (sizeof (struct rcdata_item)));
- dc->data->next = NULL;
- dc->data->type = RCDATA_BUFFER;
- dc->data->u.buffer.length = datalen;
- dc->data->u.buffer.data = data + off;
-
- off += datalen;
- }
-
- dc->next = NULL;
- *pp = dc;
- pp = &dc->next;
- }
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = RES_TYPE_DIALOG;
- r->u.dialog = d;
-
- return r;
-}
-
-/* Convert a stringtable resource from binary. */
-
-static struct res_resource *
-bin_to_res_string (data, length, big_endian)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- struct stringtable *st;
- int i;
- struct res_resource *r;
-
- st = (struct stringtable *) res_alloc (sizeof *st);
-
- for (i = 0; i < 16; i++)
- {
- unsigned int slen;
-
- if (length < 2)
- toosmall (_("stringtable string length"));
- slen = get_16 (big_endian, data);
- st->strings[i].length = slen;
-
- if (slen > 0)
- {
- unichar *s;
- unsigned int j;
-
- if (length < 2 + 2 * slen)
- toosmall (_("stringtable string"));
-
- s = (unichar *) res_alloc (slen * sizeof (unichar));
- st->strings[i].string = s;
-
- for (j = 0; j < slen; j++)
- s[j] = get_16 (big_endian, data + 2 + j * 2);
- }
-
- data += 2 + 2 * slen;
- length -= 2 + 2 * slen;
- }
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = RES_TYPE_STRINGTABLE;
- r->u.stringtable = st;
-
- return r;
-}
-
-/* Convert a fontdir resource from binary. */
-
-static struct res_resource *
-bin_to_res_fontdir (data, length, big_endian)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- int c, i;
- struct fontdir *first, **pp;
- struct res_resource *r;
-
- if (length < 2)
- toosmall (_("fontdir header"));
-
- c = get_16 (big_endian, data);
-
- first = NULL;
- pp = &first;
-
- for (i = 0; i < c; i++)
- {
- struct fontdir *fd;
- unsigned int off;
-
- if (length < 56)
- toosmall (_("fontdir"));
-
- fd = (struct fontdir *) res_alloc (sizeof *fd);
- fd->index = get_16 (big_endian, data);
-
- /* To work out the length of the fontdir data, we must get the
- length of the device name and face name strings, even though
- we don't store them in the fontdir structure. The
- documentation says that these are NULL terminated char
- strings, not Unicode strings. */
-
- off = 56;
-
- while (off < length && data[off] != '\0')
- ++off;
- if (off >= length)
- toosmall (_("fontdir device name"));
- ++off;
-
- while (off < length && data[off] != '\0')
- ++off;
- if (off >= length)
- toosmall (_("fontdir face name"));
- ++off;
-
- fd->length = off;
- fd->data = data;
-
- fd->next = NULL;
- *pp = fd;
- pp = &fd->next;
-
- /* The documentation does not indicate that any rounding is
- required. */
-
- data += off;
- length -= off;
- }
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = RES_TYPE_FONTDIR;
- r->u.fontdir = first;
-
- return r;
-}
-
-/* Convert an accelerators resource from binary. */
-
-static struct res_resource *
-bin_to_res_accelerators (data, length, big_endian)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- struct accelerator *first, **pp;
- struct res_resource *r;
-
- first = NULL;
- pp = &first;
-
- while (1)
- {
- struct accelerator *a;
-
- if (length < 8)
- toosmall (_("accelerator"));
-
- a = (struct accelerator *) res_alloc (sizeof *a);
-
- a->flags = get_16 (big_endian, data);
- a->key = get_16 (big_endian, data + 2);
- a->id = get_16 (big_endian, data + 4);
-
- a->next = NULL;
- *pp = a;
- pp = &a->next;
-
- if ((a->flags & ACC_LAST) != 0)
- break;
-
- data += 8;
- length -= 8;
- }
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = RES_TYPE_ACCELERATOR;
- r->u.acc = first;
-
- return r;
-}
-
-/* Convert an rcdata resource from binary. */
-
-static struct res_resource *
-bin_to_res_rcdata (data, length, big_endian)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- struct rcdata_item *ri;
- struct res_resource *r;
-
- ri = (struct rcdata_item *) res_alloc (sizeof *ri);
-
- ri->next = NULL;
- ri->type = RCDATA_BUFFER;
- ri->u.buffer.length = length;
- ri->u.buffer.data = data;
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = RES_TYPE_RCDATA;
- r->u.rcdata = ri;
-
- return r;
-}
-
-/* Convert a group cursor resource from binary. */
-
-static struct res_resource *
-bin_to_res_group_cursor (data, length, big_endian)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- int type, c, i;
- struct group_cursor *first, **pp;
- struct res_resource *r;
-
- if (length < 6)
- toosmall (_("group cursor header"));
-
- type = get_16 (big_endian, data + 2);
- if (type != 2)
- fatal (_("unexpected group cursor type %d"), type);
-
- c = get_16 (big_endian, data + 4);
-
- data += 6;
- length -= 6;
-
- first = NULL;
- pp = &first;
-
- for (i = 0; i < c; i++)
- {
- struct group_cursor *gc;
-
- if (length < 14)
- toosmall (_("group cursor"));
-
- gc = (struct group_cursor *) res_alloc (sizeof *gc);
-
- gc->width = get_16 (big_endian, data);
- gc->height = get_16 (big_endian, data + 2);
- gc->planes = get_16 (big_endian, data + 4);
- gc->bits = get_16 (big_endian, data + 6);
- gc->bytes = get_32 (big_endian, data + 8);
- gc->index = get_16 (big_endian, data + 12);
-
- gc->next = NULL;
- *pp = gc;
- pp = &gc->next;
-
- data += 14;
- length -= 14;
- }
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = RES_TYPE_GROUP_CURSOR;
- r->u.group_cursor = first;
-
- return r;
-}
-
-/* Convert a group icon resource from binary. */
-
-static struct res_resource *
-bin_to_res_group_icon (data, length, big_endian)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- int type, c, i;
- struct group_icon *first, **pp;
- struct res_resource *r;
-
- if (length < 6)
- toosmall (_("group icon header"));
-
- type = get_16 (big_endian, data + 2);
- if (type != 1)
- fatal (_("unexpected group icon type %d"), type);
-
- c = get_16 (big_endian, data + 4);
-
- data += 6;
- length -= 6;
-
- first = NULL;
- pp = &first;
-
- for (i = 0; i < c; i++)
- {
- struct group_icon *gi;
-
- if (length < 14)
- toosmall (_("group icon"));
-
- gi = (struct group_icon *) res_alloc (sizeof *gi);
-
- gi->width = data[0];
- gi->height = data[1];
- gi->colors = data[2];
- gi->planes = get_16 (big_endian, data + 4);
- gi->bits = get_16 (big_endian, data + 6);
- gi->bytes = get_32 (big_endian, data + 8);
- gi->index = get_16 (big_endian, data + 12);
-
- gi->next = NULL;
- *pp = gi;
- pp = &gi->next;
-
- data += 14;
- length -= 14;
- }
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = RES_TYPE_GROUP_ICON;
- r->u.group_icon = first;
-
- return r;
-}
-
-/* Extract data from a version header. If KEY is not NULL, then the
- key must be KEY; otherwise, the key is returned in *PKEY. This
- sets *LEN to the total length, *VALLEN to the value length, *TYPE
- to the type, and *OFF to the offset to the children. */
-
-static void
-get_version_header (data, length, big_endian, key, pkey, len, vallen, type,
- off)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
- const char *key;
- unichar **pkey;
- int *len;
- int *vallen;
- int *type;
- int *off;
-{
- if (length < 8)
- toosmall (key);
-
- *len = get_16 (big_endian, data);
- *vallen = get_16 (big_endian, data + 2);
- *type = get_16 (big_endian, data + 4);
-
- *off = 6;
-
- length -= 6;
- data += 6;
-
- if (key == NULL)
- {
- int sublen;
-
- *pkey = get_unicode (data, length, big_endian, &sublen);
- *off += sublen * 2 + 2;
- }
- else
- {
- while (1)
- {
- if (length < 2)
- toosmall (key);
- if (get_16 (big_endian, data) != (unsigned char) *key)
- fatal (_("unexpected version string"));
-
- *off += 2;
- length -= 2;
- data += 2;
-
- if (*key == '\0')
- break;
-
- ++key;
- }
- }
-
- *off = (*off + 3) &~ 3;
-}
-
-/* Convert a version resource from binary. */
-
-static struct res_resource *
-bin_to_res_version (data, length, big_endian)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- int verlen, vallen, type, off;
- struct fixed_versioninfo *fi;
- struct ver_info *first, **pp;
- struct versioninfo *v;
- struct res_resource *r;
-
- get_version_header (data, length, big_endian, "VS_VERSION_INFO",
- (unichar *) NULL, &verlen, &vallen, &type, &off);
-
- if ((unsigned int) verlen != length)
- fatal (_("version length %d does not match resource length %lu"),
- verlen, length);
-
- if (type != 0)
- fatal (_("unexpected version type %d"), type);
-
- data += off;
- length -= off;
-
- if (vallen == 0)
- fi = NULL;
- else
- {
- unsigned long signature, fiv;
-
- if (vallen != 52)
- fatal (_("unexpected fixed version information length %d"), vallen);
-
- if (length < 52)
- toosmall (_("fixed version info"));
-
- signature = get_32 (big_endian, data);
- if (signature != 0xfeef04bd)
- fatal (_("unexpected fixed version signature %lu"), signature);
-
- fiv = get_32 (big_endian, data + 4);
- if (fiv != 0 && fiv != 0x10000)
- fatal (_("unexpected fixed version info version %lu"), fiv);
-
- fi = (struct fixed_versioninfo *) res_alloc (sizeof *fi);
-
- fi->file_version_ms = get_32 (big_endian, data + 8);
- fi->file_version_ls = get_32 (big_endian, data + 12);
- fi->product_version_ms = get_32 (big_endian, data + 16);
- fi->product_version_ls = get_32 (big_endian, data + 20);
- fi->file_flags_mask = get_32 (big_endian, data + 24);
- fi->file_flags = get_32 (big_endian, data + 28);
- fi->file_os = get_32 (big_endian, data + 32);
- fi->file_type = get_32 (big_endian, data + 36);
- fi->file_subtype = get_32 (big_endian, data + 40);
- fi->file_date_ms = get_32 (big_endian, data + 44);
- fi->file_date_ls = get_32 (big_endian, data + 48);
-
- data += 52;
- length -= 52;
- }
-
- first = NULL;
- pp = &first;
-
- while (length > 0)
- {
- struct ver_info *vi;
- int ch;
-
- if (length < 8)
- toosmall (_("version var info"));
-
- vi = (struct ver_info *) res_alloc (sizeof *vi);
-
- ch = get_16 (big_endian, data + 6);
-
- if (ch == 'S')
- {
- struct ver_stringinfo **ppvs;
-
- vi->type = VERINFO_STRING;
-
- get_version_header (data, length, big_endian, "StringFileInfo",
- (unichar *) NULL, &verlen, &vallen, &type,
- &off);
-
- if (vallen != 0)
- fatal (_("unexpected stringfileinfo value length %d"), vallen);
-
- data += off;
- length -= off;
-
- get_version_header (data, length, big_endian, (const char *) NULL,
- &vi->u.string.language, &verlen, &vallen,
- &type, &off);
-
- if (vallen != 0)
- fatal (_("unexpected version stringtable value length %d"), vallen);
-
- data += off;
- length -= off;
- verlen -= off;
-
- vi->u.string.strings = NULL;
- ppvs = &vi->u.string.strings;
-
- /* It's convenient to round verlen to a 4 byte alignment,
- since we round the subvariables in the loop. */
- verlen = (verlen + 3) &~ 3;
-
- while (verlen > 0)
- {
- struct ver_stringinfo *vs;
- int subverlen, vslen, valoff;
-
- vs = (struct ver_stringinfo *) res_alloc (sizeof *vs);
-
- get_version_header (data, length, big_endian,
- (const char *) NULL, &vs->key, &subverlen,
- &vallen, &type, &off);
-
- subverlen = (subverlen + 3) &~ 3;
-
- data += off;
- length -= off;
-
- vs->value = get_unicode (data, length, big_endian, &vslen);
- valoff = vslen * 2 + 2;
- valoff = (valoff + 3) &~ 3;
-
- if (off + valoff != subverlen)
- fatal (_("unexpected version string length %d != %d + %d"),
- subverlen, off, valoff);
-
- vs->next = NULL;
- *ppvs = vs;
- ppvs = &vs->next;
-
- data += valoff;
- length -= valoff;
-
- if (verlen < subverlen)
- fatal (_("unexpected version string length %d < %d"),
- verlen, subverlen);
-
- verlen -= subverlen;
- }
- }
- else if (ch == 'V')
- {
- struct ver_varinfo **ppvv;
-
- vi->type = VERINFO_VAR;
-
- get_version_header (data, length, big_endian, "VarFileInfo",
- (unichar *) NULL, &verlen, &vallen, &type,
- &off);
-
- if (vallen != 0)
- fatal (_("unexpected varfileinfo value length %d"), vallen);
-
- data += off;
- length -= off;
-
- get_version_header (data, length, big_endian, (const char *) NULL,
- &vi->u.var.key, &verlen, &vallen, &type, &off);
-
- data += off;
- length -= off;
-
- vi->u.var.var = NULL;
- ppvv = &vi->u.var.var;
-
- while (vallen > 0)
- {
- struct ver_varinfo *vv;
-
- if (length < 4)
- toosmall (_("version varfileinfo"));
-
- vv = (struct ver_varinfo *) res_alloc (sizeof *vv);
-
- vv->language = get_16 (big_endian, data);
- vv->charset = get_16 (big_endian, data + 2);
-
- vv->next = NULL;
- *ppvv = vv;
- ppvv = &vv->next;
-
- data += 4;
- length -= 4;
-
- if (vallen < 4)
- fatal (_("unexpected version value length %d"), vallen);
-
- vallen -= 4;
- }
- }
- else
- fatal (_("unexpected version string"));
-
- vi->next = NULL;
- *pp = vi;
- pp = &vi->next;
- }
-
- v = (struct versioninfo *) res_alloc (sizeof *v);
- v->fixed = fi;
- v->var = first;
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = RES_TYPE_VERSIONINFO;
- r->u.versioninfo = v;
-
- return r;
-}
-
-/* Convert an arbitrary user defined resource from binary. */
-
-static struct res_resource *
-bin_to_res_userdata (data, length, big_endian)
- const unsigned char *data;
- unsigned long length;
- int big_endian;
-{
- struct rcdata_item *ri;
- struct res_resource *r;
-
- ri = (struct rcdata_item *) res_alloc (sizeof *ri);
-
- ri->next = NULL;
- ri->type = RCDATA_BUFFER;
- ri->u.buffer.length = length;
- ri->u.buffer.data = data;
-
- r = (struct res_resource *) res_alloc (sizeof *r);
- r->type = RES_TYPE_USERDATA;
- r->u.rcdata = ri;
-
- return r;
-}
-
-/* Macros to swap out values. */
-
-#define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
-#define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
-
-/* Local functions used to convert resources to binary format. */
-
-static void dword_align_bin PARAMS ((struct bindata ***, unsigned long *));
-static struct bindata *resid_to_bin PARAMS ((struct res_id, int));
-static struct bindata *unicode_to_bin PARAMS ((const unichar *, int));
-static struct bindata *res_to_bin_accelerator
- PARAMS ((const struct accelerator *, int));
-static struct bindata *res_to_bin_cursor
- PARAMS ((const struct cursor *, int));
-static struct bindata *res_to_bin_group_cursor
- PARAMS ((const struct group_cursor *, int));
-static struct bindata *res_to_bin_dialog
- PARAMS ((const struct dialog *, int));
-static struct bindata *res_to_bin_fontdir
- PARAMS ((const struct fontdir *, int));
-static struct bindata *res_to_bin_group_icon
- PARAMS ((const struct group_icon *, int));
-static struct bindata *res_to_bin_menu
- PARAMS ((const struct menu *, int));
-static struct bindata *res_to_bin_menuitems
- PARAMS ((const struct menuitem *, int));
-static struct bindata *res_to_bin_menuexitems
- PARAMS ((const struct menuitem *, int));
-static struct bindata *res_to_bin_rcdata
- PARAMS ((const struct rcdata_item *, int));
-static struct bindata *res_to_bin_stringtable
- PARAMS ((const struct stringtable *, int));
-static struct bindata *string_to_unicode_bin PARAMS ((const char *, int));
-static struct bindata *res_to_bin_versioninfo
- PARAMS ((const struct versioninfo *, int));
-static struct bindata *res_to_bin_generic
- PARAMS ((unsigned long, const unsigned char *));
-
-/* Convert a resource to binary. */
-
-struct bindata *
-res_to_bin (res, big_endian)
- const struct res_resource *res;
- int big_endian;
-{
- switch (res->type)
- {
- default:
- abort ();
- case RES_TYPE_BITMAP:
- case RES_TYPE_FONT:
- case RES_TYPE_ICON:
- case RES_TYPE_MESSAGETABLE:
- return res_to_bin_generic (res->u.data.length, res->u.data.data);
- case RES_TYPE_ACCELERATOR:
- return res_to_bin_accelerator (res->u.acc, big_endian);
- case RES_TYPE_CURSOR:
- return res_to_bin_cursor (res->u.cursor, big_endian);
- case RES_TYPE_GROUP_CURSOR:
- return res_to_bin_group_cursor (res->u.group_cursor, big_endian);
- case RES_TYPE_DIALOG:
- return res_to_bin_dialog (res->u.dialog, big_endian);
- case RES_TYPE_FONTDIR:
- return res_to_bin_fontdir (res->u.fontdir, big_endian);
- case RES_TYPE_GROUP_ICON:
- return res_to_bin_group_icon (res->u.group_icon, big_endian);
- case RES_TYPE_MENU:
- return res_to_bin_menu (res->u.menu, big_endian);
- case RES_TYPE_RCDATA:
- return res_to_bin_rcdata (res->u.rcdata, big_endian);
- case RES_TYPE_STRINGTABLE:
- return res_to_bin_stringtable (res->u.stringtable, big_endian);
- case RES_TYPE_USERDATA:
- return res_to_bin_rcdata (res->u.rcdata, big_endian);
- case RES_TYPE_VERSIONINFO:
- return res_to_bin_versioninfo (res->u.versioninfo, big_endian);
- }
-}
-
-/* Align to a 32 bit boundary. PPP points to the of a list of bindata
- structures. LENGTH points to the length of the structures. If
- necessary, this adds a new bindata to bring length up to a 32 bit
- boundary. It updates *PPP and *LENGTH. */
-
-static void
-dword_align_bin (ppp, length)
- struct bindata ***ppp;
- unsigned long *length;
-{
- int add;
- struct bindata *d;
-
- if ((*length & 3) == 0)
- return;
-
- add = 4 - (*length & 3);
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = add;
- d->data = (unsigned char *) reswr_alloc (add);
- memset (d->data, 0, add);
-
- d->next = NULL;
- **ppp = d;
- *ppp = &(**ppp)->next;
-
- *length += add;
-}
-
-/* Convert a resource ID to binary. This always returns exactly one
- bindata structure. */
-
-static struct bindata *
-resid_to_bin (id, big_endian)
- struct res_id id;
- int big_endian;
-{
- struct bindata *d;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
-
- if (! id.named)
- {
- d->length = 4;
- d->data = (unsigned char *) reswr_alloc (4);
- put_16 (big_endian, 0xffff, d->data);
- put_16 (big_endian, id.u.id, d->data + 2);
- }
- else
- {
- int i;
-
- d->length = id.u.n.length * 2 + 2;
- d->data = (unsigned char *) reswr_alloc (d->length);
- for (i = 0; i < id.u.n.length; i++)
- put_16 (big_endian, id.u.n.name[i], d->data + i * 2);
- put_16 (big_endian, 0, d->data + i * 2);
- }
-
- d->next = NULL;
-
- return d;
-}
-
-/* Convert a null terminated unicode string to binary. This always
- returns exactly one bindata structure. */
-
-static struct bindata *
-unicode_to_bin (str, big_endian)
- const unichar *str;
- int big_endian;
-{
- int len;
- struct bindata *d;
-
- len = 0;
- if (str != NULL)
- {
- const unichar *s;
-
- for (s = str; *s != 0; s++)
- ++len;
- }
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = len * 2 + 2;
- d->data = (unsigned char *) reswr_alloc (d->length);
-
- if (str == NULL)
- put_16 (big_endian, 0, d->data);
- else
- {
- const unichar *s;
- int i;
-
- for (s = str, i = 0; *s != 0; s++, i++)
- put_16 (big_endian, *s, d->data + i * 2);
- put_16 (big_endian, 0, d->data + i * 2);
- }
-
- d->next = NULL;
-
- return d;
-}
-
-/* Convert an accelerator resource to binary. */
-
-static struct bindata *
-res_to_bin_accelerator (accelerators, big_endian)
- const struct accelerator *accelerators;
- int big_endian;
-{
- struct bindata *first, **pp;
- const struct accelerator *a;
-
- first = NULL;
- pp = &first;
-
- for (a = accelerators; a != NULL; a = a->next)
- {
- struct bindata *d;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = 8;
- d->data = (unsigned char *) reswr_alloc (8);
-
- put_16 (big_endian,
- a->flags | (a->next != NULL ? 0 : ACC_LAST),
- d->data);
- put_16 (big_endian, a->key, d->data + 2);
- put_16 (big_endian, a->id, d->data + 4);
- put_16 (big_endian, 0, d->data + 8);
-
- d->next = NULL;
- *pp = d;
- pp = &d->next;
- }
-
- return first;
-}
-
-/* Convert a cursor resource to binary. */
-
-static struct bindata *
-res_to_bin_cursor (c, big_endian)
- const struct cursor *c;
- int big_endian;
-{
- struct bindata *d;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = 4;
- d->data = (unsigned char *) reswr_alloc (4);
-
- put_16 (big_endian, c->xhotspot, d->data);
- put_16 (big_endian, c->yhotspot, d->data + 2);
-
- d->next = (struct bindata *) reswr_alloc (sizeof *d);
- d->next->length = c->length;
- d->next->data = (unsigned char *) c->data;
- d->next->next = NULL;
-
- return d;
-}
-
-/* Convert a group cursor resource to binary. */
-
-static struct bindata *
-res_to_bin_group_cursor (group_cursors, big_endian)
- const struct group_cursor *group_cursors;
- int big_endian;
-{
- struct bindata *first, **pp;
- int c;
- const struct group_cursor *gc;
-
- first = (struct bindata *) reswr_alloc (sizeof *first);
- first->length = 6;
- first->data = (unsigned char *) reswr_alloc (6);
-
- put_16 (big_endian, 0, first->data);
- put_16 (big_endian, 2, first->data + 2);
-
- first->next = NULL;
- pp = &first->next;
-
- c = 0;
- for (gc = group_cursors; gc != NULL; gc = gc->next)
- {
- struct bindata *d;
-
- ++c;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = 14;
- d->data = (unsigned char *) reswr_alloc (14);
-
- put_16 (big_endian, gc->width, d->data);
- put_16 (big_endian, gc->height, d->data + 2);
- put_16 (big_endian, gc->planes, d->data + 4);
- put_16 (big_endian, gc->bits, d->data + 6);
- put_32 (big_endian, gc->bytes, d->data + 8);
- put_16 (big_endian, gc->index, d->data + 12);
-
- d->next = NULL;
- *pp = d;
- pp = &d->next;
- }
-
- put_16 (big_endian, c, first->data + 4);
-
- return first;
-}
-
-/* Convert a dialog resource to binary. */
-
-static struct bindata *
-res_to_bin_dialog (dialog, big_endian)
- const struct dialog *dialog;
- int big_endian;
-{
- int dialogex;
- struct bindata *first, **pp;
- unsigned long length;
- int off, c;
- struct dialog_control *dc;
-
- dialogex = extended_dialog (dialog);
-
- first = (struct bindata *) reswr_alloc (sizeof *first);
- first->length = dialogex ? 26 : 18;
- first->data = (unsigned char *) reswr_alloc (first->length);
-
- length = first->length;
-
- if (! dialogex)
- {
- put_32 (big_endian, dialog->style, first->data);
- put_32 (big_endian, dialog->exstyle, first->data + 4);
- off = 8;
- }
- else
- {
- put_16 (big_endian, 1, first->data);
- put_16 (big_endian, 0xffff, first->data + 2);
-
- if (dialog->ex == NULL)
- put_32 (big_endian, 0, first->data + 4);
- else
- put_32 (big_endian, dialog->ex->help, first->data + 4);
- put_32 (big_endian, dialog->exstyle, first->data + 8);
- put_32 (big_endian, dialog->style, first->data + 12);
- off = 16;
- }
-
- put_16 (big_endian, dialog->x, first->data + off + 2);
- put_16 (big_endian, dialog->y, first->data + off + 4);
- put_16 (big_endian, dialog->width, first->data + off + 6);
- put_16 (big_endian, dialog->height, first->data + off + 8);
-
- pp = &first->next;
-
- *pp = resid_to_bin (dialog->menu, big_endian);
- length += (*pp)->length;
- pp = &(*pp)->next;
-
- *pp = resid_to_bin (dialog->class, big_endian);
- length += (*pp)->length;
- pp = &(*pp)->next;
-
- *pp = unicode_to_bin (dialog->caption, big_endian);
- length += (*pp)->length;
- pp = &(*pp)->next;
-
- if ((dialog->style & DS_SETFONT) != 0)
- {
- struct bindata *d;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = dialogex ? 6 : 2;
- d->data = (unsigned char *) reswr_alloc (d->length);
-
- length += d->length;
-
- put_16 (big_endian, dialog->pointsize, d->data);
-
- if (dialogex)
- {
- if (dialog->ex == NULL)
- {
- put_16 (big_endian, 0, d->data + 2);
- put_16 (big_endian, 0, d->data + 4);
- }
- else
- {
- put_16 (big_endian, dialog->ex->weight, d->data + 2);
- put_16 (big_endian, dialog->ex->italic, d->data + 4);
- }
- }
-
- *pp = d;
- pp = &d->next;
-
- *pp = unicode_to_bin (dialog->font, big_endian);
- length += (*pp)->length;
- pp = &(*pp)->next;
- }
-
- c = 0;
- for (dc = dialog->controls; dc != NULL; dc = dc->next)
- {
- struct bindata *d;
- int dcoff;
-
- ++c;
-
- dword_align_bin (&pp, &length);
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = dialogex ? 24 : 18;
- d->data = (unsigned char *) reswr_alloc (d->length);
-
- length += d->length;
-
- if (! dialogex)
- {
- put_32 (big_endian, dc->style, d->data);
- put_32 (big_endian, dc->exstyle, d->data + 4);
- dcoff = 8;
- }
- else
- {
- put_32 (big_endian, dc->help, d->data);
- put_32 (big_endian, dc->exstyle, d->data + 4);
- put_32 (big_endian, dc->style, d->data + 8);
- dcoff = 12;
- }
-
- put_16 (big_endian, dc->x, d->data + dcoff);
- put_16 (big_endian, dc->y, d->data + dcoff + 2);
- put_16 (big_endian, dc->width, d->data + dcoff + 4);
- put_16 (big_endian, dc->height, d->data + dcoff + 6);
-
- if (dialogex)
- put_32 (big_endian, dc->id, d->data + dcoff + 8);
- else
- put_16 (big_endian, dc->id, d->data + dcoff + 8);
-
- *pp = d;
- pp = &d->next;
-
- *pp = resid_to_bin (dc->class, big_endian);
- length += (*pp)->length;
- pp = &(*pp)->next;
-
- *pp = resid_to_bin (dc->text, big_endian);
- length += (*pp)->length;
- pp = &(*pp)->next;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = 2;
- d->data = (unsigned char *) reswr_alloc (2);
-
- length += 2;
-
- d->next = NULL;
- *pp = d;
- pp = &d->next;
-
- if (dc->data == NULL)
- put_16 (big_endian, 0, d->data);
- else
- {
- unsigned long sublen;
-
- dword_align_bin (&pp, &length);
-
- *pp = res_to_bin_rcdata (dc->data, big_endian);
- sublen = 0;
- while (*pp != NULL)
- {
- sublen += (*pp)->length;
- pp = &(*pp)->next;
- }
-
- put_16 (big_endian, sublen, d->data);
-
- length += sublen;
- }
- }
- put_16 (big_endian, c, first->data + off);
-
- return first;
-}
-
-/* Convert a fontdir resource to binary. */
-
-static struct bindata *
-res_to_bin_fontdir (fontdirs, big_endian)
- const struct fontdir *fontdirs;
- int big_endian;
-{
- struct bindata *first, **pp;
- int c;
- const struct fontdir *fd;
-
- first = (struct bindata *) reswr_alloc (sizeof *first);
- first->length = 2;
- first->data = (unsigned char *) reswr_alloc (2);
-
- first->next = NULL;
- pp = &first->next;
-
- c = 0;
- for (fd = fontdirs; fd != NULL; fd = fd->next)
- {
- struct bindata *d;
-
- ++c;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = 2;
- d->data = (unsigned char *) reswr_alloc (2);
-
- put_16 (big_endian, fd->index, d->data);
-
- *pp = d;
- pp = &d->next;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = fd->length;
- d->data = (unsigned char *) fd->data;
-
- d->next = NULL;
- *pp = d;
- pp = &d->next;
- }
-
- put_16 (big_endian, c, first->data);
-
- return first;
-}
-
-/* Convert a group icon resource to binary. */
-
-static struct bindata *
-res_to_bin_group_icon (group_icons, big_endian)
- const struct group_icon *group_icons;
- int big_endian;
-{
- struct bindata *first, **pp;
- int c;
- const struct group_icon *gi;
-
- first = (struct bindata *) reswr_alloc (sizeof *first);
- first->length = 6;
- first->data = (unsigned char *) reswr_alloc (6);
-
- put_16 (big_endian, 0, first->data);
- put_16 (big_endian, 1, first->data + 2);
-
- first->next = NULL;
- pp = &first->next;
-
- c = 0;
- for (gi = group_icons; gi != NULL; gi = gi->next)
- {
- struct bindata *d;
-
- ++c;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = 14;
- d->data = (unsigned char *) reswr_alloc (14);
-
- d->data[0] = gi->width;
- d->data[1] = gi->height;
- d->data[2] = gi->colors;
- d->data[3] = 0;
- put_16 (big_endian, gi->planes, d->data + 4);
- put_16 (big_endian, gi->bits, d->data + 6);
- put_32 (big_endian, gi->bytes, d->data + 8);
- put_16 (big_endian, gi->index, d->data + 12);
-
- d->next = NULL;
- *pp = d;
- pp = &d->next;
- }
-
- put_16 (big_endian, c, first->data + 4);
-
- return first;
-}
-
-/* Convert a menu resource to binary. */
-
-static struct bindata *
-res_to_bin_menu (menu, big_endian)
- const struct menu *menu;
- int big_endian;
-{
- int menuex;
- struct bindata *d;
-
- menuex = extended_menu (menu);
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = menuex ? 8 : 4;
- d->data = (unsigned char *) reswr_alloc (d->length);
-
- if (! menuex)
- {
- put_16 (big_endian, 0, d->data);
- put_16 (big_endian, 0, d->data + 2);
-
- d->next = res_to_bin_menuitems (menu->items, big_endian);
- }
- else
- {
- put_16 (big_endian, 1, d->data);
- put_16 (big_endian, 4, d->data + 2);
- put_32 (big_endian, menu->help, d->data + 4);
-
- d->next = res_to_bin_menuexitems (menu->items, big_endian);
- }
-
- return d;
-}
-
-/* Convert menu items to binary. */
-
-static struct bindata *
-res_to_bin_menuitems (items, big_endian)
- const struct menuitem *items;
- int big_endian;
-{
- struct bindata *first, **pp;
- const struct menuitem *mi;
-
- first = NULL;
- pp = &first;
-
- for (mi = items; mi != NULL; mi = mi->next)
- {
- struct bindata *d;
- int flags;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = mi->popup == NULL ? 4 : 2;
- d->data = (unsigned char *) reswr_alloc (d->length);
-
- flags = mi->type;
- if (mi->next == NULL)
- flags |= MENUITEM_ENDMENU;
- if (mi->popup != NULL)
- flags |= MENUITEM_POPUP;
-
- put_16 (big_endian, flags, d->data);
-
- if (mi->popup == NULL)
- put_16 (big_endian, mi->id, d->data + 2);
-
- *pp = d;
- pp = &d->next;
-
- *pp = unicode_to_bin (mi->text, big_endian);
- pp = &(*pp)->next;
-
- if (mi->popup != NULL)
- {
- *pp = res_to_bin_menuitems (mi->popup, big_endian);
- while (*pp != NULL)
- pp = &(*pp)->next;
- }
- }
-
- return first;
-}
-
-/* Convert menuex items to binary. */
-
-static struct bindata *
-res_to_bin_menuexitems (items, big_endian)
- const struct menuitem *items;
- int big_endian;
-{
- struct bindata *first, **pp;
- unsigned long length;
- const struct menuitem *mi;
-
- first = NULL;
- pp = &first;
-
- length = 0;
-
- for (mi = items; mi != NULL; mi = mi->next)
- {
- struct bindata *d;
- int flags;
-
- dword_align_bin (&pp, &length);
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = 12;
- d->data = (unsigned char *) reswr_alloc (12);
-
- length += 12;
-
- put_32 (big_endian, mi->type, d->data);
- put_32 (big_endian, mi->state, d->data + 4);
- put_16 (big_endian, mi->id, d->data + 8);
-
- flags = 0;
- if (mi->next == NULL)
- flags |= 0x80;
- if (mi->popup != NULL)
- flags |= 1;
- put_16 (big_endian, flags, d->data + 10);
-
- *pp = d;
- pp = &d->next;
-
- *pp = unicode_to_bin (mi->text, big_endian);
- length += (*pp)->length;
- pp = &(*pp)->next;
-
- if (mi->popup != NULL)
- {
- dword_align_bin (&pp, &length);
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = 4;
- d->data = (unsigned char *) reswr_alloc (4);
-
- put_32 (big_endian, mi->help, d->data);
-
- *pp = d;
- pp = &d->next;
-
- *pp = res_to_bin_menuexitems (mi->popup, big_endian);
- while (*pp != NULL)
- {
- length += (*pp)->length;
- pp = &(*pp)->next;
- }
- }
- }
-
- return first;
-}
-
-/* Convert an rcdata resource to binary. This is also used to convert
- other information which happens to be stored in rcdata_item lists
- to binary. */
-
-static struct bindata *
-res_to_bin_rcdata (items, big_endian)
- const struct rcdata_item *items;
- int big_endian;
-{
- struct bindata *first, **pp;
- const struct rcdata_item *ri;
-
- first = NULL;
- pp = &first;
-
- for (ri = items; ri != NULL; ri = ri->next)
- {
- struct bindata *d;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
-
- switch (ri->type)
- {
- default:
- abort ();
-
- case RCDATA_WORD:
- d->length = 2;
- d->data = (unsigned char *) reswr_alloc (2);
- put_16 (big_endian, ri->u.word, d->data);
- break;
-
- case RCDATA_DWORD:
- d->length = 4;
- d->data = (unsigned char *) reswr_alloc (4);
- put_32 (big_endian, ri->u.dword, d->data);
- break;
-
- case RCDATA_STRING:
- d->length = ri->u.string.length;
- d->data = (unsigned char *) ri->u.string.s;
- break;
-
- case RCDATA_WSTRING:
- {
- unsigned long i;
-
- d->length = ri->u.wstring.length * 2;
- d->data = (unsigned char *) reswr_alloc (d->length);
- for (i = 0; i < ri->u.wstring.length; i++)
- put_16 (big_endian, ri->u.wstring.w[i], d->data + i * 2);
- break;
- }
-
- case RCDATA_BUFFER:
- d->length = ri->u.buffer.length;
- d->data = (unsigned char *) ri->u.buffer.data;
- break;
- }
-
- d->next = NULL;
- *pp = d;
- pp = &d->next;
- }
-
- return first;
-}
-
-/* Convert a stringtable resource to binary. */
-
-static struct bindata *
-res_to_bin_stringtable (st, big_endian)
- const struct stringtable *st;
- int big_endian;
-{
- struct bindata *first, **pp;
- int i;
-
- first = NULL;
- pp = &first;
-
- for (i = 0; i < 16; i++)
- {
- int slen, j;
- struct bindata *d;
- unichar *s;
-
- slen = st->strings[i].length;
- s = st->strings[i].string;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = 2 + slen * 2;
- d->data = (unsigned char *) reswr_alloc (d->length);
-
- put_16 (big_endian, slen, d->data);
-
- for (j = 0; j < slen; j++)
- put_16 (big_endian, s[j], d->data + 2 + j * 2);
-
- d->next = NULL;
- *pp = d;
- pp = &d->next;
- }
-
- return first;
-}
-
-/* Convert an ASCII string to a unicode binary string. This always
- returns exactly one bindata structure. */
-
-static struct bindata *
-string_to_unicode_bin (s, big_endian)
- const char *s;
- int big_endian;
-{
- size_t len, i;
- struct bindata *d;
-
- len = strlen (s);
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = len * 2 + 2;
- d->data = (unsigned char *) reswr_alloc (d->length);
-
- for (i = 0; i < len; i++)
- put_16 (big_endian, s[i], d->data + i * 2);
- put_16 (big_endian, 0, d->data + i * 2);
-
- d->next = NULL;
-
- return d;
-}
-
-/* Convert a versioninfo resource to binary. */
-
-static struct bindata *
-res_to_bin_versioninfo (versioninfo, big_endian)
- const struct versioninfo *versioninfo;
- int big_endian;
-{
- struct bindata *first, **pp;
- unsigned long length;
- struct ver_info *vi;
-
- first = (struct bindata *) reswr_alloc (sizeof *first);
- first->length = 6;
- first->data = (unsigned char *) reswr_alloc (6);
-
- length = 6;
-
- if (versioninfo->fixed == NULL)
- put_16 (big_endian, 0, first->data + 2);
- else
- put_16 (big_endian, 52, first->data + 2);
-
- put_16 (big_endian, 0, first->data + 4);
-
- pp = &first->next;
-
- *pp = string_to_unicode_bin ("VS_VERSION_INFO", big_endian);
- length += (*pp)->length;
- pp = &(*pp)->next;
-
- dword_align_bin (&pp, &length);
-
- if (versioninfo->fixed != NULL)
- {
- const struct fixed_versioninfo *fi;
- struct bindata *d;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = 52;
- d->data = (unsigned char *) reswr_alloc (52);
-
- length += 52;
-
- fi = versioninfo->fixed;
-
- put_32 (big_endian, 0xfeef04bd, d->data);
- put_32 (big_endian, 0x10000, d->data + 4);
- put_32 (big_endian, fi->file_version_ms, d->data + 8);
- put_32 (big_endian, fi->file_version_ls, d->data + 12);
- put_32 (big_endian, fi->product_version_ms, d->data + 16);
- put_32 (big_endian, fi->product_version_ls, d->data + 20);
- put_32 (big_endian, fi->file_flags_mask, d->data + 24);
- put_32 (big_endian, fi->file_flags, d->data + 28);
- put_32 (big_endian, fi->file_os, d->data + 32);
- put_32 (big_endian, fi->file_type, d->data + 36);
- put_32 (big_endian, fi->file_subtype, d->data + 40);
- put_32 (big_endian, fi->file_date_ms, d->data + 44);
- put_32 (big_endian, fi->file_date_ls, d->data + 48);
-
- d->next = NULL;
- *pp = d;
- pp = &d->next;
- }
-
- for (vi = versioninfo->var; vi != NULL; vi = vi->next)
- {
- struct bindata *vid;
- unsigned long vilen;
-
- dword_align_bin (&pp, &length);
-
- vid = (struct bindata *) reswr_alloc (sizeof *vid);
- vid->length = 6;
- vid->data = (unsigned char *) reswr_alloc (6);
-
- length += 6;
- vilen = 6;
-
- put_16 (big_endian, 0, vid->data + 2);
- put_16 (big_endian, 0, vid->data + 4);
-
- *pp = vid;
- pp = &vid->next;
-
- switch (vi->type)
- {
- default:
- abort ();
-
- case VERINFO_STRING:
- {
- unsigned long hold, vslen;
- struct bindata *vsd;
- const struct ver_stringinfo *vs;
-
- *pp = string_to_unicode_bin ("StringFileInfo", big_endian);
- length += (*pp)->length;
- vilen += (*pp)->length;
- pp = &(*pp)->next;
-
- hold = length;
- dword_align_bin (&pp, &length);
- vilen += length - hold;
-
- vsd = (struct bindata *) reswr_alloc (sizeof *vsd);
- vsd->length = 6;
- vsd->data = (unsigned char *) reswr_alloc (6);
-
- length += 6;
- vilen += 6;
- vslen = 6;
-
- put_16 (big_endian, 0, vsd->data + 2);
- put_16 (big_endian, 0, vsd->data + 4);
-
- *pp = vsd;
- pp = &vsd->next;
-
- *pp = unicode_to_bin (vi->u.string.language, big_endian);
- length += (*pp)->length;
- vilen += (*pp)->length;
- vslen += (*pp)->length;
- pp = &(*pp)->next;
-
- for (vs = vi->u.string.strings; vs != NULL; vs = vs->next)
- {
- struct bindata *vssd;
- unsigned long vsslen;
-
- hold = length;
- dword_align_bin (&pp, &length);
- vilen += length - hold;
- vslen += length - hold;
-
- vssd = (struct bindata *) reswr_alloc (sizeof *vssd);
- vssd->length = 6;
- vssd->data = (unsigned char *) reswr_alloc (6);
-
- length += 6;
- vilen += 6;
- vslen += 6;
- vsslen = 6;
-
- put_16 (big_endian, 1, vssd->data + 4);
-
- *pp = vssd;
- pp = &vssd->next;
-
- *pp = unicode_to_bin (vs->key, big_endian);
- length += (*pp)->length;
- vilen += (*pp)->length;
- vslen += (*pp)->length;
- vsslen += (*pp)->length;
- pp = &(*pp)->next;
-
- hold = length;
- dword_align_bin (&pp, &length);
- vilen += length - hold;
- vslen += length - hold;
- vsslen += length - hold;
-
- *pp = unicode_to_bin (vs->value, big_endian);
- put_16 (big_endian, (*pp)->length / 2, vssd->data + 2);
- length += (*pp)->length;
- vilen += (*pp)->length;
- vslen += (*pp)->length;
- vsslen += (*pp)->length;
- pp = &(*pp)->next;
-
- put_16 (big_endian, vsslen, vssd->data);
- }
-
- put_16 (big_endian, vslen, vsd->data);
-
- break;
- }
-
- case VERINFO_VAR:
- {
- unsigned long hold, vvlen, vvvlen;
- struct bindata *vvd;
- const struct ver_varinfo *vv;
-
- *pp = string_to_unicode_bin ("VarFileInfo", big_endian);
- length += (*pp)->length;
- vilen += (*pp)->length;
- pp = &(*pp)->next;
-
- hold = length;
- dword_align_bin (&pp, &length);
- vilen += length - hold;
-
- vvd = (struct bindata *) reswr_alloc (sizeof *vvd);
- vvd->length = 6;
- vvd->data = (unsigned char *) reswr_alloc (6);
-
- length += 6;
- vilen += 6;
- vvlen = 6;
-
- put_16 (big_endian, 0, vvd->data + 4);
-
- *pp = vvd;
- pp = &vvd->next;
-
- *pp = unicode_to_bin (vi->u.var.key, big_endian);
- length += (*pp)->length;
- vilen += (*pp)->length;
- vvlen += (*pp)->length;
- pp = &(*pp)->next;
-
- hold = length;
- dword_align_bin (&pp, &length);
- vilen += length - hold;
- vvlen += length - hold;
-
- vvvlen = 0;
-
- for (vv = vi->u.var.var; vv != NULL; vv = vv->next)
- {
- struct bindata *vvsd;
-
- vvsd = (struct bindata *) reswr_alloc (sizeof *vvsd);
- vvsd->length = 4;
- vvsd->data = (unsigned char *) reswr_alloc (4);
-
- length += 4;
- vilen += 4;
- vvlen += 4;
- vvvlen += 4;
-
- put_16 (big_endian, vv->language, vvsd->data);
- put_16 (big_endian, vv->charset, vvsd->data + 2);
-
- vvsd->next = NULL;
- *pp = vvsd;
- pp = &vvsd->next;
- }
-
- put_16 (big_endian, vvlen, vvd->data);
- put_16 (big_endian, vvvlen, vvd->data + 2);
-
- break;
- }
- }
-
- put_16 (big_endian, vilen, vid->data);
- }
-
- put_16 (big_endian, length, first->data);
-
- return first;
-}
-
-/* Convert a generic resource to binary. */
-
-static struct bindata *
-res_to_bin_generic (length, data)
- unsigned long length;
- const unsigned char *data;
-{
- struct bindata *d;
-
- d = (struct bindata *) reswr_alloc (sizeof *d);
- d->length = length;
- d->data = (unsigned char *) data;
-
- d->next = NULL;
-
- return d;
-}