Line 1... |
Line 1... |
/* resbin.c -- manipulate the Windows binary resource format.
|
/* resbin.c -- manipulate the Windows binary resource format.
|
Copyright 1997, 1998, 1999, 2002, 2003, 2005, 2006, 2007, 2009, 2010
|
Copyright 1997, 1998, 1999, 2002, 2003, 2005, 2006, 2007, 2009, 2010, 2011
|
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
Written by Ian Lance Taylor, Cygnus Support.
|
Written by Ian Lance Taylor, Cygnus Support.
|
Rewritten by Kai Tietz, Onevision.
|
Rewritten by Kai Tietz, Onevision.
|
|
|
This file is part of GNU Binutils.
|
This file is part of GNU Binutils.
|
Line 1025... |
Line 1025... |
|
|
ch = windres_get_16 (wrbfd, data + 6, 2);
|
ch = windres_get_16 (wrbfd, data + 6, 2);
|
|
|
if (ch == 'S')
|
if (ch == 'S')
|
{
|
{
|
rc_ver_stringinfo **ppvs;
|
rc_ver_stringtable **ppvst;
|
|
|
vi->type = VERINFO_STRING;
|
vi->type = VERINFO_STRING;
|
|
|
get_version_header (wrbfd, data, length, "StringFileInfo",
|
get_version_header (wrbfd, data, length, "StringFileInfo",
|
(unichar **) NULL, &verlen, &vallen, &type,
|
(unichar **) NULL, &verlen, &vallen, &type,
|
Line 1039... |
Line 1039... |
fatal (_("unexpected stringfileinfo value length %ld"), (long) vallen);
|
fatal (_("unexpected stringfileinfo value length %ld"), (long) vallen);
|
|
|
data += off;
|
data += off;
|
length -= off;
|
length -= off;
|
|
|
|
/* It's convenient to round verlen to a 4 byte alignment,
|
|
since we round the subvariables in the loop. */
|
|
|
|
verlen = (verlen + 3) &~ 3;
|
|
|
|
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,
|
get_version_header (wrbfd, data, length, (const char *) NULL,
|
&vi->u.string.language, &verlen, &vallen,
|
&vst->language, &stverlen, &vallen, &type, &off);
|
&type, &off);
|
|
|
|
if (vallen != 0)
|
if (vallen != 0)
|
fatal (_("unexpected version stringtable value length %ld"), (long) vallen);
|
fatal (_("unexpected version stringtable value length %ld"), (long) vallen);
|
|
|
data += off;
|
data += off;
|
length -= off;
|
length -= off;
|
verlen -= off;
|
verlen -= off;
|
|
|
vi->u.string.strings = NULL;
|
stverlen = (stverlen + 3) &~ 3;
|
ppvs = &vi->u.string.strings;
|
|
|
|
/* It's convenient to round verlen to a 4 byte alignment,
|
vst->strings = NULL;
|
since we round the subvariables in the loop. */
|
ppvs = &vst->strings;
|
verlen = (verlen + 3) &~ 3;
|
|
|
|
while (verlen > 0)
|
while (stverlen > 0)
|
{
|
{
|
rc_ver_stringinfo *vs;
|
rc_ver_stringinfo *vs;
|
rc_uint_type subverlen, vslen, valoff;
|
rc_uint_type sverlen, vslen, valoff;
|
|
|
vs = (rc_ver_stringinfo *) res_alloc (sizeof *vs);
|
if (length < 8)
|
|
toosmall (_("version string"));
|
|
|
get_version_header (wrbfd, data, length,
|
vs = (rc_ver_stringinfo *) res_alloc (sizeof (rc_ver_stringinfo));
|
(const char *) NULL, &vs->key, &subverlen,
|
|
&vallen, &type, &off);
|
get_version_header (wrbfd, data, length, (const char *) NULL,
|
|
&vs->key, &sverlen, &vallen, &type, &off);
|
|
|
subverlen = (subverlen + 3) &~ 3;
|
sverlen = (sverlen + 3) &~ 3;
|
|
|
data += off;
|
data += off;
|
length -= off;
|
length -= off;
|
|
|
vs->value = get_unicode (wrbfd, data, length, &vslen);
|
vs->value = get_unicode (wrbfd, data, length, &vslen);
|
valoff = vslen * 2 + 2;
|
valoff = vslen * 2 + 2;
|
valoff = (valoff + 3) &~ 3;
|
valoff = (valoff + 3) &~ 3;
|
|
|
if (off + valoff != subverlen)
|
if (off + valoff != sverlen)
|
fatal (_("unexpected version string length %ld != %ld + %ld"),
|
fatal (_("unexpected version string length %ld != %ld + %ld"),
|
(long) subverlen, (long) off, (long) valoff);
|
(long) sverlen, (long) off, (long) valoff);
|
|
|
vs->next = NULL;
|
|
*ppvs = vs;
|
|
ppvs = &vs->next;
|
|
|
|
data += valoff;
|
data += valoff;
|
length -= valoff;
|
length -= valoff;
|
|
|
if (verlen < subverlen)
|
if (stverlen < sverlen)
|
fatal (_("unexpected version string length %ld < %ld"),
|
fatal (_("unexpected version string length %ld < %ld"),
|
(long) verlen, (long) subverlen);
|
(long) verlen, (long) sverlen);
|
|
stverlen -= sverlen;
|
|
|
|
vs->next = NULL;
|
|
*ppvs = vs;
|
|
ppvs = &vs->next;
|
|
}
|
|
|
verlen -= subverlen;
|
vst->next = NULL;
|
|
*ppvst = vst;
|
|
ppvst = &vst->next;
|
}
|
}
|
}
|
}
|
else if (ch == 'V')
|
else if (ch == 'V')
|
{
|
{
|
rc_ver_varinfo **ppvv;
|
rc_ver_varinfo **ppvv;
|
Line 2003... |
Line 2025... |
{
|
{
|
default:
|
default:
|
abort ();
|
abort ();
|
case VERINFO_STRING:
|
case VERINFO_STRING:
|
{
|
{
|
struct bin_ver_info bvsd;
|
const rc_ver_stringtable *vst;
|
rc_uint_type vs_off;
|
|
const rc_ver_stringinfo *vs;
|
|
|
|
off = string_to_unicode_bin (wrbfd, off, "StringFileInfo");
|
off = string_to_unicode_bin (wrbfd, off, "StringFileInfo");
|
|
|
|
if (!vi->u.string.stringtables)
|
off += (4 - ((off - off_delta) & 3)) & 3;
|
off += (4 - ((off - off_delta) & 3)) & 3;
|
|
|
vs_off = off;
|
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 += BIN_VER_INFO_SIZE;
|
|
|
off = unicode_to_bin (wrbfd, off, vi->u.string.language);
|
off = unicode_to_bin (wrbfd, off, vst->language);
|
|
|
for (vs = vi->u.string.strings; vs != NULL; vs = vs->next)
|
for (vs = vst->strings; vs != NULL; vs = vs->next)
|
{
|
{
|
struct bin_ver_info bvss;
|
struct bin_ver_info bvs;
|
rc_uint_type vss_off,str_off;
|
rc_uint_type vs_off, str_off;
|
|
|
off += (4 - ((off - off_delta) & 3)) & 3;
|
off += (4 - ((off - off_delta) & 3)) & 3;
|
|
|
vss_off = off;
|
vs_off = off;
|
off += BIN_VER_INFO_SIZE;
|
off += BIN_VER_INFO_SIZE;
|
|
|
off = unicode_to_bin (wrbfd, off, vs->key);
|
off = unicode_to_bin (wrbfd, off, vs->key);
|
|
|
off += (4 - ((off - off_delta) & 3)) & 3;
|
off += (4 - ((off - off_delta) & 3)) & 3;
|
|
|
str_off = off;
|
str_off = off;
|
off = unicode_to_bin (wrbfd, off, vs->value);
|
off = unicode_to_bin (wrbfd, off, vs->value);
|
|
|
if (wrbfd)
|
if (wrbfd)
|
{
|
{
|
windres_put_16 (wrbfd, bvss.size, off - vss_off);
|
windres_put_16 (wrbfd, bvs.size, off - vs_off);
|
windres_put_16 (wrbfd, bvss.sig1, (off - str_off) / 2);
|
windres_put_16 (wrbfd, bvs.sig1, (off - str_off) / 2);
|
windres_put_16 (wrbfd, bvss.sig2, 1);
|
windres_put_16 (wrbfd, bvs.sig2, 1);
|
set_windres_bfd_content (wrbfd, &bvss, vss_off,
|
set_windres_bfd_content (wrbfd, &bvs, vs_off,
|
BIN_VER_INFO_SIZE);
|
BIN_VER_INFO_SIZE);
|
}
|
}
|
}
|
}
|
|
|
if (wrbfd)
|
if (wrbfd)
|
{
|
{
|
windres_put_16 (wrbfd, bvsd.size, off - vs_off);
|
windres_put_16 (wrbfd, bvst.size, off - vst_off);
|
windres_put_16 (wrbfd, bvsd.sig1, 0);
|
windres_put_16 (wrbfd, bvst.sig1, 0);
|
windres_put_16 (wrbfd, bvsd.sig2, 0);
|
windres_put_16 (wrbfd, bvst.sig2, 1);
|
set_windres_bfd_content (wrbfd, &bvsd, vs_off,
|
set_windres_bfd_content (wrbfd, &bvst, vst_off,
|
BIN_VER_INFO_SIZE);
|
BIN_VER_INFO_SIZE);
|
}
|
}
|
|
}
|
break;
|
break;
|
}
|
}
|
|
|
case VERINFO_VAR:
|
case VERINFO_VAR:
|
{
|
{
|
Line 2100... |
Line 2132... |
|
|
if (wrbfd)
|
if (wrbfd)
|
{
|
{
|
windres_put_16 (wrbfd, bv.size, off-bv_off);
|
windres_put_16 (wrbfd, bv.size, off-bv_off);
|
windres_put_16 (wrbfd, bv.sig1, 0);
|
windres_put_16 (wrbfd, bv.sig1, 0);
|
windres_put_16 (wrbfd, bv.sig2, 0);
|
windres_put_16 (wrbfd, bv.sig2, 1);
|
set_windres_bfd_content (wrbfd, &bv, bv_off,
|
set_windres_bfd_content (wrbfd, &bv, bv_off,
|
BIN_VER_INFO_SIZE);
|
BIN_VER_INFO_SIZE);
|
}
|
}
|
}
|
}
|
|
|