📄 cvtres.c
字号:
int i;
mi->id = 0;
mi->popup = to_menuitems(data + itemlen, length - itemlen, be,
&i);
itemlen += i;
}
mi->link = NULL;
*p = mi;
p = &mi->link;
data += itemlen;
length -= itemlen;
*read += itemlen;
if ((flags &MI_ENDMENU))
return first;
}
return first;
}
static struct menuitem *to_menuexitems(unsigned char *data, int length, int
be, int *read)
{
struct menuitem *first = NULL, **p = &first, *mi;
int flags, slen, itemlen;
*read = 0;
while (length > 0)
{
checksize(length, 14);
mi = AllocateMemory(sizeof(*mi));
mi->type = get_32(be, data);
mi->state = get_32(be, data + 4);
mi->id = get_16(be, data + 8);
flags = get_16(be, data + 10);
mi->text = to_string(data + 12, length - 12, be, &slen);
itemlen = 12+slen * 2+2;
itemlen = (itemlen + 3) &~3;
if ((flags &1) == 0)
{
mi->popup = NULL;
mi->help = 0;
}
else
{
int i;
checksize(length, itemlen + 4);
mi->help = get_32(be, data + itemlen);
itemlen += 4;
mi->popup = to_menuexitems(data + itemlen, length - itemlen, be,
&i);
itemlen += i;
}
mi->link = NULL;
*p = mi;
p = &mi->link;
data += itemlen;
length -= itemlen;
*read += itemlen;
if ((flags &0x80) != 0)
return first;
}
return first;
}
static RES_RES *to_menu(unsigned char *data, int length, int be)
{
RES_RES *r = AllocateMemory(sizeof(RES_RES));
struct menu *m;
int version, read;
r->type = RST_MENU;
r->u.menu = m = AllocateMemory(sizeof *m);
m->help = 0;
checksize(length, 2);
version = get_16(be, data);
if (version == 0)
{
checksize(length, 4);
m->items = to_menuitems(data + 4, length - 4, be, &read);
}
else if (version == 1)
{
int offset;
checksize(length, 8);
m->help = get_32(be, data + 4);
offset = get_16(be, data + 2);
checksize(length, offset + 4);
m->items = to_menuexitems(data + 4+offset, length - (4+offset), be,
&read);
}
else
fatal("unsupported menu version %d", version);
return r;
}
static RES_RES *to_rcdata(unsigned char *data, int length, int be)
{
RES_RES *r = AllocateMemory(sizeof(RES_RES));
struct rcdata_item *ri = AllocateMemory(sizeof(struct rcdata_item));
r->type = RST_RCDATA;
r->u.rcdata = ri;
ri->link = NULL;
ri->type = RCDATA_BUFFER;
ri->u.buffer.length = length;
ri->u.buffer.data = data;
return r;
}
static RES_RES *to_stringtable(unsigned char *data, int length, int be)
{
RES_RES *r = AllocateMemory(sizeof(RES_RES));
struct stringtable *st = AllocateMemory(sizeof(struct stringtable));
int i;
r->type = RST_STRINGTABLE;
r->u.stringtable = st;
for (i = 0; i < 16; i++)
{
int slen;
checksize(length, 2);
if (st->strings[i].length = slen = get_16(be, data))
{
CHARACTER *s;
int j;
checksize(length, 2+2 * slen);
st->strings[i].string = s = AllocateMemory((slen + 1) *sizeof
(CHARACTER));
for (j = 0; j < slen; j++)
s[j] = get_16(be, data + 2+j * 2);
s[j] = 0;
}
data += 2+2 * slen;
length -= 2+2 * slen;
}
return r;
}
static RES_RES *to_userdata(unsigned char *data, int length, int be)
{
RES_RES *r = AllocateMemory(sizeof(RES_RES));
struct rcdata_item *ri = AllocateMemory(sizeof(struct rcdata_item));
r->type = RST_USERDATA;
r->u.rcdata = ri;
ri->link = NULL;
ri->type = RCDATA_BUFFER;
ri->u.buffer.length = length;
ri->u.buffer.data = data;
return r;
}
static void get_version_header(unsigned char *data, int length, int be,
char *key, CHARACTER **pkey, int *len, int *vallen, int *type, int *off)
{
checksize(length, 8);
*len = get_16(be, data);
*vallen = get_16(be, data + 2);
*type = get_16(be, data + 4);
*off = 6;
length -= 6;
data += 6;
if (key == NULL)
{
int i;
*pkey = to_string(data, length, be, &i);
*off += i * 2+2;
}
else
{
while (1)
{
checksize(length, 2);
if (get_16(be, data) != *key)
fatal("unexpected version string");
*off += 2;
length -= 2;
data += 2;
if (*key == '\0')
break;
++key;
}
}
*off = (*off + 3) &~3;
}
static RES_RES *to_version(unsigned char *data, int length, int be)
{
int verlen, vallen, type, off;
struct fixed_versioninfo *fi;
struct ver_info *first, **pp;
struct versioninfo *v;
RES_RES *r = AllocateMemory(sizeof(RES_RES));
r->type = RST_VERSIONINFO;
get_version_header(data, length, be, "VS_VERSION_INFO", (CHARACTER*)
NULL, &verlen, &vallen, &type, &off);
if (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);
checksize(length, 52);
signature = get_32(be, data);
if (signature != 0xfeef04bd)
fatal("unexpected fixed version signature %lu", signature);
fiv = get_32(be, data + 4);
if (fiv != 0 && fiv != 0x10000)
fatal("unexpected fixed version info version %lu", fiv);
fi = AllocateMemory(sizeof *fi);
fi->file_version_ms = get_32(be, data + 8);
fi->file_version_ls = get_32(be, data + 12);
fi->product_version_ms = get_32(be, data + 16);
fi->product_version_ls = get_32(be, data + 20);
fi->file_flags_mask = get_32(be, data + 24);
fi->file_flags = get_32(be, data + 28);
fi->file_os = get_32(be, data + 32);
fi->file_type = get_32(be, data + 36);
fi->file_subtype = get_32(be, data + 40);
fi->file_date_ms = get_32(be, data + 44);
fi->file_date_ls = get_32(be, data + 48);
data += 52;
length -= 52;
}
first = NULL;
pp = &first;
while (length > 0)
{
struct ver_info *vi = AllocateMemory(sizeof(struct ver_info));
int ch;
checksize(length, 8);
ch = get_16(be, data + 6);
if (ch == 'S')
{
struct ver_stringinfo **ppvs = &vi->u.string.strings;
vi->type = VERINFO_STRING;
get_version_header(data, length, be, "StringFileInfo",
(CHARACTER*)NULL, &verlen, &vallen, &type, &off);
if (vallen != 0)
fatal("unexpected stringfileinfo value length %d", vallen);
data += off;
length -= off;
get_version_header(data, length, be, (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;
/* 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 = AllocateMemory(sizeof(struct
ver_stringinfo));
int subverlen, vslen, valoff;
get_version_header(data, length, be, (const char*)NULL, &vs
->key, &subverlen, &vallen, &type, &off);
subverlen = (subverlen + 3) &~3;
data += off;
length -= off;
vs->value = to_string(data, length, be, &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->link = NULL;
*ppvs = vs;
ppvs = &vs->link;
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->u.var.var;
vi->type = VERINFO_VAR;
get_version_header(data, length, be, "VarFileInfo", (CHARACTER*)
NULL, &verlen, &vallen, &type, &off);
if (vallen != 0)
fatal("unexpected varfileinfo value length %d", vallen);
data += off;
length -= off;
get_version_header(data, length, be, (const char*)NULL, &vi
->u.var.key, &verlen, &vallen, &type, &off);
data += off;
length -= off;
vi->u.var.var = NULL;
while (vallen > 0)
{
struct ver_varinfo *vv;
checksize(length, 4);
vv = AllocateMemory(sizeof *vv);
vv->language = get_16(be, data);
vv->charset = get_16(be, data + 2);
vv->link = NULL;
*ppvv = vv;
ppvv = &vv->link;
data += 4;
length -= 4;
if (vallen < 4)
fatal("unexpected version value length %d", vallen);
vallen -= 4;
}
}
else
fatal("unexpected version string");
vi->link = NULL;
*pp = vi;
pp = &vi->link;
}
v = AllocateMemory(sizeof *v);
v->fixed = fi;
v->var = first;
r->u.versioninfo = v;
return r;
}
#endif
RES_RES *convert_to_internal(RES_ID *type, unsigned char *data, int length, int
be)
{
return 0;
#ifdef XXXXX
if (type->hasname)
return to_userdata(data, length, be);
else
{
switch (type->v.id)
{
default:
return to_userdata(data, length, be);
case RT_ACCELERATOR:
return to_accelerators(data, length, be);
case RT_BITMAP:
return to_generic(RST_BITMAP, data, length);
case RT_CURSOR:
return to_cursor(data, length, be);
case RT_DIALOG:
return to_dialog(data, length, be);
case RT_DLGINCLUDE:
return to_generic(RST_DLGINCLUDE, data, length);
case RT_FONT:
return to_generic(RST_FONT, data, length);
case RT_FONTDIR:
return to_fontdir(data, length, be);
case RT_GROUP_CURSOR:
return to_group_cursor(data, length, be);
case RT_GROUP_ICON:
return to_group_icon(data, length, be);
case RT_ICON:
return to_generic(RST_ICON, data, length);
case RT_MENU:
return to_menu(data, length, be);
case RT_MESSAGETABLE:
return to_generic(RST_MESSAGETABLE, data, length);
case RT_RCDATA:
return to_rcdata(data, length, be);
case RT_STRING:
return to_stringtable(data, length, be);
case RT_VERSION:
return to_version(data, length, be);
}
}
#endif
}
//-------------------------------------------------------------------------
static void put_16(int be, int v, unsigned char *s)
{
if (be)
{
*s++ = v >> 8;
*s++ = v;
}
else
{
*(short*)s = v;
}
}
//-------------------------------------------------------------------------
static long put_32(int be, int v, unsigned char *s)
{
if (be)
{
*s++ = v >> 24;
*s++ = v >> 16;
*s++ = v >> 8;
*s++ = v;
}
else
{
*(long*)s = v;
}
}
//-------------------------------------------------------------------------
static void align(BINDATA * * * ppp, long *length)
{
int add;
BINDATA *d;
if ((*length &3) == 0)
return ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -