summaryrefslogtreecommitdiff
path: root/binutils/resres.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils/resres.c')
-rw-r--r--binutils/resres.c544
1 files changed, 310 insertions, 234 deletions
diff --git a/binutils/resres.c b/binutils/resres.c
index 1489d5eeda49..f345da3e5de6 100644
--- a/binutils/resres.c
+++ b/binutils/resres.c
@@ -1,6 +1,8 @@
/* resres.c: read_res_file and write_res_file implementation for windres.
- Copyright 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
+ Copyright 1998, 1999, 2001, 2002, 2007
+ Free Software Foundation, Inc.
Written by Anders Norlander <anorland@hem2.passagen.se>.
+ Rewritten by Kai Tietz, Onevision.
This file is part of GNU Binutils.
@@ -23,6 +25,7 @@
It assumes that it can use fread and fwrite to read and write
integers. It does no swapping. */
+#include "sysdep.h"
#include "bfd.h"
#include "bucomm.h"
#include "libiberty.h"
@@ -31,154 +34,179 @@
#include <assert.h>
#include <time.h>
-struct res_hdr
- {
- unsigned long data_size;
- unsigned long header_size;
- };
-
-static void write_res_directory
- PARAMS ((const struct res_directory *,
- const struct res_id *, const struct res_id *,
- int *, int));
-static void write_res_resource
- PARAMS ((const struct res_id *, const struct res_id *,
- const struct res_resource *, int *));
-static void write_res_bin
- PARAMS ((const struct res_resource *, const struct res_id *,
- const struct res_id *, const struct res_res_info *));
-
-static void write_res_id PARAMS ((const struct res_id *));
-static void write_res_info PARAMS ((const struct res_res_info *));
-static void write_res_data PARAMS ((const void *, size_t, int));
-static void write_res_header
- PARAMS ((unsigned long, const struct res_id *, const struct res_id *,
- const struct res_res_info *));
-
-static int read_resource_entry PARAMS ((void));
-static void read_res_data PARAMS ((void *, size_t, int));
-static void read_res_id PARAMS ((struct res_id *));
-static unichar *read_unistring PARAMS ((int *));
-static void skip_null_resource PARAMS ((void));
-
-static unsigned long get_id_size PARAMS ((const struct res_id *));
-static void res_align_file PARAMS ((void));
+static rc_uint_type write_res_directory (windres_bfd *, rc_uint_type,
+ const rc_res_directory *, const rc_res_id *,
+ const rc_res_id *, rc_uint_type *, int);
+static rc_uint_type write_res_resource (windres_bfd *, rc_uint_type,const rc_res_id *,
+ const rc_res_id *, const rc_res_resource *,
+ rc_uint_type *);
+static rc_uint_type write_res_bin (windres_bfd *, rc_uint_type, const rc_res_resource *,
+ const rc_res_id *, const rc_res_id *,
+ const rc_res_res_info *);
-static void
- res_add_resource
- PARAMS ((struct res_resource *, const struct res_id *,
- const struct res_id *, int, int));
+static rc_uint_type write_res_id (windres_bfd *, rc_uint_type, const rc_res_id *);
+static rc_uint_type write_res_info (windres_bfd *, rc_uint_type, const rc_res_res_info *);
+static rc_uint_type write_res_data_hdr (windres_bfd *, rc_uint_type, res_hdr *);
-void
- res_append_resource
- PARAMS ((struct res_directory **, struct res_resource *,
- int, const struct res_id *, int));
+static rc_uint_type write_res_header (windres_bfd *, rc_uint_type, rc_uint_type,
+ const rc_res_id *, const rc_res_id *,
+ const rc_res_res_info *);
+
+static int read_resource_entry (windres_bfd *, rc_uint_type *, rc_uint_type);
+static void read_res_data (windres_bfd *, rc_uint_type *, rc_uint_type, void *,
+ rc_uint_type);
+static void read_res_data_hdr (windres_bfd *, rc_uint_type *, rc_uint_type, res_hdr *);
+static void read_res_id (windres_bfd *, rc_uint_type *, rc_uint_type, rc_res_id *);
+static unichar *read_unistring (windres_bfd *, rc_uint_type *, rc_uint_type, rc_uint_type *);
+static void skip_null_resource (windres_bfd *, rc_uint_type *, rc_uint_type);
+static int probe_binary (windres_bfd *wrbfd, rc_uint_type);
+
+static unsigned long get_id_size (const rc_res_id *);
-static struct res_directory *resources = NULL;
+static void res_add_resource (rc_res_resource *, const rc_res_id *,
+ const rc_res_id *, rc_uint_type, int);
+
+static void res_append_resource (rc_res_directory **, rc_res_resource *,
+ int, const rc_res_id *, int);
+
+static rc_res_directory *resources = NULL;
-static FILE *fres;
static const char *filename;
extern char *program_name;
/* Read resource file */
-struct res_directory *
-read_res_file (fn)
- const char *fn;
+rc_res_directory *
+read_res_file (const char *fn)
{
+ rc_uint_type off, flen;
+ windres_bfd wrbfd;
+ bfd *abfd;
+ asection *sec;
filename = fn;
- fres = fopen (filename, "rb");
- if (fres == NULL)
- fatal ("can't open `%s' for output: %s", filename, strerror (errno));
- skip_null_resource ();
+ flen = (rc_uint_type) get_file_size (filename);
+ if (! flen)
+ fatal ("can't open '%s' for input.", filename);
+ abfd = windres_open_as_binary (filename, 1);
+ sec = bfd_get_section_by_name (abfd, ".data");
+ if (sec == NULL)
+ bfd_fatal ("bfd_get_section_by_name");
+ set_windres_bfd (&wrbfd, abfd, sec,
+ (target_is_bigendian ? WR_KIND_BFD_BIN_B
+ : WR_KIND_BFD_BIN_L));
+ off = 0;
+
+ if (! probe_binary (&wrbfd, flen))
+ set_windres_bfd_endianess (&wrbfd, ! target_is_bigendian);
- while (read_resource_entry ())
+ skip_null_resource (&wrbfd, &off, flen);
+
+ while (read_resource_entry (&wrbfd, &off, flen))
;
- fclose (fres);
+ bfd_close (abfd);
return resources;
}
/* Write resource file */
void
-write_res_file (fn, resdir)
- const char *fn;
- const struct res_directory *resdir;
+write_res_file (const char *fn,const rc_res_directory *resdir)
{
- int language;
- static const unsigned char sign[] =
+ asection *sec;
+ rc_uint_type language;
+ bfd *abfd;
+ windres_bfd wrbfd;
+ unsigned long sec_length = 0,sec_length_wrote;
+ static const bfd_byte sign[] =
{0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- long fpos;
filename = fn;
- fres = fopen (filename, "wb");
- if (fres == NULL)
- fatal ("can't open `%s' for output: %s", filename, strerror (errno));
-
- /* Write 32 bit resource signature */
- write_res_data (sign, sizeof (sign), 1);
-
- /* write resources */
+ abfd = windres_open_as_binary (filename, 0);
+ sec = bfd_make_section (abfd, ".data");
+ if (sec == NULL)
+ bfd_fatal ("bfd_make_section");
+ if (! bfd_set_section_flags (abfd, sec,
+ (SEC_HAS_CONTENTS | SEC_ALLOC
+ | SEC_LOAD | SEC_DATA)))
+ bfd_fatal ("bfd_set_section_flags");
+ /* Requiring this is probably a bug in BFD. */
+ sec->output_section = sec;
+
+ set_windres_bfd (&wrbfd, abfd, sec,
+ (target_is_bigendian ? WR_KIND_BFD_BIN_B
+ : WR_KIND_BFD_BIN_L));
language = -1;
- write_res_directory (resdir, (const struct res_id *) NULL,
- (const struct res_id *) NULL, &language, 1);
-
- /* end file on DWORD boundary */
- fpos = ftell (fres);
- if (fpos % 4)
- write_res_data (sign, fpos % 4, 1);
-
- fclose (fres);
+ sec_length = write_res_directory ((windres_bfd *) NULL, 0x20UL, resdir,
+ (const rc_res_id *) NULL,
+ (const rc_res_id *) NULL, &language, 1);
+ if (! bfd_set_section_size (abfd, sec, (sec_length + 3) & ~3))
+ bfd_fatal ("bfd_set_section_size");
+ if ((sec_length & 3) != 0)
+ set_windres_bfd_content (&wrbfd, sign, sec_length, 4-(sec_length & 3));
+ set_windres_bfd_content (&wrbfd, sign, 0, sizeof (sign));
+ language = -1;
+ sec_length_wrote = write_res_directory (&wrbfd, 0x20UL, resdir,
+ (const rc_res_id *) NULL,
+ (const rc_res_id *) NULL,
+ &language, 1);
+ if (sec_length != sec_length_wrote)
+ fatal ("res write failed with different sizes (%lu/%lu).", (long) sec_length,
+ (long) sec_length_wrote);
+
+ bfd_close (abfd);
+ return;
}
/* Read a resource entry, returns 0 when all resources are read */
static int
-read_resource_entry (void)
+read_resource_entry (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax)
{
- struct res_id type;
- struct res_id name;
- struct res_res_info resinfo;
- struct res_hdr reshdr;
- long version;
+ rc_res_id type;
+ rc_res_id name;
+ rc_res_res_info resinfo;
+ res_hdr reshdr;
void *buff;
- struct res_resource *r;
+ rc_res_resource *r;
+ struct bin_res_info l;
- res_align_file ();
+ off[0] = (off[0] + 3) & ~3;
/* Read header */
- if (fread (&reshdr, sizeof (reshdr), 1, fres) != 1)
+ if ((off[0] + 8) > omax)
return 0;
+ read_res_data_hdr (wrbfd, off, omax, &reshdr);
/* read resource type */
- read_res_id (&type);
+ read_res_id (wrbfd, off, omax, &type);
/* read resource id */
- read_res_id (&name);
+ read_res_id (wrbfd, off, omax, &name);
- res_align_file ();
+ off[0] = (off[0] + 3) & ~3;
/* Read additional resource header */
- read_res_data (&resinfo.version, sizeof (resinfo.version), 1);
- read_res_data (&resinfo.memflags, sizeof (resinfo.memflags), 1);
- read_res_data (&resinfo.language, sizeof (resinfo.language), 1);
- read_res_data (&version, sizeof (version), 1);
- read_res_data (&resinfo.characteristics, sizeof (resinfo.characteristics), 1);
+ read_res_data (wrbfd, off, omax, &l, BIN_RES_INFO_SIZE);
+ resinfo.version = windres_get_32 (wrbfd, l.version, 4);
+ resinfo.memflags = windres_get_16 (wrbfd, l.memflags, 2);
+ resinfo.language = windres_get_16 (wrbfd, l.language, 2);
+ /* resinfo.version2 = windres_get_32 (wrbfd, l.version2, 4); */
+ resinfo.characteristics = windres_get_32 (wrbfd, l.characteristics, 4);
- res_align_file ();
+ off[0] = (off[0] + 3) & ~3;
/* Allocate buffer for data */
buff = res_alloc (reshdr.data_size);
/* Read data */
- read_res_data (buff, reshdr.data_size, 1);
+ read_res_data (wrbfd, off, omax, buff, reshdr.data_size);
/* Convert binary data to resource */
- r = bin_to_res (type, buff, reshdr.data_size, 0);
+ r = bin_to_res (wrbfd, type, buff, reshdr.data_size);
r->res_info = resinfo;
/* Add resource to resource directory */
res_add_resource (r, &type, &name, resinfo.language, 0);
@@ -187,15 +215,12 @@ read_resource_entry (void)
}
/* write resource directory to binary resource file */
-static void
-write_res_directory (rd, type, name, language, level)
- const struct res_directory *rd;
- const struct res_id *type;
- const struct res_id *name;
- int *language;
- int level;
+static rc_uint_type
+write_res_directory (windres_bfd *wrbfd, rc_uint_type off, const rc_res_directory *rd,
+ const rc_res_id *type, const rc_res_id *name, rc_uint_type *language,
+ int level)
{
- const struct res_entry *re;
+ const rc_res_entry *re;
for (re = rd->entries; re != NULL; re = re->next)
{
@@ -218,7 +243,7 @@ write_res_directory (rd, type, name, language, level)
case 3:
/* If we're at level 3, then this key represents a language.
Use it to update the current language. */
- if (!re->id.named
+ if (! re->id.named
&& re->id.u.id != (unsigned long) *language
&& (re->id.u.id & 0xffff) == re->id.u.id)
{
@@ -231,7 +256,8 @@ write_res_directory (rd, type, name, language, level)
}
if (re->subdir)
- write_res_directory (re->u.dir, type, name, language, level + 1);
+ off = write_res_directory (wrbfd, off, re->u.dir, type, name, language,
+ level + 1);
else
{
if (level == 3)
@@ -241,25 +267,25 @@ write_res_directory (rd, type, name, language, level)
2, and represents the name to use. We probably just
set LANGUAGE, and it will probably match what the
resource itself records if anything. */
- write_res_resource (type, name, re->u.res, language);
+ off = write_res_resource (wrbfd, off, type, name, re->u.res,
+ language);
}
else
{
fprintf (stderr, "// Resource at unexpected level %d\n", level);
- write_res_resource (type, (struct res_id *) NULL, re->u.res,
- language);
+ off = write_res_resource (wrbfd, off, type, (rc_res_id *) NULL,
+ re->u.res, language);
}
}
}
+ return off;
}
-static void
-write_res_resource (type, name, res, language)
- const struct res_id *type;
- const struct res_id *name;
- const struct res_resource *res;
- int *language ATTRIBUTE_UNUSED;
+static rc_uint_type
+write_res_resource (windres_bfd *wrbfd, rc_uint_type off, const rc_res_id *type,
+ const rc_res_id *name, const rc_res_resource *res,
+ rc_uint_type *language ATTRIBUTE_UNUSED)
{
int rt;
@@ -327,6 +353,10 @@ write_res_resource (type, name, res, language)
case RES_TYPE_VERSIONINFO:
rt = RT_VERSION;
break;
+
+ case RES_TYPE_TOOLBAR:
+ rt = RT_TOOLBAR;
+ break;
}
if (rt != 0
@@ -339,35 +369,29 @@ write_res_resource (type, name, res, language)
abort ();
}
- write_res_bin (res, type, name, &res->res_info);
- return;
+ return write_res_bin (wrbfd, off, res, type, name, &res->res_info);
}
/* Write a resource in binary resource format */
-static void
-write_res_bin (res, type, name, resinfo)
- const struct res_resource *res;
- const struct res_id *type;
- const struct res_id *name;
- const struct res_res_info *resinfo;
+static rc_uint_type
+write_res_bin (windres_bfd *wrbfd, rc_uint_type off, const rc_res_resource *res,
+ const rc_res_id *type, const rc_res_id *name,
+ const rc_res_res_info *resinfo)
{
- unsigned long datasize = 0;
- const struct bindata *bin_rep, *data;
+ rc_uint_type noff;
+ rc_uint_type datasize = 0;
- bin_rep = res_to_bin (res, 0);
- for (data = bin_rep; data != NULL; data = data->next)
- datasize += data->length;
+ noff = res_to_bin ((windres_bfd *) NULL, off, res);
+ datasize = noff - off;
- write_res_header (datasize, type, name, resinfo);
-
- for (data = bin_rep; data != NULL; data = data->next)
- write_res_data (data->data, data->length, 1);
+ off = write_res_header (wrbfd, off, datasize, type, name, resinfo);
+ return res_to_bin (wrbfd, off, res);
}
/* Get number of bytes needed to store an id in binary format */
static unsigned long
get_id_size (id)
- const struct res_id *id;
+ const rc_res_id *id;
{
if (id->named)
return sizeof (unichar) * (id->u.n.length + 1);
@@ -376,108 +400,142 @@ get_id_size (id)
}
/* Write a resource header */
-static void
-write_res_header (datasize, type, name, resinfo)
- unsigned long datasize;
- const struct res_id *type;
- const struct res_id *name;
- const struct res_res_info *resinfo;
+static rc_uint_type
+write_res_header (windres_bfd *wrbfd, rc_uint_type off, rc_uint_type datasize,
+ const rc_res_id *type, const rc_res_id *name,
+ const rc_res_res_info *resinfo)
{
- struct res_hdr reshdr;
+ res_hdr reshdr;
reshdr.data_size = datasize;
reshdr.header_size = 24 + get_id_size (type) + get_id_size (name);
reshdr.header_size = (reshdr.header_size + 3) & ~3;
- res_align_file ();
- write_res_data (&reshdr, sizeof (reshdr), 1);
- write_res_id (type);
- write_res_id (name);
+ off = (off + 3) & ~3;
+
+ off = write_res_data_hdr (wrbfd, off, &reshdr);
+ off = write_res_id (wrbfd, off, type);
+ off = write_res_id (wrbfd, off, name);
- res_align_file ();
+ off = (off + 3) & ~3;
- write_res_info (resinfo);
- res_align_file ();
+ off = write_res_info (wrbfd, off, resinfo);
+ off = (off + 3) & ~3;
+ return off;
}
+static rc_uint_type
+write_res_data_hdr (windres_bfd *wrbfd, rc_uint_type off, res_hdr *hdr)
+{
+ if (wrbfd)
+ {
+ struct bin_res_hdr brh;
+ windres_put_32 (wrbfd, brh.data_size, hdr->data_size);
+ windres_put_32 (wrbfd, brh.header_size, hdr->header_size);
+ set_windres_bfd_content (wrbfd, &brh, off, BIN_RES_HDR_SIZE);
+ }
+ return off + BIN_RES_HDR_SIZE;
+}
-/* Write data to file, abort on failure */
static void
-write_res_data (data, size, count)
- const void *data;
- size_t size;
- int count;
+read_res_data_hdr (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax,
+ res_hdr *reshdr)
{
- if ((size_t) fwrite (data, size, count, fres) != (size_t) count)
- fatal ("%s: could not write to file", filename);
+ struct bin_res_hdr brh;
+
+ if ((off[0] + BIN_RES_HDR_SIZE) > omax)
+ fatal ("%s: unexpected end of file %ld/%ld", filename,(long) off[0], (long) omax);
+
+ get_windres_bfd_content (wrbfd, &brh, off[0], BIN_RES_HDR_SIZE);
+ reshdr->data_size = windres_get_32 (wrbfd, brh.data_size, 4);
+ reshdr->header_size = windres_get_32 (wrbfd, brh.header_size, 4);
+ off[0] += BIN_RES_HDR_SIZE;
}
/* Read data from file, abort on failure */
static void
-read_res_data (data, size, count)
- void *data;
- size_t size;
- int count;
+read_res_data (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax, void *data,
+ rc_uint_type size)
{
- if (fread (data, size, count, fres) != (size_t) count)
- fatal ("%s: unexpected end of file", filename);
+ if ((off[0] + size) > omax)
+ fatal ("%s: unexpected end of file %ld/%ld %ld", filename,(long) off[0],
+ (long) omax, (long) size);
+ get_windres_bfd_content (wrbfd, data, off[0], size);
+ off[0] += size;
}
/* Write a resource id */
-static void
-write_res_id (id)
- const struct res_id *id;
+static rc_uint_type
+write_res_id (windres_bfd *wrbfd, rc_uint_type off, const rc_res_id *id)
{
if (id->named)
{
- unsigned long len = id->u.n.length;
- unichar null_term = 0;
- write_res_data (id->u.n.name, len * sizeof (unichar), 1);
- write_res_data (&null_term, sizeof (null_term), 1);
+ rc_uint_type len = (((bfd_signed_vma) id->u.n.length < 0 ? 0 : id->u.n.length) + 1);
+ if (wrbfd)
+ {
+ rc_uint_type i;
+ bfd_byte *d = (bfd_byte *) xmalloc (len * sizeof (unichar));
+ for (i = 0; i < (len - 1); i++)
+ windres_put_16 (wrbfd, d + (i * sizeof (unichar)), id->u.n.name[i]);
+ windres_put_16 (wrbfd, d + (i * sizeof (unichar)), 0);
+ set_windres_bfd_content (wrbfd, d, off, (len * sizeof (unichar)));
+ }
+ off += (len * sizeof (unichar));
}
else
{
- unsigned short i = 0xFFFF;
- write_res_data (&i, sizeof (i), 1);
- i = id->u.id;
- write_res_data (&i, sizeof (i), 1);
+ if (wrbfd)
+ {
+ struct bin_res_id bid;
+ windres_put_16 (wrbfd, bid.sig, 0xffff);
+ windres_put_16 (wrbfd, bid.id, id->u.id);
+ set_windres_bfd_content (wrbfd, &bid, off, BIN_RES_ID);
+ }
+ off += BIN_RES_ID;
}
+ return off;
}
/* Write resource info */
-static void
-write_res_info (info)
- const struct res_res_info *info;
+static rc_uint_type
+write_res_info (windres_bfd *wrbfd, rc_uint_type off, const rc_res_res_info *info)
{
- write_res_data (&info->version, sizeof (info->version), 1);
- write_res_data (&info->memflags, sizeof (info->memflags), 1);
- write_res_data (&info->language, sizeof (info->language), 1);
- write_res_data (&info->version, sizeof (info->version), 1);
- write_res_data (&info->characteristics, sizeof (info->characteristics), 1);
+ if (wrbfd)
+ {
+ struct bin_res_info l;
+
+ windres_put_32 (wrbfd, l.version, info->version);
+ windres_put_16 (wrbfd, l.memflags, info->memflags);
+ windres_put_16 (wrbfd, l.language, info->language);
+ windres_put_32 (wrbfd, l.version2, info->version);
+ windres_put_32 (wrbfd, l.characteristics, info->characteristics);
+ set_windres_bfd_content (wrbfd, &l, off, BIN_RES_INFO_SIZE);
+ }
+ return off + BIN_RES_INFO_SIZE;
}
/* read a resource identifier */
-void
-read_res_id (id)
- struct res_id *id;
+static void
+read_res_id (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax, rc_res_id *id)
{
+ struct bin_res_id bid;
unsigned short ord;
unichar *id_s = NULL;
- int len;
+ rc_uint_type len;
- read_res_data (&ord, sizeof (ord), 1);
+ read_res_data (wrbfd, off, omax, &bid, BIN_RES_ID - 2);
+ ord = (unsigned short) windres_get_16 (wrbfd, bid.sig, 2);
if (ord == 0xFFFF) /* an ordinal id */
{
- read_res_data (&ord, sizeof (ord), 1);
+ read_res_data (wrbfd, off, omax, bid.id, BIN_RES_ID - 2);
id->named = 0;
- id->u.id = ord;
+ id->u.id = windres_get_16 (wrbfd, bid.id, 2);
}
else
/* named id */
{
- if (fseek (fres, -sizeof (ord), SEEK_CUR) != 0)
- fatal ("%s: %s: could not seek in file", program_name, filename);
- id_s = read_unistring (&len);
+ off[0] -= 2;
+ id_s = read_unistring (wrbfd, off, omax, &len);
id->named = 1;
id->u.n.length = len;
id->u.n.name = id_s;
@@ -486,39 +544,62 @@ read_res_id (id)
/* Read a null terminated UNICODE string */
static unichar *
-read_unistring (len)
- int *len;
+read_unistring (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax,
+ rc_uint_type *len)
{
unichar *s;
+ bfd_byte d[2];
unichar c;
unichar *p;
- int l;
+ rc_uint_type l;
+ rc_uint_type soff = off[0];
- *len = 0;
- l = 0;
+ do
+ {
+ read_res_data (wrbfd, &soff, omax, d, sizeof (unichar));
+ c = windres_get_16 (wrbfd, d, 2);
+ }
+ while (c != 0);
+ l = ((soff - off[0]) / sizeof (unichar));
- /* there are hardly any names longer than 256 characters */
- p = s = (unichar *) xmalloc (sizeof (unichar) * 256);
+ /* there are hardly any names longer than 256 characters, but anyway. */
+ p = s = (unichar *) xmalloc (sizeof (unichar) * l);
do
{
- read_res_data (&c, sizeof (c), 1);
+ read_res_data (wrbfd, off, omax, d, sizeof (unichar));
+ c = windres_get_16 (wrbfd, d, 2);
*p++ = c;
- if (c != 0)
- l++;
}
while (c != 0);
- *len = l;
+ *len = l - 1;
return s;
}
-/* align file on DWORD boundary */
-static void
-res_align_file (void)
+static int
+probe_binary (windres_bfd *wrbfd, rc_uint_type omax)
{
- int pos = ftell (fres);
- int skip = ((pos + 3) & ~3) - pos;
- if (fseek (fres, skip, SEEK_CUR) != 0)
- fatal ("%s: %s: unable to align file", program_name, filename);
+ rc_uint_type off;
+ res_hdr reshdr;
+
+ off = 0;
+ read_res_data_hdr (wrbfd, &off, omax, &reshdr);
+ if (reshdr.data_size != 0)
+ return 1;
+ if ((reshdr.header_size != 0x20 && ! target_is_bigendian)
+ || (reshdr.header_size != 0x20000000 && target_is_bigendian))
+ return 1;
+
+ /* Subtract size of HeaderSize. DataSize has to be zero. */
+ off += 0x20 - BIN_RES_HDR_SIZE;
+ if ((off + BIN_RES_HDR_SIZE) >= omax)
+ return 1;
+ read_res_data_hdr (wrbfd, &off, omax, &reshdr);
+ /* off is advanced by BIN_RES_HDR_SIZE in read_res_data_hdr()
+ which is part of reshdr.header_size. We shouldn't take it
+ into account twice. */
+ if ((off - BIN_RES_HDR_SIZE + reshdr.data_size + reshdr.header_size) > omax)
+ return 0;
+ return 1;
}
/* Check if file is a win32 binary resource file, if so
@@ -526,16 +607,19 @@ res_align_file (void)
error.
*/
static void
-skip_null_resource (void)
+skip_null_resource (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax)
{
- struct res_hdr reshdr =
- {0, 0};
- read_res_data (&reshdr, sizeof (reshdr), 1);
- if ((reshdr.data_size != 0) || (reshdr.header_size != 0x20))
+ res_hdr reshdr;
+ read_res_data_hdr (wrbfd, off, omax, &reshdr);
+ if (reshdr.data_size != 0)
+ goto skip_err;
+ if ((reshdr.header_size != 0x20 && ! target_is_bigendian)
+ || (reshdr.header_size != 0x20000000 && target_is_bigendian))
goto skip_err;
- /* Subtract size of HeaderSize and DataSize */
- if (fseek (fres, reshdr.header_size - 8, SEEK_CUR) != 0)
+ /* Subtract size of HeaderSize. DataSize has to be zero. */
+ off[0] += 0x20 - BIN_RES_HDR_SIZE;
+ if (off[0] >= omax)
goto skip_err;
return;
@@ -547,15 +631,11 @@ skip_err:
}
/* Add a resource to resource directory */
-void
-res_add_resource (r, type, id, language, dupok)
- struct res_resource *r;
- const struct res_id *type;
- const struct res_id *id;
- int language;
- int dupok;
+static void
+res_add_resource (rc_res_resource *r, const rc_res_id *type, const rc_res_id *id,
+ rc_uint_type language, int dupok)
{
- struct res_id a[3];
+ rc_res_id a[3];
a[0] = *type;
a[1] = *id;
@@ -568,21 +648,17 @@ res_add_resource (r, type, id, language, dupok)
This is just copied from define_resource
and modified to add an existing resource.
*/
-void
-res_append_resource (resources, resource, cids, ids, dupok)
- struct res_directory **resources;
- struct res_resource *resource;
- int cids;
- const struct res_id *ids;
- int dupok;
+static void
+res_append_resource (rc_res_directory **resources, rc_res_resource *resource,
+ int cids, const rc_res_id *ids, int dupok)
{
- struct res_entry *re = NULL;
+ rc_res_entry *re = NULL;
int i;
assert (cids > 0);
for (i = 0; i < cids; i++)
{
- struct res_entry **pp;
+ rc_res_entry **pp;
if (*resources == NULL)
{
@@ -593,8 +669,8 @@ res_append_resource (resources, resource, cids, ids, dupok)
if (timeval == 0)
timeval = time (NULL);
- *resources = ((struct res_directory *)
- res_alloc (sizeof **resources));
+ *resources = ((rc_res_directory *)
+ res_alloc (sizeof (rc_res_directory)));
(*resources)->characteristics = 0;
(*resources)->time = timeval;
(*resources)->major = 0;
@@ -610,7 +686,7 @@ res_append_resource (resources, resource, cids, ids, dupok)
re = *pp;
else
{
- re = (struct res_entry *) res_alloc (sizeof *re);
+ re = (rc_res_entry *) res_alloc (sizeof (rc_res_entry));
re->next = NULL;
re->id = ids[i];
if ((i + 1) < cids)
@@ -629,7 +705,7 @@ res_append_resource (resources, resource, cids, ids, dupok)
if ((i + 1) < cids)
{
- if (!re->subdir)
+ if (! re->subdir)
{
fprintf (stderr, "%s: ", program_name);
res_ids_print (stderr, i, ids);