/* .type { .field { name 0 : string buildin 1 : integer type 2 : integer tag 3 : integer array 4 : boolean } name 0 : string fields 1 : *field } */ static const uint8_t * import_type(struct sproto *s, struct sproto_type *t, const uint8_t * stream) { uint32_t sz = todword(stream); stream += SIZEOF_LENGTH; const uint8_t * result = stream + sz; int fn = struct_field(stream, sz); if (fn <= 0 || fn > 2) return NULL; int i; for (i=0;i<fn*SIZEOF_FIELD;i+=SIZEOF_FIELD) { // name and fields must encode to 0 int v = toword(stream + SIZEOF_HEADER + i); if (v != 0) return NULL; } memset(t, 0, sizeof(*t)); stream += SIZEOF_HEADER + fn * SIZEOF_FIELD; t->name = import_string(s, stream); if (fn == 1) { return result; } stream += todword(stream)+SIZEOF_LENGTH; // second data int n = count_array(stream); if (n<0) return NULL; stream += SIZEOF_LENGTH; int maxn = n; int last = -1; t->n = n; t->f = pool_alloc(&s->memory, sizeof(struct field) * n); for (i=0;i<n;i++) { struct field *f = &t->f[i]; stream = import_field(s, f, stream); if (stream == NULL) return NULL; int tag = f->tag; if (tag < last) return NULL; // tag must in ascending order if (tag > last+1) { ++maxn; } last = tag; } t->maxn = maxn; t->base = t->f[0].tag; n = t->f[n-1].tag - t->base + 1; if (n != t->n) { t->base = -1; } return result; }
static int struct_field(const uint8_t * stream, size_t sz) { if (sz < SIZEOF_LENGTH) return -1; int fn = toword(stream); int header = SIZEOF_HEADER + SIZEOF_FIELD * fn; if (sz < header) return -1; const uint8_t * field = stream + SIZEOF_HEADER; sz -= header; stream += header; int i; for (i=0;i<fn;i++) { int value= toword(field + i * SIZEOF_FIELD + SIZEOF_HEADER); if (value != 0) continue; if (sz < SIZEOF_LENGTH) return -1; uint32_t dsz = todword(stream); if (sz < SIZEOF_LENGTH + dsz) return -1; stream += SIZEOF_LENGTH + dsz; sz -= SIZEOF_LENGTH + dsz; } return fn; }
static const char * import_string(struct sproto *s, const uint8_t * stream) { uint32_t sz = todword(stream); char * buffer = pool_alloc(&s->memory, sz+1); memcpy(buffer, stream+SIZEOF_LENGTH, sz); buffer[sz] = '\0'; return buffer; }
static int count_array(const uint8_t * stream) { uint32_t length = todword(stream); stream += SIZEOF_LENGTH; int n = 0; while (length > 0) { if (length < SIZEOF_LENGTH) return -1; uint32_t nsz = todword(stream); nsz += SIZEOF_LENGTH; if (nsz > length) return -1; ++n; stream += nsz; length -= nsz; } return n; }
/* .protocol { name 0 : string tag 1 : integer request 2 : integer response 3 : integer } */ static const uint8_t * import_protocol(struct sproto *s, struct protocol *p, const uint8_t * stream) { uint32_t sz = todword(stream); stream += SIZEOF_LENGTH; const uint8_t * result = stream + sz; int fn = struct_field(stream, sz); stream += SIZEOF_HEADER; p->name = NULL; p->tag = -1; p->p[SPROTO_REQUEST] = NULL; p->p[SPROTO_RESPONSE] = NULL; int i; for (i=0;i<fn;i++) { int value = toword(stream + SIZEOF_FIELD * i); if (value & 1) return NULL; value = value/2 - 1; switch (i) { case 0: // name if (value != -1) { return NULL; } p->name = import_string(s, stream + SIZEOF_FIELD *fn); break; case 1: // tag if (value < 0) { return NULL; } p->tag = value; break; case 2: // request if (value < 0 || value>=s->type_n) return NULL; p->p[SPROTO_REQUEST] = &s->type[value]; break; case 3: // response if (value < 0 || value>=s->type_n) return NULL; p->p[SPROTO_RESPONSE] = &s->type[value]; break; default: return NULL; } } if (p->name == NULL || p->tag<0 || p->p[SPROTO_REQUEST] == NULL) { return NULL; } return result; }
static struct sproto * create_from_bundle(struct sproto *s, const uint8_t * stream, size_t sz) { int fn = struct_field(stream, sz); if (fn < 0) return NULL; stream += SIZEOF_HEADER; const uint8_t * content = stream + fn*SIZEOF_FIELD; const uint8_t * typedata = NULL; const uint8_t * protocoldata = NULL; int i; for (i=0;i<fn;i++) { int value = toword(stream + i*SIZEOF_FIELD); if (value != 0) return NULL; int n = count_array(content); if (n<0) return NULL; if (i == 0) { typedata = content+SIZEOF_LENGTH; s->type_n = n; s->type = pool_alloc(&s->memory, n * sizeof(*s->type)); } else { protocoldata = content+SIZEOF_LENGTH; s->protocol_n = n; s->proto = pool_alloc(&s->memory, n * sizeof(*s->proto)); } content += todword(content) + SIZEOF_LENGTH; } for (i=0;i<s->type_n;i++) { typedata = import_type(s, &s->type[i], typedata); if (typedata == NULL) { return NULL; } } for (i=0;i<s->protocol_n;i++) { protocoldata = import_protocol(s, &s->proto[i], protocoldata); if (protocoldata == NULL) { return NULL; } } return s; }
struct newresource *scaleresource (struct newresource *res, HWND parent) { DLGTEMPLATEEX *d; DLGTEMPLATEEX_END *d2; DLGITEMTEMPLATEEX *dt; BYTE *p, *p2; int i; struct newresource *ns; d = (DLGTEMPLATEEX*)res->resource; d2 = (DLGTEMPLATEEX_END*)res->resource; if (d->dlgVer != 1 || d->signature != 0xffff) return 0; if (!(d->style & (DS_SETFONT | DS_SHELLFONT))) return 0; ns = xcalloc (struct newresource, 1); ns->inst = res->inst; ns->size = res->size; ns->tmpl = res->tmpl; ns->resource = (LPCDLGTEMPLATEW)xmalloc (uae_u8, ns->size); memcpy ((void*)ns->resource, res->resource, ns->size); d = (DLGTEMPLATEEX*)ns->resource; d2 = (DLGTEMPLATEEX_END*)ns->resource; p = (BYTE*)d + sizeof (DLGTEMPLATEEX); p = skiptext (p); p = skiptext (p); p = skiptext (p); d2 = (DLGTEMPLATEEX_END*)p; p2 = p; p2 += sizeof (DLGTEMPLATEEX_END); p2 = skiptextone (p2); p2 = todword (p2); modifytemplatefont (d, d2); p += sizeof (DLGTEMPLATEEX_END); p = skiptextone (p); p = todword (p); if (p != p2) memmove (p, p2, ns->size - (p2 - (BYTE*)ns->resource)); modifytemplate(d, d2, ns->tmpl, mult); for (i = 0; i < d->cDlgItems; i++) { dt = (DLGITEMTEMPLATEEX*)p; modifyitem (d, d2, dt, ns->tmpl, mult); p += sizeof (DLGITEMTEMPLATEEX); p = skiptextone (p); p = skiptext (p); p += ((WORD*)p)[0]; p += sizeof (WORD); p = todword (p); } ns->width = d->cx; ns->height = d->cy; return ns; }
static struct newresource *scaleresource2 (struct newresource *res, HWND parent, int resize, int fullscreen, DWORD exstyle) { DLGTEMPLATEEX *d, *s; DLGTEMPLATEEX_END *d2, *s2; DLGITEMTEMPLATEEX *dt; BYTE *p, *p2, *ps, *ps2; int i; struct newresource *ns; listviewcnt = 0; d = (DLGTEMPLATEEX*)res->resource; d2 = (DLGTEMPLATEEX_END*)res->resource; if (d->dlgVer != 1 || d->signature != 0xffff) return 0; if (!(d->style & (DS_SETFONT | DS_SHELLFONT))) return 0; ns = xcalloc (struct newresource, 1); ns->inst = res->inst; ns->size = res->size; ns->tmpl = res->tmpl; ns->resource = (LPCDLGTEMPLATEW)xmalloc (uae_u8, ns->size + 32); memcpy ((void*)ns->resource, res->resource, ns->size); d = (DLGTEMPLATEEX*)ns->resource; s = (DLGTEMPLATEEX*)res->resource; int width = d->cx; int height = d->cy; if (resize > 0) { d->style &= ~DS_MODALFRAME; d->style |= WS_THICKFRAME; } else if (resize == 0) { d->style |= DS_MODALFRAME; d->style &= ~WS_THICKFRAME; } if (fullscreen > 0) { //d->style |= SW_MAXIMIZE; d->style |= WS_THICKFRAME; } else { d->style |= WS_MINIMIZEBOX; } d->exStyle |= exstyle; d2 = (DLGTEMPLATEEX_END*)ns->resource; p = (BYTE*)d + sizeof (DLGTEMPLATEEX); p = skiptext (p); p = skiptext (p); p = skiptext (p); s2 = (DLGTEMPLATEEX_END*)res->resource; ps = (BYTE*)s2 + sizeof (DLGTEMPLATEEX); ps = skiptext (ps); ps = skiptext (ps); ps = skiptext (ps); d2 = (DLGTEMPLATEEX_END*)p; p2 = p; p2 += sizeof (DLGTEMPLATEEX_END); p2 = skiptextone (p2); p2 = todword (p2); s2 = (DLGTEMPLATEEX_END*)ps; ps2 = ps; ps2 += sizeof (DLGTEMPLATEEX_END); ps2 = skiptextone (ps2); ps2 = todword (ps2); modifytemplatefont (d, d2); p += sizeof (DLGTEMPLATEEX_END); p = skiptextone (p); p = todword (p); memcpy (p, ps2, ns->size - (ps2 - (BYTE*)res->resource)); modifytemplate(d, d2, ns->tmpl, fullscreen); for (i = 0; i < d->cDlgItems; i++) { dt = (DLGITEMTEMPLATEEX*)p; modifyitem (d, d2, dt, ns->tmpl); p += sizeof (DLGITEMTEMPLATEEX); p = skiptextone (p); p = skiptext (p); p += ((WORD*)p)[0]; p += sizeof (WORD); p = todword (p); } ns->width = width; ns->height = height; return ns; }
static const uint8_t * import_field(struct sproto *s, struct field *f, const uint8_t * stream) { f->tag = -1; f->type = -1; f->name = NULL; f->st = NULL; uint32_t sz = todword(stream); stream += SIZEOF_LENGTH; const uint8_t * result = stream + sz; int fn = struct_field(stream, sz); if (fn < 0) return NULL; stream += SIZEOF_HEADER; int i; int array = 0; int tag = -1; for (i=0;i<fn;i++) { ++tag; int value = toword(stream + SIZEOF_FIELD * i); if (value & 1) { tag+= value/2; continue; } if (tag == 0) { // name if (value != 0) return NULL; f->name = import_string(s, stream + fn * SIZEOF_FIELD); continue; } if (value == 0) return NULL; value = value/2 - 1; switch(tag) { case 1: // buildin if (value >= SPROTO_TSTRUCT) return NULL; // invalid buildin type f->type = value; break; case 2: // type index if (value >= s->type_n) return NULL; // invalid type index if (f->type >= 0) return NULL; f->type = SPROTO_TSTRUCT; f->st = &s->type[value]; break; case 3: // tag f->tag = value; break; case 4: // array if (value) array = SPROTO_TARRAY; break; default: return NULL; } } if (f->tag < 0 || f->type < 0 || f->name == NULL) return NULL; f->type |= array; return result; }