/* resbin.c -- manipulate the Windows binary resource format.
   Copyright (C) 1997-2021 Free Software Foundation, Inc.
   Written by Ian Lance Taylor, Cygnus Support.
   Rewritten by Kai Tietz, Onevision.

   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 3 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., 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, 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 "sysdep.h"
#include "bfd.h"
#include "bucomm.h"
#include "libiberty.h"
#include "windres.h"

/* Local functions.  */

static void toosmall (const char *);

static unichar *get_unicode (windres_bfd *, const bfd_byte *, rc_uint_type, rc_uint_type *);
static int get_resid (windres_bfd *, rc_res_id *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_generic (windres_bfd *, enum rc_res_type,
					    const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_cursor (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_menu (windres_bfd *,const bfd_byte *, rc_uint_type);
static rc_menuitem *bin_to_res_menuitems (windres_bfd *, const bfd_byte *, rc_uint_type,
					  rc_uint_type *);
static rc_menuitem *bin_to_res_menuexitems (windres_bfd *, const bfd_byte *, rc_uint_type,
					    rc_uint_type *);
static rc_res_resource *bin_to_res_dialog (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_string (windres_bfd *,const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_fontdir (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_accelerators (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_rcdata (windres_bfd *, const bfd_byte *, rc_uint_type, int);
static rc_res_resource *bin_to_res_group_cursor (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_group_icon (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_version (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_userdata (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_toolbar (windres_bfd *, const bfd_byte *, rc_uint_type);
static void get_version_header (windres_bfd *, const bfd_byte *, rc_uint_type, const char *,
				unichar **, rc_uint_type *, rc_uint_type *, rc_uint_type *,
				rc_uint_type *);

/* Given a resource type ID, a pointer to data, a length, return a
   rc_res_resource structure which represents that resource.  The caller
   is responsible for initializing the res_info and coff_info fields
   of the returned structure.  */

rc_res_resource *
bin_to_res (windres_bfd *wrbfd, rc_res_id type, const bfd_byte *data,
	    rc_uint_type length)
{
  if (type.named)
    return bin_to_res_userdata (wrbfd, data, length);
  else
    {
      switch (type.u.id)
	{
	default:
	  return bin_to_res_userdata (wrbfd, data, length);
	case RT_CURSOR:
	  return bin_to_res_cursor (wrbfd, data, length);
	case RT_BITMAP:
	  return bin_to_res_generic (wrbfd, RES_TYPE_BITMAP, data, length);
	case RT_ICON:
	  return bin_to_res_generic (wrbfd, RES_TYPE_ICON, data, length);
	case RT_MENU:
	  return bin_to_res_menu (wrbfd, data, length);
	case RT_DIALOG:
	  return bin_to_res_dialog (wrbfd, data, length);
	case RT_STRING:
	  return bin_to_res_string (wrbfd, data, length);
	case RT_FONTDIR:
	  return bin_to_res_fontdir (wrbfd, data, length);
	case RT_FONT:
	  return bin_to_res_generic (wrbfd, RES_TYPE_FONT, data, length);
	case RT_ACCELERATOR:
	  return bin_to_res_accelerators (wrbfd, data, length);
	case RT_RCDATA:
	  return bin_to_res_rcdata (wrbfd, data, length, RES_TYPE_RCDATA);
	case RT_MESSAGETABLE:
	  return bin_to_res_generic (wrbfd, RES_TYPE_MESSAGETABLE, data, length);
	case RT_GROUP_CURSOR:
	  return bin_to_res_group_cursor (wrbfd, data, length);
	case RT_GROUP_ICON:
	  return bin_to_res_group_icon (wrbfd, data, length);
	case RT_VERSION:
	  return bin_to_res_version (wrbfd, data, length);
	case RT_TOOLBAR:
	  return  bin_to_res_toolbar (wrbfd, data, length);

	}
    }
}

/* Give an error if the binary data is too small.  */

static void
toosmall (const char *msg)
{
  fatal (_("%s: not enough binary data"), msg);
}

/* Swap in a NULL terminated unicode string.  */

static unichar *
get_unicode (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
	     rc_uint_type *retlen)
{
  rc_uint_type c, i;
  unichar *ret;

  c = 0;
  while (1)
    {
      if (length < c * 2 + 2)
	toosmall (_("null terminated unicode string"));
      if (windres_get_16 (wrbfd, data + c * 2, 2) == 0)
	break;
      ++c;
    }

  ret = (unichar *) res_alloc ((c + 1) * sizeof (unichar));

  for (i = 0; i < c; i++)
    ret[i] = windres_get_16 (wrbfd, data + i * 2, 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 (windres_bfd *wrbfd, rc_res_id *id, const bfd_byte *data,
	   rc_uint_type length)
{
  rc_uint_type first;

  if (length < 2)
    toosmall (_("resource ID"));

  first = windres_get_16 (wrbfd, data, 2);
  if (first == 0xffff)
    {
      if (length < 4)
	toosmall (_("resource ID"));
      id->named = 0;
      id->u.id = windres_get_16 (wrbfd, data + 2, 2);
      return 4;
    }
  else
    {
      id->named = 1;
      id->u.n.name = get_unicode (wrbfd, data, length, &id->u.n.length);
      return id->u.n.length * 2 + 2;
    }
}

/* Convert a resource which just stores uninterpreted data from
   binary.  */

rc_res_resource *
bin_to_res_generic (windres_bfd *wrbfd ATTRIBUTE_UNUSED, enum rc_res_type type,
		    const bfd_byte *data, rc_uint_type length)
{
  rc_res_resource *r;

  r = (rc_res_resource *) res_alloc (sizeof (rc_res_resource));
  r->type = type;
  r->u.data.data = data;
  r->u.data.length = length;

  return r;
}

/* Convert a cursor resource from binary.  */

rc_res_resource *
bin_to_res_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_cursor *c;
  rc_res_resource *r;

  if (length < 4)
    toosmall (_("cursor"));

  c = (rc_cursor *) res_alloc (sizeof (rc_cursor));
  c->xhotspot = windres_get_16 (wrbfd, data, 2);
  c->yhotspot = windres_get_16 (wrbfd, data + 2, 2);
  c->length = length - 4;
  c->data = data + 4;

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_CURSOR;
  r->u.cursor = c;

  return r;
}

/* Convert a menu resource from binary.  */

rc_res_resource *
bin_to_res_menu (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_res_resource *r;
  rc_menu *m;
  rc_uint_type version, got;

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_MENU;

  m = (rc_menu *) res_alloc (sizeof (rc_menu));
  r->u.menu = m;

  if (length < 2)
    toosmall (_("menu header"));

  version = windres_get_16 (wrbfd, data, 2);

  if (version == 0)
    {
      if (length < 4)
	toosmall (_("menu header"));
      m->help = 0;
      m->items = bin_to_res_menuitems (wrbfd, data + 4, length - 4, &got);
    }
  else if (version == 1)
    {
      rc_uint_type offset;

      if (length < 8)
	toosmall (_("menuex header"));
      m->help = windres_get_32 (wrbfd, data + 4, 4);
      offset = windres_get_16 (wrbfd, data + 2, 2);
      if (offset + 4 >= length)
	toosmall (_("menuex offset"));
      m->items = bin_to_res_menuexitems (wrbfd, data + 4 + offset,
					 length - (4 + offset), &got);
    }
  else
    fatal (_("unsupported menu version %d"), (int) version);

  return r;
}

/* Convert menu items from binary.  */

static rc_menuitem *
bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
		      rc_uint_type *got)
{
  rc_menuitem *first, **pp;

  first = NULL;
  pp = &first;

  *got = 0;

  while (length > 0)
    {
      rc_uint_type flags, slen, itemlen;
      rc_uint_type stroff;
      rc_menuitem *mi;

      if (length < 4)
	toosmall (_("menuitem header"));

      mi = (rc_menuitem *) res_alloc (sizeof *mi);
      mi->state = 0;
      mi->help = 0;

      flags = windres_get_16 (wrbfd, data, 2);
      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 (windres_get_16 (wrbfd, data + stroff, 2) == 0)
	{
	  slen = 0;
	  mi->text = NULL;
	}
      else
	mi->text = get_unicode (wrbfd, data + stroff, length - stroff, &slen);

      itemlen = stroff + slen * 2 + 2;

      if ((flags & MENUITEM_POPUP) == 0)
	{
	  mi->popup = NULL;
	  mi->id = windres_get_16 (wrbfd, data + 2, 2);
	}
      else
	{
	  rc_uint_type subread;

	  mi->id = 0;
	  mi->popup = bin_to_res_menuitems (wrbfd, data + itemlen, length - itemlen,
	  				    &subread);
	  itemlen += subread;
	}

      mi->next = NULL;
      *pp = mi;
      pp = &mi->next;

      data += itemlen;
      length -= itemlen;
      *got += itemlen;

      if ((flags & MENUITEM_ENDMENU) != 0)
	return first;
    }

  return first;
}

/* Convert menuex items from binary.  */

static rc_menuitem *
bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
			rc_uint_type *got)
{
  rc_menuitem *first, **pp;

  first = NULL;
  pp = &first;

  *got = 0;

  while (length > 0)
    {
      rc_uint_type flags, slen;
      rc_uint_type itemlen;
      rc_menuitem *mi;

      if (length < 16)
	toosmall (_("menuitem header"));

      mi = (rc_menuitem *) res_alloc (sizeof (rc_menuitem));
      mi->type = windres_get_32 (wrbfd, data, 4);
      mi->state = windres_get_32 (wrbfd, data + 4, 4);
      mi->id = windres_get_32 (wrbfd, data + 8, 4);

      flags = windres_get_16 (wrbfd, data + 12, 2);

      if (windres_get_16 (wrbfd, data + 14, 2) == 0)
	{
	  slen = 0;
	  mi->text = NULL;
	}
      else
	mi->text = get_unicode (wrbfd, data + 14, length - 14, &slen);

      itemlen = 14 + slen * 2 + 2;
      itemlen = (itemlen + 3) &~ 3;

      if ((flags & 1) == 0)
	{
	  mi->popup = NULL;
	  mi->help = 0;
	}
      else
	{
	  rc_uint_type subread;

	  if (length < itemlen + 4)
	    toosmall (_("menuitem"));
	  mi->help = windres_get_32 (wrbfd, data + itemlen, 4);
	  itemlen += 4;

	  mi->popup = bin_to_res_menuexitems (wrbfd, data + itemlen,
					      length - itemlen, &subread);
	  itemlen += subread;
	}

      mi->next = NULL;
      *pp = mi;
      pp = &mi->next;

      data += itemlen;
      length -= itemlen;
      *got += itemlen;

      if ((flags & 0x80) != 0)
	return first;
    }

  return first;
}

/* Convert a dialog resource from binary.  */

static rc_res_resource *
bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_uint_type signature;
  rc_dialog *d;
  rc_uint_type c, sublen, i;
  rc_uint_type off;
  rc_dialog_control **pp;
  rc_res_resource *r;

  if (length < 18)
    toosmall (_("dialog header"));

  d = (rc_dialog *) res_alloc (sizeof (rc_dialog));

  signature = windres_get_16 (wrbfd, data + 2, 2);
  if (signature != 0xffff)
    {
      d->ex = NULL;
      d->style = windres_get_32 (wrbfd, data, 4);
      d->exstyle = windres_get_32 (wrbfd, data + 4, 4);
      off = 8;
    }
  else
    {
      int version;

      version = windres_get_16 (wrbfd, data, 2);
      if (version != 1)
	fatal (_("unexpected DIALOGEX version %d"), version);

      d->ex = (rc_dialog_ex *) res_alloc (sizeof (rc_dialog_ex));
      d->ex->help = windres_get_32 (wrbfd, data + 4, 4);
      d->exstyle = windres_get_32 (wrbfd, data + 8, 4);
      d->style = windres_get_32 (wrbfd, data + 12, 4);
      off = 16;
    }

  if (length < off + 10)
    toosmall (_("dialog header"));

  c = windres_get_16 (wrbfd, data + off, 2);
  d->x = windres_get_16 (wrbfd, data + off + 2, 2);
  d->y = windres_get_16 (wrbfd, data + off + 4, 2);
  d->width = windres_get_16 (wrbfd, data + off + 6, 2);
  d->height = windres_get_16 (wrbfd, data + off + 8, 2);

  off += 10;

  sublen = get_resid (wrbfd, &d->menu, data + off, length - off);
  off += sublen;

  sublen = get_resid (wrbfd, &d->class, data + off, length - off);
  off += sublen;

  d->caption = get_unicode (wrbfd, data + off, length - off, &sublen);
  off += sublen * 2 + 2;
  if (sublen == 0)
    d->caption = NULL;

  if ((d->style & DS_SETFONT) == 0)
    {
      d->pointsize = 0;
      d->font = NULL;
      if (d->ex != NULL)
	{
	  d->ex->weight = 0;
	  d->ex->italic = 0;
	  d->ex->charset = 1; /* Default charset.  */
	}
    }
  else
    {
      if (length < off + 2)
	toosmall (_("dialog font point size"));

      d->pointsize = windres_get_16 (wrbfd, data + off, 2);
      off += 2;

      if (d->ex != NULL)
	{
	  if (length < off + 4)
	    toosmall (_("dialogex font information"));
	  d->ex->weight = windres_get_16 (wrbfd, data + off, 2);
	  d->ex->italic = windres_get_8 (wrbfd, data + off + 2, 1);
	  d->ex->charset = windres_get_8 (wrbfd, data + off + 3, 1);
	  off += 4;
	}

      d->font = get_unicode (wrbfd, data + off, length - off, &sublen);
      off += sublen * 2 + 2;
    }

  d->controls = NULL;
  pp = &d->controls;

  for (i = 0; i < c; i++)
    {
      rc_dialog_control *dc;
      int datalen;

      off = (off + 3) &~ 3;

      dc = (rc_dialog_control *) res_alloc (sizeof (rc_dialog_control));

      if (d->ex == NULL)
	{
	  if (length < off + 8)
	    toosmall (_("dialog control"));

	  dc->style = windres_get_32 (wrbfd, data + off, 4);
	  dc->exstyle = windres_get_32 (wrbfd, data + off + 4, 4);
	  dc->help = 0;
	  off += 8;
	}
      else
	{
	  if (length < off + 12)
	    toosmall (_("dialogex control"));
	  dc->help = windres_get_32 (wrbfd, data + off, 4);
	  dc->exstyle = windres_get_32 (wrbfd, data + off + 4, 4);
	  dc->style = windres_get_32 (wrbfd, data + off + 8, 4);
	  off += 12;
	}

      if (length < off + (d->ex != NULL ? 2 : 0) + 10)
	toosmall (_("dialog control"));

      dc->x = windres_get_16 (wrbfd, data + off, 2);
      dc->y = windres_get_16 (wrbfd, data + off + 2, 2);
      dc->width = windres_get_16 (wrbfd, data + off + 4, 2);
      dc->height = windres_get_16 (wrbfd, data + off + 6, 2);

      if (d->ex != NULL)
	dc->id = windres_get_32 (wrbfd, data + off + 8, 4);
      else
	dc->id = windres_get_16 (wrbfd, data + off + 8, 2);

      off += 10 + (d->ex != NULL ? 2 : 0);

      sublen = get_resid (wrbfd, &dc->class, data + off, length - off);
      off += sublen;

      sublen = get_resid (wrbfd, &dc->text, data + off, length - off);
      off += sublen;

      if (length < off + 2)
	toosmall (_("dialog control end"));

      datalen = windres_get_16 (wrbfd, data + off, 2);
      off += 2;

      if (datalen == 0)
	dc->data = NULL;
      else
	{
	  if (length < off + datalen)
	    toosmall (_("dialog control data"));

	  dc->data = ((rc_rcdata_item *)
		      res_alloc (sizeof (rc_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 = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_DIALOG;
  r->u.dialog = d;

  return r;
}

/* Convert a stringtable resource from binary.  */

static rc_res_resource *
bin_to_res_string (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_stringtable *st;
  int i;
  rc_res_resource *r;

  st = (rc_stringtable *) res_alloc (sizeof (rc_stringtable));

  for (i = 0; i < 16; i++)
    {
      unsigned int slen;

      if (length < 2)
	toosmall (_("stringtable string length"));
      slen = windres_get_16 (wrbfd, data, 2);
      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] = windres_get_16 (wrbfd, data + 2 + j * 2, 2);
	}

      data += 2 + 2 * slen;
      length -= 2 + 2 * slen;
    }

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_STRINGTABLE;
  r->u.stringtable = st;

  return r;
}

/* Convert a fontdir resource from binary.  */

static rc_res_resource *
bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_uint_type c, i;
  rc_fontdir *first, **pp;
  rc_res_resource *r;

  if (length < 2)
    toosmall (_("fontdir header"));

  c = windres_get_16 (wrbfd, data, 2);

  first = NULL;
  pp = &first;

  for (i = 0; i < c; i++)
    {
      const struct bin_fontdir_item *bfi;
      rc_fontdir *fd;
      unsigned int off;

      if (length < 56)
	toosmall (_("fontdir"));

      bfi = (const struct bin_fontdir_item *) data;
      fd = (rc_fontdir *) res_alloc (sizeof *fd);
      fd->index = windres_get_16 (wrbfd, bfi->index, 2);

      /* 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 rc_fontdir.  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 = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_FONTDIR;
  r->u.fontdir = first;

  return r;
}

/* Convert an accelerators resource from binary.  */

static rc_res_resource *
bin_to_res_accelerators (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_accelerator *first, **pp;
  rc_res_resource *r;

  first = NULL;
  pp = &first;

  while (1)
    {
      rc_accelerator *a;

      if (length < 8)
	toosmall (_("accelerator"));

      a = (rc_accelerator *) res_alloc (sizeof (rc_accelerator));

      a->flags = windres_get_16 (wrbfd, data, 2);
      a->key = windres_get_16 (wrbfd, data + 2, 2);
      a->id = windres_get_16 (wrbfd, data + 4, 2);

      a->next = NULL;
      *pp = a;
      pp = &a->next;

      if ((a->flags & ACC_LAST) != 0)
	break;

      data += 8;
      length -= 8;
    }

  r = (rc_res_resource *) res_alloc (sizeof (rc_res_resource));
  r->type = RES_TYPE_ACCELERATOR;
  r->u.acc = first;

  return r;
}

/* Convert an rcdata resource from binary.  */

static rc_res_resource *
bin_to_res_rcdata (windres_bfd *wrbfd ATTRIBUTE_UNUSED, const bfd_byte *data,
		   rc_uint_type length, int rctyp)
{
  rc_rcdata_item *ri;
  rc_res_resource *r;

  ri = (rc_rcdata_item *) res_alloc (sizeof (rc_rcdata_item));

  ri->next = NULL;
  ri->type = RCDATA_BUFFER;
  ri->u.buffer.length = length;
  ri->u.buffer.data = data;

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = rctyp;
  r->u.rcdata = ri;

  return r;
}

/* Convert a group cursor resource from binary.  */

static rc_res_resource *
bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  int type, c, i;
  rc_group_cursor *first, **pp;
  rc_res_resource *r;

  if (length < 6)
    toosmall (_("group cursor header"));

  type = windres_get_16 (wrbfd, data + 2, 2);
  if (type != 2)
    fatal (_("unexpected group cursor type %d"), type);

  c = windres_get_16 (wrbfd, data + 4, 2);

  data += 6;
  length -= 6;

  first = NULL;
  pp = &first;

  for (i = 0; i < c; i++)
    {
      rc_group_cursor *gc;

      if (length < 14)
	toosmall (_("group cursor"));

      gc = (rc_group_cursor *) res_alloc (sizeof *gc);

      gc->width = windres_get_16 (wrbfd, data, 2);
      gc->height = windres_get_16 (wrbfd, data + 2, 2);
      gc->planes = windres_get_16 (wrbfd, data + 4, 2);
      gc->bits = windres_get_16 (wrbfd, data + 6, 2);
      gc->bytes = windres_get_32 (wrbfd, data + 8, 4);
      gc->index = windres_get_16 (wrbfd, data + 12, 2);

      gc->next = NULL;
      *pp = gc;
      pp = &gc->next;

      data += 14;
      length -= 14;
    }

  r = (rc_res_resource *) res_alloc (sizeof (rc_res_resource));
  r->type = RES_TYPE_GROUP_CURSOR;
  r->u.group_cursor = first;

  return r;
}

/* Convert a group icon resource from binary.  */

static rc_res_resource *
bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  int type, c, i;
  rc_group_icon *first, **pp;
  rc_res_resource *r;

  if (length < 6)
    toosmall (_("group icon header"));

  type = windres_get_16 (wrbfd, data + 2, 2);
  if (type != 1)
    fatal (_("unexpected group icon type %d"), type);

  c = windres_get_16 (wrbfd, data + 4, 2);

  data += 6;
  length -= 6;

  first = NULL;
  pp = &first;

  for (i = 0; i < c; i++)
    {
      rc_group_icon *gi;

      if (length < 14)
	toosmall (_("group icon"));

      gi = (rc_group_icon *) res_alloc (sizeof (rc_group_icon));

      gi->width = windres_get_8 (wrbfd, data, 1);
      gi->height = windres_get_8 (wrbfd, data + 1, 1);
      gi->colors = windres_get_8 (wrbfd, data + 2, 1);
      gi->planes = windres_get_16 (wrbfd, data + 4, 2);
      gi->bits = windres_get_16 (wrbfd, data + 6, 2);
      gi->bytes = windres_get_32 (wrbfd, data + 8, 4);
      gi->index = windres_get_16 (wrbfd, data + 12, 2);

      gi->next = NULL;
      *pp = gi;
      pp = &gi->next;

      data += 14;
      length -= 14;
    }

  r = (rc_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 (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
		    const char *key, unichar **pkey,
		    rc_uint_type *len, rc_uint_type *vallen, rc_uint_type *type,
		    rc_uint_type *off)
{
  if (length < 8)
    toosmall (key);

  *len = (windres_get_16 (wrbfd, data, 2) + 3) & ~3;
  *vallen = windres_get_16 (wrbfd, data + 2, 2);
  *type = windres_get_16 (wrbfd, data + 4, 2);

  *off = 6;

  length -= 6;
  data += 6;

  if (key == NULL)
    {
      rc_uint_type sublen;

      *pkey = get_unicode (wrbfd, data, length, &sublen);
      *off += (sublen + 1) * sizeof (unichar);
    }
  else
    {
      while (1)
	{
	  if (length < 2)
	    toosmall (key);
	  if (windres_get_16 (wrbfd, data, 2) != (bfd_byte) *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 rc_res_resource *
bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_uint_type verlen, vallen, type, off;
  rc_fixed_versioninfo *fi;
  rc_ver_info *first, **pp;
  rc_versioninfo *v;
  rc_res_resource *r;

  get_version_header (wrbfd, data, length, "VS_VERSION_INFO",
		      (unichar **) NULL, &verlen, &vallen, &type, &off);

  /* PR 17512: The verlen field does not include padding length.  */
  if (verlen > length)
    fatal (_("version length %lu greater than resource length %lu"),
	   (unsigned long) verlen, (unsigned long) length);

  if (type != 0)
    fatal (_("unexpected version type %d"), (int) type);

  /* PR 27686: Ignore any padding bytes after the end of the version structure.  */
  length = verlen;

  data += off;
  length -= off;

  if (vallen == 0)
    fi = NULL;
  else
    {
      unsigned long signature, fiv;

      if (vallen != 52)
	fatal (_("unexpected fixed version information length %ld"), (long) vallen);

      if (length < 52)
	toosmall (_("fixed version info"));

      signature = windres_get_32 (wrbfd, data, 4);
      if (signature != 0xfeef04bd)
	fatal (_("unexpected fixed version signature %lu"), signature);

      fiv = windres_get_32 (wrbfd, data + 4, 4);
      if (fiv != 0 && fiv != 0x10000)
	fatal (_("unexpected fixed version info version %lu"), fiv);

      fi = (rc_fixed_versioninfo *) res_alloc (sizeof (rc_fixed_versioninfo));

      fi->file_version_ms = windres_get_32 (wrbfd, data + 8, 4);
      fi->file_version_ls = windres_get_32 (wrbfd, data + 12, 4);
      fi->product_version_ms = windres_get_32 (wrbfd, data + 16, 4);
      fi->product_version_ls = windres_get_32 (wrbfd, data + 20, 4);
      fi->file_flags_mask = windres_get_32 (wrbfd, data + 24, 4);
      fi->file_flags = windres_get_32 (wrbfd, data + 28, 4);
      fi->file_os = windres_get_32 (wrbfd, data + 32, 4);
      fi->file_type = windres_get_32 (wrbfd, data + 36, 4);
      fi->file_subtype = windres_get_32 (wrbfd, data + 40, 4);
      fi->file_date_ms = windres_get_32 (wrbfd, data + 44, 4);
      fi->file_date_ls = windres_get_32 (wrbfd, data + 48, 4);

      data += 52;
      length -= 52;
    }

  first = NULL;
  pp = &first;

  while (length > 0)
    {
      rc_ver_info *vi;
      int ch;

      if (length < 8)
	toosmall (_("version var info"));

      vi = (rc_ver_info *) res_alloc (sizeof (rc_ver_info));

      ch = windres_get_16 (wrbfd, data + 6, 2);

      if (ch == 'S')
	{
	  rc_ver_stringtable **ppvst;

	  vi->type = VERINFO_STRING;

	  get_version_header (wrbfd, data, length, "StringFileInfo",
			      (unichar **) NULL, &verlen, &vallen, &type,
			      &off);

	  if (vallen != 0)
	    fatal (_("unexpected stringfileinfo value length %ld"), (long) vallen);

	  data += off;
	  length -= off;

	  verlen -= off;

	  vi->u.string.stringtables = NULL;
	  ppvst = &vi->u.string.stringtables;

	  while (verlen > 0)
	    {
	      rc_ver_stringtable *vst;
	      rc_uint_type stverlen;
	      rc_ver_stringinfo **ppvs;

	      if (length < 8)
		toosmall (_("version stringtable"));

	      vst = (rc_ver_stringtable *) res_alloc (sizeof (rc_ver_stringtable));

	      get_version_header (wrbfd, data, length, (const char *) NULL,
				  &vst->language, &stverlen, &vallen, &type, &off);

	      if (vallen != 0)
		fatal (_("unexpected version stringtable value length %ld"), (long) vallen);

	      data += off;
	      length -= off;
	      verlen -= off;

	  stverlen -= off;

	  vst->strings = NULL;
	  ppvs = &vst->strings;

	  while (stverlen > 0)
	    {
	      rc_ver_stringinfo *vs;
	      rc_uint_type sverlen, vslen, valoff;

	      if (length < 8)
		toosmall (_("version string"));

	      vs = (rc_ver_stringinfo *) res_alloc (sizeof (rc_ver_stringinfo));

	      get_version_header (wrbfd, data, length, (const char *) NULL,
				  &vs->key, &sverlen, &vallen, &type, &off);

	      data += off;
	      length -= off;

	      vs->value = get_unicode (wrbfd, data, length, &vslen);
	      valoff = vslen * 2 + 2;
	      valoff = (valoff + 3) & ~3;

	      if (off + valoff != sverlen)
		fatal (_("unexpected version string length %ld != %ld + %ld"),
		       (long) sverlen, (long) off, (long) valoff);

	      data += valoff;
	      length -= valoff;

	      if (stverlen < sverlen)
		fatal (_("unexpected version string length %ld < %ld"),
		       (long) verlen, (long) sverlen);
	      stverlen -= sverlen;
	      verlen -= sverlen;

	      vs->next = NULL;
	      *ppvs = vs;
	      ppvs = &vs->next;
	    }

	  vst->next = NULL;
	  *ppvst = vst;
	  ppvst = &vst->next;
	    }
	}
      else if (ch == 'V')
	{
	  rc_ver_varinfo **ppvv;

	  vi->type = VERINFO_VAR;

	  get_version_header (wrbfd, data, length, "VarFileInfo",
			      (unichar **) NULL, &verlen, &vallen, &type,
			      &off);

	  if (vallen != 0)
	    fatal (_("unexpected varfileinfo value length %ld"), (long) vallen);

	  data += off;
	  length -= off;

	  get_version_header (wrbfd, data, length, (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)
	    {
	      rc_ver_varinfo *vv;

	      if (length < 4)
		toosmall (_("version varfileinfo"));

	      vv = (rc_ver_varinfo *) res_alloc (sizeof (rc_ver_varinfo));

	      vv->language = windres_get_16 (wrbfd, data, 2);
	      vv->charset = windres_get_16 (wrbfd, data + 2, 2);

	      vv->next = NULL;
	      *ppvv = vv;
	      ppvv = &vv->next;

	      data += 4;
	      length -= 4;

	      if (vallen < 4)
		fatal (_("unexpected version value length %ld"), (long) vallen);

	      vallen -= 4;
	    }
	}
      else if (ch == 0)
	{
	  if (length == 8)
	    /* Padding - skip.  */
	    break;
	  fatal (_("nul bytes found in version string"));
	}
      else
	fatal (_("unexpected version string character: %x"), ch);

      vi->next = NULL;
      *pp = vi;
      pp = &vi->next;
    }

  v = (rc_versioninfo *) res_alloc (sizeof (rc_versioninfo));
  v->fixed = fi;
  v->var = first;

  r = (rc_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 rc_res_resource *
bin_to_res_userdata (windres_bfd *wrbfd ATTRIBUTE_UNUSED, const bfd_byte *data,
		     rc_uint_type length)
{
  rc_rcdata_item *ri;
  rc_res_resource *r;

  ri = (rc_rcdata_item *) res_alloc (sizeof (rc_rcdata_item));

  ri->next = NULL;
  ri->type = RCDATA_BUFFER;
  ri->u.buffer.length = length;
  ri->u.buffer.data = data;

  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_USERDATA;
  r->u.rcdata = ri;

  return r;
}

static rc_res_resource *
bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
{
  rc_toolbar *ri;
  rc_res_resource *r;
  rc_uint_type i;

  ri = (rc_toolbar *) res_alloc (sizeof (rc_toolbar));
  ri->button_width = windres_get_32 (wrbfd, data, 4);
  ri->button_height = windres_get_32 (wrbfd, data + 4, 4);
  ri->nitems = windres_get_32 (wrbfd, data + 8, 4);
  ri->items = NULL;

  data += 12;
  length -= 12;
  for (i=0 ; i < ri->nitems; i++)
  {
    rc_toolbar_item *it;
    it = (rc_toolbar_item *) res_alloc (sizeof (rc_toolbar_item));
    it->id.named = 0;
    it->id.u.id = (int) windres_get_32 (wrbfd, data, 4);
    it->prev = it->next = NULL;
    data += 4;
    length -= 4;
    if(ri->items) {
      rc_toolbar_item *ii = ri->items;
      while (ii->next != NULL)
	ii = ii->next;
      it->prev = ii;
      ii->next = it;
    }
    else
      ri->items = it;
  }
  r = (rc_res_resource *) res_alloc (sizeof *r);
  r->type = RES_TYPE_TOOLBAR;
  r->u.toolbar = ri;
  return r;
}


/* Local functions used to convert resources to binary format.  */

static rc_uint_type resid_to_bin (windres_bfd *, rc_uint_type, rc_res_id);
static rc_uint_type unicode_to_bin (windres_bfd *, rc_uint_type, const unichar *);
static rc_uint_type res_to_bin_accelerator (windres_bfd *, rc_uint_type, const rc_accelerator *);
static rc_uint_type res_to_bin_cursor (windres_bfd *, rc_uint_type, const rc_cursor *);
static rc_uint_type res_to_bin_group_cursor (windres_bfd *, rc_uint_type, const rc_group_cursor *);
static rc_uint_type res_to_bin_dialog (windres_bfd *, rc_uint_type, const rc_dialog *);
static rc_uint_type res_to_bin_fontdir (windres_bfd *, rc_uint_type, const rc_fontdir *);
static rc_uint_type res_to_bin_group_icon (windres_bfd *, rc_uint_type, const rc_group_icon *);
static rc_uint_type res_to_bin_menu (windres_bfd *, rc_uint_type, const rc_menu *);
static rc_uint_type res_to_bin_menuitems (windres_bfd *, rc_uint_type, const rc_menuitem *);
static rc_uint_type res_to_bin_menuexitems (windres_bfd *, rc_uint_type, const rc_menuitem *);
static rc_uint_type res_to_bin_rcdata (windres_bfd *, rc_uint_type, const rc_rcdata_item *);
static rc_uint_type res_to_bin_stringtable (windres_bfd *, rc_uint_type, const rc_stringtable *);
static rc_uint_type string_to_unicode_bin (windres_bfd *, rc_uint_type, const char *);
static rc_uint_type res_to_bin_toolbar (windres_bfd *, rc_uint_type, rc_toolbar *tb);
static rc_uint_type res_to_bin_versioninfo (windres_bfd *, rc_uint_type, const rc_versioninfo *);
static rc_uint_type res_to_bin_generic (windres_bfd *, rc_uint_type, rc_uint_type,
					const bfd_byte *);

/* Convert a resource to binary.  */

rc_uint_type
res_to_bin (windres_bfd *wrbfd, rc_uint_type off, const rc_res_resource *res)
{
  switch (res->type)
    {
    case RES_TYPE_BITMAP:
    case RES_TYPE_FONT:
    case RES_TYPE_ICON:
    case RES_TYPE_MESSAGETABLE:
      return res_to_bin_generic (wrbfd, off, res->u.data.length, res->u.data.data);
    case RES_TYPE_ACCELERATOR:
      return res_to_bin_accelerator (wrbfd, off, res->u.acc);
    case RES_TYPE_CURSOR:
      return res_to_bin_cursor (wrbfd, off, res->u.cursor);
    case RES_TYPE_GROUP_CURSOR:
      return res_to_bin_group_cursor (wrbfd, off, res->u.group_cursor);
    case RES_TYPE_DIALOG:
      return res_to_bin_dialog (wrbfd, off, res->u.dialog);
    case RES_TYPE_FONTDIR:
      return res_to_bin_fontdir (wrbfd, off, res->u.fontdir);
    case RES_TYPE_GROUP_ICON:
      return res_to_bin_group_icon (wrbfd, off, res->u.group_icon);
    case RES_TYPE_MENU:
      return res_to_bin_menu (wrbfd, off, res->u.menu);
    case RES_TYPE_STRINGTABLE:
      return res_to_bin_stringtable (wrbfd, off, res->u.stringtable);
    case RES_TYPE_VERSIONINFO:
      return res_to_bin_versioninfo (wrbfd, off, res->u.versioninfo);
    case RES_TYPE_TOOLBAR:
      return res_to_bin_toolbar (wrbfd, off, res->u.toolbar);
    case RES_TYPE_USERDATA:
    case RES_TYPE_RCDATA:
    default:
      return res_to_bin_rcdata (wrbfd, off, res->u.rcdata);
    }
}

/* Convert a resource ID to binary.  This always returns exactly one
   bindata structure.  */

static rc_uint_type
resid_to_bin (windres_bfd *wrbfd, rc_uint_type off, rc_res_id id)
{
  if (! id.named)
    {
      if (wrbfd)
	{
	  struct bin_res_id bri;

	  windres_put_16 (wrbfd, bri.sig, 0xffff);
	  windres_put_16 (wrbfd, bri.id, id.u.id);
	  set_windres_bfd_content (wrbfd, &bri, off, BIN_RES_ID);
	}
      off += BIN_RES_ID;
    }
  else
    {
      rc_uint_type len = (id.u.n.name ? unichar_len (id.u.n.name) : 0);
      if (wrbfd)
	{
	  bfd_byte *d = (bfd_byte *) reswr_alloc ((len + 1) * sizeof (unichar));
	  rc_uint_type i;
	  for (i = 0; i < len; i++)
	    windres_put_16 (wrbfd, d + (i * sizeof (unichar)), id.u.n.name[i]);
	  windres_put_16 (wrbfd, d + (len * sizeof (unichar)), 0);
	  set_windres_bfd_content (wrbfd, d, off, (len + 1) * sizeof (unichar));
    }
      off += (rc_uint_type) ((len + 1) * sizeof (unichar));
    }
  return off;
}

/* Convert a null terminated unicode string to binary.  This always
   returns exactly one bindata structure.  */

static rc_uint_type
unicode_to_bin (windres_bfd *wrbfd, rc_uint_type off, const unichar *str)
{
  rc_uint_type len = 0;

  if (str != NULL)
    len = unichar_len (str);

  if (wrbfd)
    {
      bfd_byte *d;
      rc_uint_type i;
      d = (bfd_byte *) reswr_alloc ( (len + 1) * sizeof (unichar));
      for (i = 0; i < len; i++)
	windres_put_16 (wrbfd, d + (i * sizeof (unichar)), str[i]);
      windres_put_16 (wrbfd, d + (len * sizeof (unichar)), 0);
      set_windres_bfd_content (wrbfd, d, off, (len + 1) * sizeof (unichar));
    }
  off += (rc_uint_type) ((len + 1) * sizeof (unichar));

  return off;
}

/* Convert an accelerator resource to binary.  */

static rc_uint_type
res_to_bin_accelerator (windres_bfd *wrbfd, rc_uint_type off,
			const rc_accelerator *accelerators)
{
  const rc_accelerator *a;

  for (a = accelerators; a != NULL; a = a->next)
    {
      if (wrbfd)
	{
	  struct bin_accelerator ba;

	  windres_put_16 (wrbfd, ba.flags, a->flags | (a->next != NULL ? 0 : ACC_LAST));
	  windres_put_16 (wrbfd, ba.key, a->key);
	  windres_put_16 (wrbfd, ba.id, a->id);
	  windres_put_16 (wrbfd, ba.pad, 0);
	  set_windres_bfd_content (wrbfd, &ba, off, BIN_ACCELERATOR_SIZE);
    }
      off += BIN_ACCELERATOR_SIZE;
    }
  return off;
}

/* Convert a cursor resource to binary.  */

static rc_uint_type
res_to_bin_cursor (windres_bfd *wrbfd, rc_uint_type off, const rc_cursor *c)
{
  if (wrbfd)
    {
      struct bin_cursor bc;

      windres_put_16 (wrbfd, bc.xhotspot, c->xhotspot);
      windres_put_16 (wrbfd, bc.yhotspot, c->yhotspot);
      set_windres_bfd_content (wrbfd, &bc, off, BIN_CURSOR_SIZE);
      if (c->length)
	set_windres_bfd_content (wrbfd, c->data, off + BIN_CURSOR_SIZE, c->length);
    }
  off = (off + BIN_CURSOR_SIZE + (rc_uint_type) c->length);
  return off;
}

/* Convert a group cursor resource to binary.  */

static rc_uint_type
res_to_bin_group_cursor (windres_bfd *wrbfd, rc_uint_type off,
			 const rc_group_cursor *group_cursors)
{
  int c = 0;
  const rc_group_cursor *gc;
  struct bin_group_cursor bgc;
  struct bin_group_cursor_item bgci;
  rc_uint_type start = off;

  off += BIN_GROUP_CURSOR_SIZE;

  for (c = 0, gc = group_cursors; gc != NULL; gc = gc->next, c++)
    {
      if (wrbfd)
	{
	  windres_put_16 (wrbfd, bgci.width, gc->width);
	  windres_put_16 (wrbfd, bgci.height, gc->height);
	  windres_put_16 (wrbfd, bgci.planes, gc->planes);
	  windres_put_16 (wrbfd, bgci.bits, gc->bits);
	  windres_put_32 (wrbfd, bgci.bytes, gc->bytes);
	  windres_put_16 (wrbfd, bgci.index, gc->index);
	  set_windres_bfd_content (wrbfd, &bgci, off, BIN_GROUP_CURSOR_ITEM_SIZE);
    }

      off += BIN_GROUP_CURSOR_ITEM_SIZE;
    }
  if (wrbfd)
    {
      windres_put_16 (wrbfd, bgc.sig1, 0);
      windres_put_16 (wrbfd, bgc.sig2, 2);
      windres_put_16 (wrbfd, bgc.nitems, c);
      set_windres_bfd_content (wrbfd, &bgc, start, BIN_GROUP_CURSOR_SIZE);
    }
  return off;
}

/* Convert a dialog resource to binary.  */

static rc_uint_type
res_to_bin_dialog (windres_bfd *wrbfd, rc_uint_type off, const rc_dialog *dialog)
{
  rc_uint_type off_delta;
  rc_uint_type start, marker;
  int dialogex;
  int c;
  rc_dialog_control *dc;
  struct bin_dialogex bdx;
  struct bin_dialog bd;

  off_delta = off;
  start = off;
  dialogex = extended_dialog (dialog);

  if (wrbfd)
    {
  if (! dialogex)
    {
	  windres_put_32 (wrbfd, bd.style, dialog->style);
	  windres_put_32 (wrbfd, bd.exstyle, dialog->exstyle);
	  windres_put_16 (wrbfd, bd.x, dialog->x);
	  windres_put_16 (wrbfd, bd.y, dialog->y);
	  windres_put_16 (wrbfd, bd.width, dialog->width);
	  windres_put_16 (wrbfd, bd.height, dialog->height);
    }
  else
    {
	  windres_put_16 (wrbfd, bdx.sig1, 1);
	  windres_put_16 (wrbfd, bdx.sig2, 0xffff);
	  windres_put_32 (wrbfd, bdx.help, (dialog->ex ? dialog->ex->help : 0));
	  windres_put_32 (wrbfd, bdx.exstyle, dialog->exstyle);
	  windres_put_32 (wrbfd, bdx.style, dialog->style);
	  windres_put_16 (wrbfd, bdx.x, dialog->x);
	  windres_put_16 (wrbfd, bdx.y, dialog->y);
	  windres_put_16 (wrbfd, bdx.width, dialog->width);
	  windres_put_16 (wrbfd, bdx.height, dialog->height);
	}
    }

  off += (dialogex != 0 ? BIN_DIALOGEX_SIZE : BIN_DIALOG_SIZE);

  off = resid_to_bin (wrbfd, off, dialog->menu);
  off = resid_to_bin (wrbfd, off, dialog->class);
  off = unicode_to_bin (wrbfd, off, dialog->caption);

  if ((dialog->style & DS_SETFONT) != 0)
    {
      if (wrbfd)
	{
	  if (! dialogex)
	    {
	      struct bin_dialogfont bdf;
	      windres_put_16 (wrbfd, bdf.pointsize, dialog->pointsize);
	      set_windres_bfd_content (wrbfd, &bdf, off, BIN_DIALOGFONT_SIZE);
	    }
	  else
	    {
	      struct bin_dialogexfont bdxf;
	      windres_put_16 (wrbfd, bdxf.pointsize, dialog->pointsize);
	      windres_put_16 (wrbfd, bdxf.weight, (dialog->ex == NULL ? 0 : dialog->ex->weight));
	      windres_put_8 (wrbfd, bdxf.italic, (dialog->ex == NULL ? 0 : dialog->ex->italic));
	      windres_put_8 (wrbfd, bdxf.charset, (dialog->ex == NULL ? 1 : dialog->ex->charset));
	      set_windres_bfd_content (wrbfd, &bdxf, off, BIN_DIALOGEXFONT_SIZE);
	    }
	}
      off += (dialogex ? BIN_DIALOGEXFONT_SIZE : BIN_DIALOGFONT_SIZE);
      off = unicode_to_bin (wrbfd, off, dialog->font);
    }
  for (c = 0, dc = dialog->controls; dc != NULL; dc = dc->next, c++)
    {
      bfd_byte dc_rclen[2];

      off += (4 - ((off - off_delta) & 3)) & 3;
      if (wrbfd)
	{
      if (! dialogex)
	{
	      struct bin_dialog_control bdc;

	      windres_put_32 (wrbfd, bdc.style, dc->style);
	      windres_put_32 (wrbfd, bdc.exstyle, dc->exstyle);
	      windres_put_16 (wrbfd, bdc.x, dc->x);
	      windres_put_16 (wrbfd, bdc.y, dc->y);
	      windres_put_16 (wrbfd, bdc.width, dc->width);
	      windres_put_16 (wrbfd, bdc.height, dc->height);
	      windres_put_16 (wrbfd, bdc.id, dc->id);
	      set_windres_bfd_content (wrbfd, &bdc, off, BIN_DIALOG_CONTROL_SIZE);
	}
      else
	{
	      struct bin_dialogex_control bdc;

	      windres_put_32 (wrbfd, bdc.help, dc->help);
	      windres_put_32 (wrbfd, bdc.exstyle, dc->exstyle);
	      windres_put_32 (wrbfd, bdc.style, dc->style);
	      windres_put_16 (wrbfd, bdc.x, dc->x);
	      windres_put_16 (wrbfd, bdc.y, dc->y);
	      windres_put_16 (wrbfd, bdc.width, dc->width);
	      windres_put_16 (wrbfd, bdc.height, dc->height);
	      windres_put_32 (wrbfd, bdc.id, dc->id);
	      set_windres_bfd_content (wrbfd, &bdc, off, BIN_DIALOGEX_CONTROL_SIZE);
	    }
	}
      off += (dialogex != 0 ? BIN_DIALOGEX_CONTROL_SIZE : BIN_DIALOG_CONTROL_SIZE);

      off = resid_to_bin (wrbfd, off, dc->class);
      off = resid_to_bin (wrbfd, off, dc->text);

      marker = off; /* Save two bytes for size of optional data.  */
      off += 2;

      if (dc->data == NULL)
        {
	  if (wrbfd)
	    windres_put_16 (wrbfd, dc_rclen, 0);
	}
      else
	{
	  rc_uint_type saved_off = off;
	  rc_uint_type old_off;

	  old_off = off;
	  off = res_to_bin_rcdata (wrbfd, off, dc->data);
	  if ((off - old_off) == 0)
	    old_off = off = saved_off;
	  if (wrbfd)
	    windres_put_16 (wrbfd, dc_rclen, off - old_off);
	}
      if (wrbfd)
	set_windres_bfd_content (wrbfd, dc_rclen, marker, 2);
    }

  if (wrbfd)
    {
      windres_put_16 (wrbfd, (dialogex != 0 ? bdx.off : bd.off), c);
      if (! dialogex)
	set_windres_bfd_content (wrbfd, &bd, start, BIN_DIALOG_SIZE);
      else
	set_windres_bfd_content (wrbfd, &bdx, start, BIN_DIALOGEX_SIZE);
    }

  return off;
}

/* Convert a fontdir resource to binary.  */
static rc_uint_type
res_to_bin_fontdir (windres_bfd *wrbfd, rc_uint_type off, const rc_fontdir *fontdirs)
{
  rc_uint_type start;
  int c;
  const rc_fontdir *fd;

  start = off;
  off += 2;

  for (c = 0, fd = fontdirs; fd != NULL; fd = fd->next, c++)
    {
      if (wrbfd)
	{
	  bfd_byte d[2];
	  windres_put_16 (wrbfd, d, fd->index);
	  set_windres_bfd_content (wrbfd, d, off, 2);
	  if (fd->length)
	    set_windres_bfd_content (wrbfd, fd->data, off + 2, fd->length);
	}
      off += (rc_uint_type) fd->length + 2;
    }

  if (wrbfd)
    {
      bfd_byte d[2];
      windres_put_16 (wrbfd, d, c);
      set_windres_bfd_content (wrbfd, d, start, 2);
    }
  return off;
}

/* Convert a group icon resource to binary.  */

static rc_uint_type
res_to_bin_group_icon (windres_bfd *wrbfd, rc_uint_type off, const rc_group_icon *group_icons)
{
  rc_uint_type start;
  struct bin_group_icon bgi;
  int c;
  const rc_group_icon *gi;

  start = off;
  off += BIN_GROUP_ICON_SIZE;

  for (c = 0, gi = group_icons; gi != NULL; gi = gi->next, c++)
    {
      struct bin_group_icon_item bgii;

      if (wrbfd)
	{
	  windres_put_8 (wrbfd, bgii.width, gi->width);
	  windres_put_8 (wrbfd, bgii.height, gi->height);
	  windres_put_8 (wrbfd, bgii.colors, gi->colors);
	  windres_put_8 (wrbfd, bgii.pad, 0);
	  windres_put_16 (wrbfd, bgii.planes, gi->planes);
	  windres_put_16 (wrbfd, bgii.bits, gi->bits);
	  windres_put_32 (wrbfd, bgii.bytes, gi->bytes);
	  windres_put_16 (wrbfd, bgii.index, gi->index);
	  set_windres_bfd_content (wrbfd, &bgii, off, BIN_GROUP_ICON_ITEM_SIZE);
	}
      off += BIN_GROUP_ICON_ITEM_SIZE;
    }

  if (wrbfd)
    {
      windres_put_16 (wrbfd, bgi.sig1, 0);
      windres_put_16 (wrbfd, bgi.sig2, 1);
      windres_put_16 (wrbfd, bgi.count, c);
      set_windres_bfd_content (wrbfd, &bgi, start, BIN_GROUP_ICON_SIZE);
    }
  return off;
}

/* Convert a menu resource to binary.  */

static rc_uint_type
res_to_bin_menu (windres_bfd *wrbfd, rc_uint_type off, const rc_menu *menu)
{
  int menuex;

  menuex = extended_menu (menu);

  if (wrbfd)
    {
  if (! menuex)
    {
	  struct bin_menu bm;
	  windres_put_16 (wrbfd, bm.sig1, 0);
	  windres_put_16 (wrbfd, bm.sig2, 0);
	  set_windres_bfd_content (wrbfd, &bm, off, BIN_MENU_SIZE);
    }
  else
    {
	  struct bin_menuex bm;
	  windres_put_16 (wrbfd, bm.sig1, 1);
	  windres_put_16 (wrbfd, bm.sig2, 4);
	  windres_put_32 (wrbfd, bm.help, menu->help);
	  set_windres_bfd_content (wrbfd, &bm, off, BIN_MENUEX_SIZE);
    }
    }
  off += (menuex != 0 ? BIN_MENUEX_SIZE : BIN_MENU_SIZE);
  if (! menuex)
    {
      off = res_to_bin_menuitems (wrbfd, off, menu->items);
    }
  else
    {
      off = res_to_bin_menuexitems (wrbfd, off, menu->items);
    }
  return off;
}

/* Convert menu items to binary.  */

static rc_uint_type
res_to_bin_menuitems (windres_bfd *wrbfd, rc_uint_type off, const rc_menuitem *items)
{
  const rc_menuitem *mi;

  for (mi = items; mi != NULL; mi = mi->next)
    {
      struct bin_menuitem bmi;
      int flags;

      flags = mi->type;
      if (mi->next == NULL)
	flags |= MENUITEM_ENDMENU;
      if (mi->popup != NULL)
	flags |= MENUITEM_POPUP;

      if (wrbfd)
	{
	  windres_put_16 (wrbfd, bmi.flags, flags);
      if (mi->popup == NULL)
	    windres_put_16 (wrbfd, bmi.id, mi->id);
	  set_windres_bfd_content (wrbfd, &bmi, off,
				   mi->popup == NULL ? BIN_MENUITEM_SIZE
				   		     : BIN_MENUITEM_POPUP_SIZE);
	}
      off += (mi->popup == NULL ? BIN_MENUITEM_SIZE : BIN_MENUITEM_POPUP_SIZE);

      off = unicode_to_bin (wrbfd, off, mi->text);

      if (mi->popup != NULL)
	{
	  off = res_to_bin_menuitems (wrbfd, off, mi->popup);
	}
    }
  return off;
}

/* Convert menuex items to binary.  */

static rc_uint_type
res_to_bin_menuexitems (windres_bfd *wrbfd, rc_uint_type off, const rc_menuitem *items)
{
  rc_uint_type off_delta = off;
  const rc_menuitem *mi;

  for (mi = items; mi != NULL; mi = mi->next)
    {
      struct bin_menuitemex bmi;
      int flags;

      off += (4 - ((off - off_delta) & 3)) & 3;

      flags = 0;
      if (mi->next == NULL)
	flags |= 0x80;
      if (mi->popup != NULL)
	flags |= 1;

      if (wrbfd)
	{
	  windres_put_32 (wrbfd, bmi.type, mi->type);
	  windres_put_32 (wrbfd, bmi.state, mi->state);
	  windres_put_32 (wrbfd, bmi.id, mi->id);
	  windres_put_16 (wrbfd, bmi.flags, flags);
	  set_windres_bfd_content (wrbfd, &bmi, off, BIN_MENUITEMEX_SIZE);
	}
      off += BIN_MENUITEMEX_SIZE;

      off = unicode_to_bin (wrbfd, off, mi->text);

      if (mi->popup != NULL)
	{
	  bfd_byte help[4];

	  off += (4 - ((off - off_delta) & 3)) & 3;

	  if (wrbfd)
	    {
	      windres_put_32 (wrbfd, help, mi->help);
	      set_windres_bfd_content (wrbfd, help, off, 4);
	    }
	  off += 4;
	  off = res_to_bin_menuexitems (wrbfd, off, mi->popup);
	}
    }
  return off;
}

/* Convert an rcdata resource to binary.  This is also used to convert
   other information which happens to be stored in rc_rcdata_item lists
   to binary.  */

static rc_uint_type
res_to_bin_rcdata (windres_bfd *wrbfd, rc_uint_type off, const rc_rcdata_item *items)
{
  const rc_rcdata_item *ri;

  for (ri = items; ri != NULL; ri = ri->next)
    {
      rc_uint_type len;
      switch (ri->type)
	{
	default:
	  abort ();
	case RCDATA_WORD:
	  len = 2;
	  break;
	case RCDATA_DWORD:
	  len = 4;
	  break;
	case RCDATA_STRING:
	  len = ri->u.string.length;
	  break;
	case RCDATA_WSTRING:
	  len = ri->u.wstring.length * sizeof (unichar);
	  break;
	case RCDATA_BUFFER:
	  len = ri->u.buffer.length;
	  break;
	}
      if (wrbfd)
	{
	  bfd_byte h[4];
	  bfd_byte *hp = &h[0];
	  switch (ri->type)
	    {
	    case RCDATA_WORD:
	      windres_put_16 (wrbfd, hp, ri->u.word);
	      break;
	    case RCDATA_DWORD:
	      windres_put_32 (wrbfd, hp, ri->u.dword);
	      break;
	    case RCDATA_STRING:
	      hp = (bfd_byte *) ri->u.string.s;
	  break;
	case RCDATA_WSTRING:
	  {
		rc_uint_type i;

		hp = (bfd_byte *) reswr_alloc (len);
	    for (i = 0; i < ri->u.wstring.length; i++)
		  windres_put_16 (wrbfd, hp + i * sizeof (unichar), ri->u.wstring.w[i]);
	  }
	      break;
	case RCDATA_BUFFER:
	      hp = (bfd_byte *) ri->u.buffer.data;
	  break;
	}
	  set_windres_bfd_content (wrbfd, hp, off, len);
    }
      off += len;
    }
  return off;
}

/* Convert a stringtable resource to binary.  */

static rc_uint_type
res_to_bin_stringtable (windres_bfd *wrbfd, rc_uint_type off,
			const rc_stringtable *st)
{
  int i;

  for (i = 0; i < 16; i++)
    {
      rc_uint_type slen, length;
      unichar *s;

      slen = (rc_uint_type) st->strings[i].length;
      if (slen == 0xffffffff) slen = 0;
      s = st->strings[i].string;

      length = 2 + slen * 2;
      if (wrbfd)
	{
	  bfd_byte *hp;
	  rc_uint_type j;

	  hp = (bfd_byte *) reswr_alloc (length);
	  windres_put_16 (wrbfd, hp, slen);

      for (j = 0; j < slen; j++)
	    windres_put_16 (wrbfd, hp + 2 + j * 2, s[j]);
	  set_windres_bfd_content (wrbfd, hp, off, length);
    }
      off += length;
    }
  return off;
}

/* Convert an ASCII string to a unicode binary string.  This always
   returns exactly one bindata structure.  */

static rc_uint_type
string_to_unicode_bin (windres_bfd *wrbfd, rc_uint_type off, const char *s)
{
  rc_uint_type len;

  len = (rc_uint_type) strlen (s);

  if (wrbfd)
    {
      rc_uint_type i;
      bfd_byte *hp;

      hp = (bfd_byte *) reswr_alloc ((len + 1) * sizeof (unichar));

      for (i = 0; i < len; i++)
	windres_put_16 (wrbfd, hp + i * 2, s[i]);
      windres_put_16 (wrbfd, hp + i * 2, 0);
      set_windres_bfd_content (wrbfd, hp, off, (len + 1) * sizeof (unichar));
    }
  off += (rc_uint_type) ((len + 1) * sizeof (unichar));
  return off;
}

static rc_uint_type
res_to_bin_toolbar (windres_bfd *wrbfd, rc_uint_type off, rc_toolbar *tb)
{
  if (wrbfd)
    {
      struct bin_toolbar bt;
      windres_put_32 (wrbfd, bt.button_width, tb->button_width);
      windres_put_32 (wrbfd, bt.button_height, tb->button_height);
      windres_put_32 (wrbfd, bt.nitems, tb->nitems);
      set_windres_bfd_content (wrbfd, &bt, off, BIN_TOOLBAR_SIZE);
      if (tb->nitems > 0)
	{
	  rc_toolbar_item *it;
	  bfd_byte *ids;
	  rc_uint_type i = 0;

	  ids = (bfd_byte *) reswr_alloc (tb->nitems * 4);
	  it=tb->items;
	  while(it != NULL)
	    {
	      windres_put_32 (wrbfd, ids + i, it->id.u.id);
	      i += 4;
	      it = it->next;
	    }
	  set_windres_bfd_content (wrbfd, ids, off + BIN_TOOLBAR_SIZE, i);
 	}
    }
  off += BIN_TOOLBAR_SIZE + tb->nitems * 4;

  return off;
}

/* Convert a versioninfo resource to binary.  */

static rc_uint_type
res_to_bin_versioninfo (windres_bfd *wrbfd, rc_uint_type off,
			const rc_versioninfo *versioninfo)
{
  rc_uint_type off_delta = off;
  rc_uint_type start;
  struct bin_versioninfo bvi;
  rc_ver_info *vi;

  start = off;
  off += BIN_VERSIONINFO_SIZE;
  off = string_to_unicode_bin (wrbfd, off, "VS_VERSION_INFO");
  off += (4 - ((off - off_delta) & 3)) & 3;

  if (versioninfo->fixed != NULL)
    {
      if (wrbfd)
	{
	  struct bin_fixed_versioninfo bfv;
	  const rc_fixed_versioninfo *fi;

      fi = versioninfo->fixed;
	  windres_put_32 (wrbfd, bfv.sig1, 0xfeef04bd);
	  windres_put_32 (wrbfd, bfv.sig2, 0x10000);
	  windres_put_32 (wrbfd, bfv.file_version, fi->file_version_ms);
	  windres_put_32 (wrbfd, bfv.file_version_ls, fi->file_version_ls);
	  windres_put_32 (wrbfd, bfv.product_version_ms, fi->product_version_ms);
	  windres_put_32 (wrbfd, bfv.product_version_ls, fi->product_version_ls);
	  windres_put_32 (wrbfd, bfv.file_flags_mask, fi->file_flags_mask);
	  windres_put_32 (wrbfd, bfv.file_flags, fi->file_flags);
	  windres_put_32 (wrbfd, bfv.file_os, fi->file_os);
	  windres_put_32 (wrbfd, bfv.file_type, fi->file_type);
	  windres_put_32 (wrbfd, bfv.file_subtype, fi->file_subtype);
	  windres_put_32 (wrbfd, bfv.file_date_ms, fi->file_date_ms);
	  windres_put_32 (wrbfd, bfv.file_date_ls, fi->file_date_ls);
	  set_windres_bfd_content (wrbfd, &bfv, off, BIN_FIXED_VERSIONINFO_SIZE);
	}
      off += BIN_FIXED_VERSIONINFO_SIZE;
    }

  for (vi = versioninfo->var; vi != NULL; vi = vi->next)
    {
      struct bin_ver_info bv;
      rc_uint_type bv_off;

      off += (4 - ((off - off_delta) & 3)) & 3;

      bv_off = off;

      off += BIN_VER_INFO_SIZE;

      switch (vi->type)
	{
	default:
	  abort ();
	case VERINFO_STRING:
	  {
	    const rc_ver_stringtable *vst;

	    off = string_to_unicode_bin (wrbfd, off, "StringFileInfo");

	    if (!vi->u.string.stringtables)
	      off += (4 - ((off - off_delta) & 3)) & 3;

	    for (vst = vi->u.string.stringtables; vst != NULL; vst = vst->next)
	      {
		struct bin_ver_info bvst;
		rc_uint_type vst_off;
		const rc_ver_stringinfo *vs;

		off += (4 - ((off - off_delta) & 3)) & 3;

		vst_off = off;
		off += BIN_VER_INFO_SIZE;

		off = unicode_to_bin (wrbfd, off, vst->language);

		for (vs = vst->strings; vs != NULL; vs = vs->next)
		  {
		    struct bin_ver_info bvs;
		    rc_uint_type vs_off, str_off;

		    off += (4 - ((off - off_delta) & 3)) & 3;

		    vs_off = off;
		    off += BIN_VER_INFO_SIZE;

		    off = unicode_to_bin (wrbfd, off, vs->key);

		    off += (4 - ((off - off_delta) & 3)) & 3;

		    str_off = off;
		    off = unicode_to_bin (wrbfd, off, vs->value);

		    if (wrbfd)
		      {
			windres_put_16 (wrbfd, bvs.size, off - vs_off);
			windres_put_16 (wrbfd, bvs.sig1, (off - str_off) / 2);
			windres_put_16 (wrbfd, bvs.sig2, 1);
			set_windres_bfd_content (wrbfd, &bvs, vs_off,
						 BIN_VER_INFO_SIZE);
		      }
		  }

		if (wrbfd)
		  {
		    windres_put_16 (wrbfd, bvst.size, off - vst_off);
		    windres_put_16 (wrbfd, bvst.sig1, 0);
		    windres_put_16 (wrbfd, bvst.sig2, 1);
		    set_windres_bfd_content (wrbfd, &bvst, vst_off,
					     BIN_VER_INFO_SIZE);
		  }
	      }
	    break;
	  }

	case VERINFO_VAR:
	  {
	    rc_uint_type vvd_off, vvvd_off;
	    struct bin_ver_info bvvd;
	    const rc_ver_varinfo *vv;

	    off = string_to_unicode_bin (wrbfd, off, "VarFileInfo");

	    off += (4 - ((off - off_delta) & 3)) & 3;

	    vvd_off = off;
	    off += BIN_VER_INFO_SIZE;

	    off = unicode_to_bin (wrbfd, off, vi->u.var.key);

	    off += (4 - ((off - off_delta) & 3)) & 3;

	    vvvd_off = off;

	    for (vv = vi->u.var.var; vv != NULL; vv = vv->next)
	      {
		if (wrbfd)
		  {
		    bfd_byte vvsd[4];

		    windres_put_16 (wrbfd, &vvsd[0], vv->language);
		    windres_put_16 (wrbfd, &vvsd[2], vv->charset);
		    set_windres_bfd_content (wrbfd, vvsd, off, 4);
		  }
		off += 4;
	      }
	    if (wrbfd)
	    {
		windres_put_16 (wrbfd, bvvd.size, off - vvd_off);
		windres_put_16 (wrbfd, bvvd.sig1, off - vvvd_off);
		windres_put_16 (wrbfd, bvvd.sig2, 0);
		set_windres_bfd_content (wrbfd, &bvvd, vvd_off,
					 BIN_VER_INFO_SIZE);
	    }

	    break;
	  }
	}

      if (wrbfd)
	{
	  windres_put_16 (wrbfd, bv.size, off - bv_off);
	  windres_put_16 (wrbfd, bv.sig1, 0);
	  windres_put_16 (wrbfd, bv.sig2, 1);
	  set_windres_bfd_content (wrbfd, &bv, bv_off,
	  			   BIN_VER_INFO_SIZE);
	}
    }

  if (wrbfd)
    {
      windres_put_16 (wrbfd, bvi.size, off - start);
      windres_put_16 (wrbfd, bvi.fixed_size,
		      versioninfo->fixed == NULL ? 0
		      				 : BIN_FIXED_VERSIONINFO_SIZE);
      windres_put_16 (wrbfd, bvi.sig2, 0);
      set_windres_bfd_content (wrbfd, &bvi, start, BIN_VER_INFO_SIZE);
    }
  return off;
}

/* Convert a generic resource to binary.  */

static rc_uint_type
res_to_bin_generic (windres_bfd *wrbfd, rc_uint_type off, rc_uint_type length,
		    const bfd_byte *data)
{
  if (wrbfd && length != 0)
    set_windres_bfd_content (wrbfd, data, off, length);
  return off + (rc_uint_type) length;
}
