newstruc.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278
  1. /*
  2. * Create dynamic new structures of various types
  3. * and some utils in that trend.
  4. *
  5. * Copyright 1998 Bertho A. Stultiens
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  20. */
  21. #include "config.h"
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <assert.h>
  26. #include <ctype.h>
  27. #include "wrc.h"
  28. #include "newstruc.h"
  29. #include "utils.h"
  30. #include "parser.h"
  31. #include "wingdi.h" /* for BITMAPINFOHEADER */
  32. #define ICO_PNG_MAGIC 0x474e5089
  33. #include <pshpack2.h>
  34. typedef struct
  35. {
  36. DWORD biSize;
  37. WORD biWidth;
  38. WORD biHeight;
  39. WORD biPlanes;
  40. WORD biBitCount;
  41. } BITMAPOS2HEADER;
  42. #include <poppack.h>
  43. /* New instances for all types of structures */
  44. /* Very inefficient (in size), but very functional :-]
  45. * Especially for type-checking.
  46. */
  47. dialog_t *new_dialog(void)
  48. {
  49. dialog_t *ret = xmalloc( sizeof(*ret) );
  50. memset( ret, 0, sizeof(*ret) );
  51. return ret;
  52. }
  53. name_id_t *new_name_id(void)
  54. {
  55. name_id_t *ret = xmalloc( sizeof(*ret) );
  56. memset( ret, 0, sizeof(*ret) );
  57. return ret;
  58. }
  59. menu_t *new_menu(void)
  60. {
  61. menu_t *ret = xmalloc( sizeof(*ret) );
  62. memset( ret, 0, sizeof(*ret) );
  63. return ret;
  64. }
  65. menu_item_t *new_menu_item(void)
  66. {
  67. menu_item_t *ret = xmalloc( sizeof(*ret) );
  68. memset( ret, 0, sizeof(*ret) );
  69. return ret;
  70. }
  71. control_t *new_control(void)
  72. {
  73. control_t *ret = xmalloc( sizeof(*ret) );
  74. memset( ret, 0, sizeof(*ret) );
  75. return ret;
  76. }
  77. icon_t *new_icon(void)
  78. {
  79. icon_t *ret = xmalloc( sizeof(*ret) );
  80. memset( ret, 0, sizeof(*ret) );
  81. return ret;
  82. }
  83. cursor_t *new_cursor(void)
  84. {
  85. cursor_t *ret = xmalloc( sizeof(*ret) );
  86. memset( ret, 0, sizeof(*ret) );
  87. return ret;
  88. }
  89. versioninfo_t *new_versioninfo(void)
  90. {
  91. versioninfo_t *ret = xmalloc( sizeof(*ret) );
  92. memset( ret, 0, sizeof(*ret) );
  93. return ret;
  94. }
  95. ver_value_t *new_ver_value(void)
  96. {
  97. ver_value_t *ret = xmalloc( sizeof(*ret) );
  98. memset( ret, 0, sizeof(*ret) );
  99. return ret;
  100. }
  101. ver_block_t *new_ver_block(void)
  102. {
  103. ver_block_t *ret = xmalloc( sizeof(*ret) );
  104. memset( ret, 0, sizeof(*ret) );
  105. return ret;
  106. }
  107. stt_entry_t *new_stt_entry(void)
  108. {
  109. stt_entry_t *ret = xmalloc( sizeof(*ret) );
  110. memset( ret, 0, sizeof(*ret) );
  111. return ret;
  112. }
  113. accelerator_t *new_accelerator(void)
  114. {
  115. accelerator_t *ret = xmalloc( sizeof(*ret) );
  116. memset( ret, 0, sizeof(*ret) );
  117. return ret;
  118. }
  119. event_t *new_event(void)
  120. {
  121. event_t *ret = xmalloc( sizeof(*ret) );
  122. memset( ret, 0, sizeof(*ret) );
  123. return ret;
  124. }
  125. raw_data_t *new_raw_data(void)
  126. {
  127. raw_data_t *ret = xmalloc( sizeof(*ret) );
  128. memset( ret, 0, sizeof(*ret) );
  129. return ret;
  130. }
  131. lvc_t *new_lvc(void)
  132. {
  133. lvc_t *ret = xmalloc( sizeof(*ret) );
  134. memset( ret, 0, sizeof(*ret) );
  135. return ret;
  136. }
  137. res_count_t *new_res_count(void)
  138. {
  139. res_count_t *ret = xmalloc( sizeof(*ret) );
  140. memset( ret, 0, sizeof(*ret) );
  141. return ret;
  142. }
  143. string_t *new_string(void)
  144. {
  145. string_t *ret = xmalloc( sizeof(*ret) );
  146. memset( ret, 0, sizeof(*ret) );
  147. set_location( &ret->loc );
  148. return ret;
  149. }
  150. toolbar_item_t *new_toolbar_item(void)
  151. {
  152. toolbar_item_t *ret = xmalloc( sizeof(*ret) );
  153. memset( ret, 0, sizeof(*ret) );
  154. return ret;
  155. }
  156. ani_any_t *new_ani_any(void)
  157. {
  158. ani_any_t *ret = xmalloc( sizeof(*ret) );
  159. memset( ret, 0, sizeof(*ret) );
  160. return ret;
  161. }
  162. resource_t *new_resource(enum res_e t, void *res, int memopt, language_t *lan)
  163. {
  164. resource_t *r = xmalloc(sizeof(resource_t));
  165. memset( r, 0, sizeof(*r) );
  166. r->type = t;
  167. r->res.overlay = res;
  168. r->memopt = memopt;
  169. r->lan = lan;
  170. return r;
  171. }
  172. version_t *new_version(DWORD v)
  173. {
  174. version_t *vp = xmalloc(sizeof(version_t));
  175. *vp = v;
  176. return vp;
  177. }
  178. characts_t *new_characts(DWORD c)
  179. {
  180. characts_t *cp = xmalloc(sizeof(characts_t));
  181. *cp = c;
  182. return cp;
  183. }
  184. language_t *new_language(int id, int sub)
  185. {
  186. language_t *lan = xmalloc(sizeof(language_t));
  187. lan->id = id;
  188. lan->sub = sub;
  189. return lan;
  190. }
  191. language_t *dup_language(language_t *l)
  192. {
  193. if(!l) return NULL;
  194. return new_language(l->id, l->sub);
  195. }
  196. version_t *dup_version(version_t *v)
  197. {
  198. if(!v) return NULL;
  199. return new_version(*v);
  200. }
  201. characts_t *dup_characts(characts_t *c)
  202. {
  203. if(!c) return NULL;
  204. return new_characts(*c);
  205. }
  206. html_t *new_html(raw_data_t *rd, int *memopt)
  207. {
  208. html_t *html = xmalloc(sizeof(html_t));
  209. html->data = rd;
  210. if(memopt)
  211. {
  212. html->memopt = *memopt;
  213. free(memopt);
  214. }
  215. else
  216. html->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
  217. return html;
  218. }
  219. rcdata_t *new_rcdata(raw_data_t *rd, int *memopt)
  220. {
  221. rcdata_t *rc = xmalloc(sizeof(rcdata_t));
  222. rc->data = rd;
  223. if(memopt)
  224. {
  225. rc->memopt = *memopt;
  226. free(memopt);
  227. }
  228. else
  229. rc->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
  230. return rc;
  231. }
  232. font_id_t *new_font_id(int size, string_t *face, int weight, int italic)
  233. {
  234. font_id_t *fid = xmalloc(sizeof(font_id_t));
  235. fid->name = face;
  236. fid->size = size;
  237. fid->weight = weight;
  238. fid->italic = italic;
  239. return fid;
  240. }
  241. user_t *new_user(name_id_t *type, raw_data_t *rd, int *memopt)
  242. {
  243. user_t *usr = xmalloc(sizeof(user_t));
  244. usr->data = rd;
  245. if(memopt)
  246. {
  247. usr->memopt = *memopt;
  248. free(memopt);
  249. }
  250. else
  251. usr->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
  252. usr->type = type;
  253. return usr;
  254. }
  255. font_t *new_font(raw_data_t *rd, int *memopt)
  256. {
  257. font_t *fnt = xmalloc(sizeof(font_t));
  258. fnt->data = rd;
  259. if(memopt)
  260. {
  261. fnt->memopt = *memopt;
  262. free(memopt);
  263. }
  264. else
  265. fnt->memopt = WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE;
  266. return fnt;
  267. }
  268. fontdir_t *new_fontdir(raw_data_t *rd, int *memopt)
  269. {
  270. fontdir_t *fnd = xmalloc(sizeof(fontdir_t));
  271. fnd->data = rd;
  272. if(memopt)
  273. {
  274. fnd->memopt = *memopt;
  275. free(memopt);
  276. }
  277. else
  278. fnd->memopt = WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE;
  279. return fnd;
  280. }
  281. /*
  282. * Convert bitmaps to proper endian
  283. */
  284. static void convert_bitmap_swap(BITMAPV5HEADER *bh, DWORD size)
  285. {
  286. bh->bV5Size = BYTESWAP_DWORD(bh->bV5Size);
  287. bh->bV5Width = BYTESWAP_DWORD(bh->bV5Width);
  288. bh->bV5Height = BYTESWAP_DWORD(bh->bV5Height);
  289. bh->bV5Planes = BYTESWAP_WORD(bh->bV5Planes);
  290. bh->bV5BitCount = BYTESWAP_WORD(bh->bV5BitCount);
  291. bh->bV5Compression = BYTESWAP_DWORD(bh->bV5Compression);
  292. bh->bV5SizeImage = BYTESWAP_DWORD(bh->bV5SizeImage);
  293. bh->bV5XPelsPerMeter = BYTESWAP_DWORD(bh->bV5XPelsPerMeter);
  294. bh->bV5YPelsPerMeter = BYTESWAP_DWORD(bh->bV5YPelsPerMeter);
  295. bh->bV5ClrUsed = BYTESWAP_DWORD(bh->bV5ClrUsed);
  296. bh->bV5ClrImportant = BYTESWAP_DWORD(bh->bV5ClrImportant);
  297. if (size == sizeof(BITMAPINFOHEADER)) return;
  298. bh->bV5RedMask = BYTESWAP_DWORD(bh->bV5RedMask);
  299. bh->bV5GreenMask = BYTESWAP_DWORD(bh->bV5GreenMask);
  300. bh->bV5BlueMask = BYTESWAP_DWORD(bh->bV5BlueMask);
  301. bh->bV5AlphaMask = BYTESWAP_DWORD(bh->bV5AlphaMask);
  302. bh->bV5CSType = BYTESWAP_DWORD(bh->bV5CSType);
  303. bh->bV5Endpoints.ciexyzRed.ciexyzX = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzRed.ciexyzX);
  304. bh->bV5Endpoints.ciexyzRed.ciexyzY = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzRed.ciexyzY);
  305. bh->bV5Endpoints.ciexyzRed.ciexyzZ = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzRed.ciexyzZ);
  306. bh->bV5Endpoints.ciexyzGreen.ciexyzX = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzGreen.ciexyzX);
  307. bh->bV5Endpoints.ciexyzGreen.ciexyzY = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzGreen.ciexyzY);
  308. bh->bV5Endpoints.ciexyzGreen.ciexyzZ = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzGreen.ciexyzZ);
  309. bh->bV5Endpoints.ciexyzBlue.ciexyzX = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzBlue.ciexyzX);
  310. bh->bV5Endpoints.ciexyzBlue.ciexyzY = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzBlue.ciexyzY);
  311. bh->bV5Endpoints.ciexyzBlue.ciexyzZ = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzBlue.ciexyzZ);
  312. bh->bV5GammaRed = BYTESWAP_DWORD(bh->bV5GammaRed);
  313. bh->bV5GammaGreen = BYTESWAP_DWORD(bh->bV5GammaGreen);
  314. bh->bV5GammaBlue = BYTESWAP_DWORD(bh->bV5GammaBlue);
  315. if (size == sizeof(BITMAPV4HEADER)) return;
  316. bh->bV5Intent = BYTESWAP_DWORD(bh->bV5Intent);
  317. bh->bV5ProfileData = BYTESWAP_DWORD(bh->bV5ProfileData);
  318. bh->bV5ProfileSize = BYTESWAP_DWORD(bh->bV5ProfileSize);
  319. bh->bV5Reserved = BYTESWAP_DWORD(bh->bV5Reserved);
  320. }
  321. static void convert_bitmap_swap_os2(BITMAPOS2HEADER *boh)
  322. {
  323. boh->biSize = BYTESWAP_DWORD(boh->biSize);
  324. boh->biWidth = BYTESWAP_WORD(boh->biWidth);
  325. boh->biHeight = BYTESWAP_WORD(boh->biHeight);
  326. boh->biPlanes = BYTESWAP_WORD(boh->biPlanes);
  327. boh->biBitCount = BYTESWAP_WORD(boh->biBitCount);
  328. }
  329. #define FL_SIGBE 0x01
  330. #define FL_SIZEBE 0x02
  331. static int convert_bitmap(char *data, int size)
  332. {
  333. BITMAPV5HEADER *bih = (BITMAPV5HEADER *)data;
  334. BITMAPOS2HEADER *boh = (BITMAPOS2HEADER *)data;
  335. DWORD bmsize;
  336. int type = 0;
  337. int returnSize = 0; /* size to be returned */
  338. /*
  339. * Originally the bih and b4h pointers were simply incremented here,
  340. * and memmoved at the end of the function. This causes alignment
  341. * issues on solaris, so we do the memmove here rather than at the end.
  342. */
  343. if(data[0] == 'B' && data[1] == 'M')
  344. {
  345. /* Little endian signature */
  346. memmove(data, data+sizeof(BITMAPFILEHEADER), size - sizeof(BITMAPFILEHEADER));
  347. returnSize = sizeof(BITMAPFILEHEADER);
  348. }
  349. else if(data[0] == 'M' && data[1] == 'B')
  350. {
  351. type |= FL_SIGBE; /* Big endian signature */
  352. memmove(data, data+sizeof(BITMAPFILEHEADER), size - sizeof(BITMAPFILEHEADER));
  353. returnSize = sizeof(BITMAPFILEHEADER);
  354. }
  355. bmsize = bih->bV5Size;
  356. switch (bmsize)
  357. {
  358. case sizeof(BITMAPOS2HEADER):
  359. case sizeof(BITMAPINFOHEADER):
  360. case sizeof(BITMAPV4HEADER):
  361. case sizeof(BITMAPV5HEADER):
  362. #ifdef WORDS_BIGENDIAN
  363. type |= FL_SIZEBE;
  364. #endif
  365. break;
  366. case BYTESWAP_DWORD( sizeof(BITMAPOS2HEADER) ):
  367. case BYTESWAP_DWORD( sizeof(BITMAPINFOHEADER) ):
  368. case BYTESWAP_DWORD( sizeof(BITMAPV4HEADER) ):
  369. case BYTESWAP_DWORD( sizeof(BITMAPV5HEADER) ):
  370. #ifndef WORDS_BIGENDIAN
  371. type |= FL_SIZEBE;
  372. #endif
  373. bmsize = BYTESWAP_DWORD( bmsize );
  374. break;
  375. case ICO_PNG_MAGIC:
  376. case BYTESWAP_DWORD( ICO_PNG_MAGIC ):
  377. return 0; /* nothing to convert */
  378. default:
  379. parser_error("Invalid bitmap format, bih->biSize = %d", bih->bV5Size);
  380. }
  381. switch(type)
  382. {
  383. case FL_SIZEBE:
  384. parser_warning("Bitmap signature little-endian, but size big-endian\n");
  385. break;
  386. case FL_SIGBE:
  387. parser_warning("Bitmap signature big-endian, but size little-endian\n");
  388. break;
  389. }
  390. switch(byteorder)
  391. {
  392. #ifdef WORDS_BIGENDIAN
  393. default:
  394. #endif
  395. case WRC_BO_BIG:
  396. if(!(type & FL_SIZEBE))
  397. {
  398. if (bmsize == sizeof(BITMAPOS2HEADER))
  399. convert_bitmap_swap_os2(boh);
  400. else
  401. convert_bitmap_swap(bih, bmsize);
  402. }
  403. break;
  404. #ifndef WORDS_BIGENDIAN
  405. default:
  406. #endif
  407. case WRC_BO_LITTLE:
  408. if(type & FL_SIZEBE)
  409. {
  410. if (bmsize == sizeof(BITMAPOS2HEADER))
  411. convert_bitmap_swap_os2(boh);
  412. else
  413. convert_bitmap_swap(bih, bmsize);
  414. }
  415. break;
  416. }
  417. if(size && (void *)data != (void *)bih)
  418. {
  419. /* We have the fileheader still attached, remove it */
  420. memmove(data, data+sizeof(BITMAPFILEHEADER), size - sizeof(BITMAPFILEHEADER));
  421. return sizeof(BITMAPFILEHEADER);
  422. }
  423. return returnSize;
  424. }
  425. #undef FL_SIGBE
  426. #undef FL_SIZEBE
  427. /*
  428. * Cursor and icon splitter functions used when allocating
  429. * cursor- and icon-groups.
  430. */
  431. typedef struct {
  432. language_t lan;
  433. int id;
  434. } id_alloc_t;
  435. static int get_new_id(id_alloc_t **list, int *n, language_t *lan)
  436. {
  437. int i;
  438. assert(lan != NULL);
  439. assert(list != NULL);
  440. assert(n != NULL);
  441. if(!*list)
  442. {
  443. *list = xmalloc(sizeof(id_alloc_t));
  444. *n = 1;
  445. (*list)[0].lan = *lan;
  446. (*list)[0].id = 1;
  447. return 1;
  448. }
  449. for(i = 0; i < *n; i++)
  450. {
  451. if((*list)[i].lan.id == lan->id && (*list)[i].lan.sub == lan->sub)
  452. return ++((*list)[i].id);
  453. }
  454. *list = xrealloc(*list, sizeof(id_alloc_t) * (*n+1));
  455. (*list)[*n].lan = *lan;
  456. (*list)[*n].id = 1;
  457. *n += 1;
  458. return 1;
  459. }
  460. static int alloc_icon_id(language_t *lan)
  461. {
  462. static id_alloc_t *idlist = NULL;
  463. static int nid = 0;
  464. return get_new_id(&idlist, &nid, lan);
  465. }
  466. static int alloc_cursor_id(language_t *lan)
  467. {
  468. static id_alloc_t *idlist = NULL;
  469. static int nid = 0;
  470. return get_new_id(&idlist, &nid, lan);
  471. }
  472. static void split_icons(raw_data_t *rd, icon_group_t *icog, int *nico)
  473. {
  474. int cnt;
  475. int i;
  476. icon_t *ico;
  477. icon_t *list = NULL;
  478. icon_header_t *ih = (icon_header_t *)rd->data;
  479. int swap = 0;
  480. if(ih->type == 1)
  481. swap = 0;
  482. else if(BYTESWAP_WORD(ih->type) == 1)
  483. swap = 1;
  484. else
  485. parser_error("Icon resource data has invalid type id %d", ih->type);
  486. cnt = swap ? BYTESWAP_WORD(ih->count) : ih->count;
  487. for(i = 0; i < cnt; i++)
  488. {
  489. icon_dir_entry_t ide;
  490. BITMAPINFOHEADER info;
  491. memcpy(&ide, rd->data + sizeof(icon_header_t)
  492. + i*sizeof(icon_dir_entry_t), sizeof(ide));
  493. ico = new_icon();
  494. ico->id = alloc_icon_id(icog->lvc.language);
  495. ico->lvc = icog->lvc;
  496. if(swap)
  497. {
  498. ide.offset = BYTESWAP_DWORD(ide.offset);
  499. ide.ressize= BYTESWAP_DWORD(ide.ressize);
  500. }
  501. if(ide.offset > rd->size
  502. || ide.offset + ide.ressize > rd->size)
  503. parser_error("Icon resource data corrupt");
  504. ico->width = ide.width;
  505. ico->height = ide.height;
  506. ico->nclr = ide.nclr;
  507. ico->planes = swap ? BYTESWAP_WORD(ide.planes) : ide.planes;
  508. ico->bits = swap ? BYTESWAP_WORD(ide.bits) : ide.bits;
  509. memcpy(&info, rd->data + ide.offset, sizeof(info));
  510. convert_bitmap((char *) &info, 0);
  511. memcpy(rd->data + ide.offset, &info, sizeof(info));
  512. if(!ico->planes)
  513. {
  514. /* Argh! They did not fill out the resdir structure */
  515. /* The bitmap is in destination byteorder. We want native for our structures */
  516. switch(byteorder)
  517. {
  518. #ifdef WORDS_BIGENDIAN
  519. case WRC_BO_LITTLE:
  520. #else
  521. case WRC_BO_BIG:
  522. #endif
  523. ico->planes = BYTESWAP_WORD(info.biPlanes);
  524. break;
  525. default:
  526. ico->planes = info.biPlanes;
  527. }
  528. }
  529. if(!ico->bits)
  530. {
  531. /* Argh! They did not fill out the resdir structure */
  532. /* The bitmap is in destination byteorder. We want native for our structures */
  533. switch(byteorder)
  534. {
  535. #ifdef WORDS_BIGENDIAN
  536. case WRC_BO_LITTLE:
  537. #else
  538. case WRC_BO_BIG:
  539. #endif
  540. ico->bits = BYTESWAP_WORD(info.biBitCount);
  541. break;
  542. default:
  543. ico->bits = info.biBitCount;
  544. }
  545. }
  546. ico->data = new_raw_data();
  547. copy_raw_data(ico->data, rd, ide.offset, ide.ressize);
  548. if(!list)
  549. {
  550. list = ico;
  551. }
  552. else
  553. {
  554. ico->next = list;
  555. list->prev = ico;
  556. list = ico;
  557. }
  558. }
  559. icog->iconlist = list;
  560. *nico = cnt;
  561. }
  562. static void split_cursors(raw_data_t *rd, cursor_group_t *curg, int *ncur)
  563. {
  564. int cnt;
  565. int i;
  566. cursor_t *cur;
  567. cursor_t *list = NULL;
  568. cursor_header_t *ch = (cursor_header_t *)rd->data;
  569. int swap = 0;
  570. if(ch->type == 2)
  571. swap = 0;
  572. else if(BYTESWAP_WORD(ch->type) == 2)
  573. swap = 1;
  574. else
  575. parser_error("Cursor resource data has invalid type id %d", ch->type);
  576. cnt = swap ? BYTESWAP_WORD(ch->count) : ch->count;
  577. for(i = 0; i < cnt; i++)
  578. {
  579. cursor_dir_entry_t cde;
  580. BITMAPINFOHEADER info;
  581. memcpy(&cde, rd->data + sizeof(cursor_header_t)
  582. + i*sizeof(cursor_dir_entry_t), sizeof(cde));
  583. cur = new_cursor();
  584. cur->id = alloc_cursor_id(curg->lvc.language);
  585. cur->lvc = curg->lvc;
  586. if(swap)
  587. {
  588. cde.offset = BYTESWAP_DWORD(cde.offset);
  589. cde.ressize= BYTESWAP_DWORD(cde.ressize);
  590. }
  591. if(cde.offset > rd->size
  592. || cde.offset + cde.ressize > rd->size)
  593. parser_error("Cursor resource data corrupt");
  594. cur->width = cde.width;
  595. cur->height = cde.height;
  596. cur->nclr = cde.nclr;
  597. memcpy(&info, rd->data + cde.offset, sizeof(info));
  598. convert_bitmap((char *)&info, 0);
  599. memcpy(rd->data + cde.offset, &info, sizeof(info));
  600. /* The bitmap is in destination byteorder. We want native for our structures */
  601. switch(byteorder)
  602. {
  603. #ifdef WORDS_BIGENDIAN
  604. case WRC_BO_LITTLE:
  605. #else
  606. case WRC_BO_BIG:
  607. #endif
  608. cur->planes = BYTESWAP_WORD(info.biPlanes);
  609. cur->bits = BYTESWAP_WORD(info.biBitCount);
  610. break;
  611. default:
  612. cur->planes = info.biPlanes;
  613. cur->bits = info.biBitCount;
  614. }
  615. if(!win32 && (cur->planes != 1 || cur->bits != 1))
  616. parser_warning("Win16 cursor contains colors\n");
  617. cur->xhot = swap ? BYTESWAP_WORD(cde.xhot) : cde.xhot;
  618. cur->yhot = swap ? BYTESWAP_WORD(cde.yhot) : cde.yhot;
  619. cur->data = new_raw_data();
  620. copy_raw_data(cur->data, rd, cde.offset, cde.ressize);
  621. if(!list)
  622. {
  623. list = cur;
  624. }
  625. else
  626. {
  627. cur->next = list;
  628. list->prev = cur;
  629. list = cur;
  630. }
  631. }
  632. curg->cursorlist = list;
  633. *ncur = cnt;
  634. }
  635. icon_group_t *new_icon_group(raw_data_t *rd, int *memopt)
  636. {
  637. icon_group_t *icog = xmalloc(sizeof(icon_group_t));
  638. if(memopt)
  639. {
  640. icog->memopt = *memopt;
  641. free(memopt);
  642. }
  643. else
  644. icog->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE | WRC_MO_DISCARDABLE;
  645. icog->lvc = rd->lvc;
  646. split_icons(rd, icog, &(icog->nicon));
  647. free(rd->data);
  648. free(rd);
  649. return icog;
  650. }
  651. cursor_group_t *new_cursor_group(raw_data_t *rd, int *memopt)
  652. {
  653. cursor_group_t *curg = xmalloc(sizeof(cursor_group_t));
  654. if(memopt)
  655. {
  656. curg->memopt = *memopt;
  657. free(memopt);
  658. }
  659. else
  660. curg->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE | WRC_MO_DISCARDABLE;
  661. curg->lvc = rd->lvc;
  662. split_cursors(rd, curg, &(curg->ncursor));
  663. free(rd->data);
  664. free(rd);
  665. return curg;
  666. }
  667. /*
  668. * Animated cursors and icons
  669. *
  670. * The format of animated cursors and icons is yet another example
  671. * of bad design by "The Company". The entire RIFF structure is
  672. * flawed by design because it is inconsistent and single minded:
  673. * - some tags have lengths attached, others don't. The use of these
  674. * non-length tags is absolutely unclear;
  675. * - the content of "icon" tags can be both icons and cursors;
  676. * - tags lack proper alignment constraints. It seems that everything
  677. * is 16bit aligned, but I could not find that in any docu. Just be
  678. * prepared to eat anything;
  679. * - there are no strict constraints on tag-nesting and the organization
  680. * is highly illogical;
  681. *
  682. * Anyhow, here is the basic structure:
  683. * "RIFF" { dword taglength }
  684. * "ACON" // What does it do?
  685. * "LIST" { dword taglength }
  686. * "INFO" // And what does this do?
  687. * "INAM" { dword taglength } // Icon/cursor name
  688. * {inam data}
  689. * "IART" { dword taglength } // The artist
  690. * {iart data}
  691. * "fram" // Is followed by "icon"s
  692. * "icon" { dword taglength } // First frame
  693. * { icon/cursor data }
  694. * "icon" { dword taglength } // Second frame
  695. * { icon/cursor data }
  696. * ... // ...
  697. * "anih" { dword taglength } // Header structure
  698. * { aniheader_t structure }
  699. * "rate" { dword taglength } // The rate for each frame
  700. * { `steps' dwords }
  701. * "seq " { dword taglength } // The frame blit-order
  702. * { `steps' dwords }
  703. *
  704. * Tag length are bytelength without the header and length field (i.e. -8).
  705. * The "LIST" tag may occur several times and may encapsulate different
  706. * tags. The `steps' is the number of "icon" tags found (actually the
  707. * number of steps specified in the aniheader_t structure). The "seq "uence
  708. * tag can be omitted, in which case the sequence is equal to the sequence
  709. * of "icon"s found in the file. Also "rate" may be omitted, in which case
  710. * the default from the aniheader_t structure is used.
  711. *
  712. * An animated cursor puts `.cur' formatted files into each "icon" tag,
  713. * whereas animated icons contain `.ico' formatted files.
  714. *
  715. * Note about the code: Yes, it can be shorter/compressed. Some tags can be
  716. * dealt with in the same code. However, this version shows what is going on
  717. * and is better debug-able.
  718. */
  719. static const char riff[4] = "RIFF";
  720. static const char acon[4] = "ACON";
  721. static const char list[4] = "LIST";
  722. static const char info[4] = "INFO";
  723. static const char inam[4] = "INAM";
  724. static const char iart[4] = "IART";
  725. static const char fram[4] = "fram";
  726. static const char icon[4] = "icon";
  727. static const char anih[4] = "anih";
  728. static const char rate[4] = "rate";
  729. static const char seq[4] = "seq ";
  730. #define SKIP_TAG(p,size) ((riff_tag_t *)(((char *)p) + (size)))
  731. #define NEXT_TAG(p) SKIP_TAG(p,(isswapped ? BYTESWAP_DWORD(p->size) : p->size) + sizeof(*p))
  732. static void handle_ani_icon(riff_tag_t *rtp, enum res_e type, int isswapped)
  733. {
  734. cursor_dir_entry_t *cdp;
  735. cursor_header_t *chp;
  736. int count;
  737. int ctype;
  738. int i;
  739. static int once = 0; /* This will trigger only once per file! */
  740. const char *anistr = type == res_aniico ? "icon" : "cursor";
  741. /* Notes:
  742. * Both cursor and icon directories are similar
  743. * Both cursor and icon headers are similar
  744. */
  745. chp = (cursor_header_t *)(rtp+1);
  746. cdp = (cursor_dir_entry_t *)(chp+1);
  747. count = isswapped ? BYTESWAP_WORD(chp->count) : chp->count;
  748. ctype = isswapped ? BYTESWAP_WORD(chp->type) : chp->type;
  749. chp->reserved = BYTESWAP_WORD(chp->reserved);
  750. chp->type = BYTESWAP_WORD(chp->type);
  751. chp->count = BYTESWAP_WORD(chp->count);
  752. if(type == res_anicur && ctype != 2 && !once)
  753. {
  754. parser_warning("Animated cursor contains invalid \"icon\" tag cursor-file (%d->%s)\n",
  755. ctype,
  756. ctype == 1 ? "icontype" : "?");
  757. once++;
  758. }
  759. else if(type == res_aniico && ctype != 1 && !once)
  760. {
  761. parser_warning("Animated icon contains invalid \"icon\" tag icon-file (%d->%s)\n",
  762. ctype,
  763. ctype == 2 ? "cursortype" : "?");
  764. once++;
  765. }
  766. else if(ctype != 1 && ctype != 2 && !once)
  767. {
  768. parser_warning("Animated %s contains invalid \"icon\" tag file-type (%d; neither icon nor cursor)\n", anistr, ctype);
  769. once++;
  770. }
  771. for(i = 0; i < count; i++)
  772. {
  773. DWORD ofs = isswapped ? BYTESWAP_DWORD(cdp[i].offset) : cdp[i].offset;
  774. DWORD sze = isswapped ? BYTESWAP_DWORD(cdp[i].ressize) : cdp[i].ressize;
  775. if(ofs > rtp->size || ofs+sze > rtp->size)
  776. parser_error("Animated %s's data corrupt", anistr);
  777. convert_bitmap((char *)chp + ofs, 0);
  778. cdp[i].xhot = BYTESWAP_WORD(cdp->xhot);
  779. cdp[i].yhot = BYTESWAP_WORD(cdp->yhot);
  780. cdp[i].ressize = BYTESWAP_DWORD(cdp->ressize);
  781. cdp[i].offset = BYTESWAP_DWORD(cdp->offset);
  782. }
  783. }
  784. static void handle_ani_list(riff_tag_t *lst, enum res_e type, int isswapped)
  785. {
  786. riff_tag_t *rtp = lst+1; /* Skip the "LIST" tag */
  787. while((char *)rtp < (char *)lst + lst->size + sizeof(*lst))
  788. {
  789. if(!memcmp(rtp->tag, info, sizeof(info)))
  790. {
  791. rtp = SKIP_TAG(rtp,4);
  792. }
  793. else if(!memcmp(rtp->tag, inam, sizeof(inam)))
  794. {
  795. /* Ignore the icon/cursor name; it's a string */
  796. rtp = NEXT_TAG(rtp);
  797. }
  798. else if(!memcmp(rtp->tag, iart, sizeof(iart)))
  799. {
  800. /* Ignore the author's name; it's a string */
  801. rtp = NEXT_TAG(rtp);
  802. }
  803. else if(!memcmp(rtp->tag, fram, sizeof(fram)))
  804. {
  805. /* This should be followed by "icon"s, but we
  806. * simply ignore this because it is pure
  807. * non-information.
  808. */
  809. rtp = SKIP_TAG(rtp,4);
  810. }
  811. else if(!memcmp(rtp->tag, icon, sizeof(icon)))
  812. {
  813. handle_ani_icon(rtp, type, isswapped);
  814. rtp = NEXT_TAG(rtp);
  815. }
  816. else
  817. internal_error(__FILE__, __LINE__, "Unknown tag \"%c%c%c%c\" in RIFF file\n",
  818. isprint(rtp->tag[0]) ? rtp->tag[0] : '.',
  819. isprint(rtp->tag[1]) ? rtp->tag[1] : '.',
  820. isprint(rtp->tag[2]) ? rtp->tag[2] : '.',
  821. isprint(rtp->tag[3]) ? rtp->tag[3] : '.');
  822. if((UINT_PTR)rtp & 1)
  823. rtp = SKIP_TAG(rtp,1);
  824. }
  825. }
  826. ani_curico_t *new_ani_curico(enum res_e type, raw_data_t *rd, int *memopt)
  827. {
  828. ani_curico_t *ani = xmalloc(sizeof(ani_curico_t));
  829. riff_tag_t *rtp;
  830. int isswapped = 0;
  831. int doswap;
  832. const char *anistr = type == res_aniico ? "icon" : "cursor";
  833. assert(!memcmp(rd->data, riff, sizeof(riff)));
  834. assert(type == res_anicur || type == res_aniico);
  835. rtp = (riff_tag_t *)rd->data;
  836. if(BYTESWAP_DWORD(rtp->size) + 2*sizeof(DWORD) == rd->size)
  837. isswapped = 1;
  838. else if(rtp->size + 2*sizeof(DWORD) == rd->size)
  839. isswapped = 0;
  840. else
  841. parser_error("Animated %s has an invalid RIFF length", anistr);
  842. switch(byteorder)
  843. {
  844. #ifdef WORDS_BIGENDIAN
  845. case WRC_BO_LITTLE:
  846. #else
  847. case WRC_BO_BIG:
  848. #endif
  849. doswap = !isswapped;
  850. break;
  851. default:
  852. doswap = isswapped;
  853. }
  854. /*
  855. * When to swap what:
  856. * isswapped | doswap |
  857. * ----------+--------+---------------------------------
  858. * 0 | 0 | read native; don't convert
  859. * 1 | 0 | read swapped size; don't convert
  860. * 0 | 1 | read native; convert
  861. * 1 | 1 | read swapped size; convert
  862. * Reading swapped size if necessary to calculate in native
  863. * format. E.g. a little-endian source on a big-endian
  864. * processor.
  865. */
  866. if(doswap)
  867. {
  868. /* We only go through the RIFF file if we need to swap
  869. * bytes in words/dwords. Else we couldn't care less
  870. * what the file contains. This is consistent with
  871. * MS' rc.exe, which doesn't complain at all, even though
  872. * the file format might not be entirely correct.
  873. */
  874. rtp++; /* Skip the "RIFF" tag */
  875. while((char *)rtp < (char *)rd->data + rd->size)
  876. {
  877. if(!memcmp(rtp->tag, acon, sizeof(acon)))
  878. {
  879. rtp = SKIP_TAG(rtp,4);
  880. }
  881. else if(!memcmp(rtp->tag, list, sizeof(list)))
  882. {
  883. handle_ani_list(rtp, type, isswapped);
  884. rtp = NEXT_TAG(rtp);
  885. }
  886. else if(!memcmp(rtp->tag, anih, sizeof(anih)))
  887. {
  888. aniheader_t *ahp = (aniheader_t *)((char *)(rtp+1));
  889. ahp->structsize = BYTESWAP_DWORD(ahp->structsize);
  890. ahp->frames = BYTESWAP_DWORD(ahp->frames);
  891. ahp->steps = BYTESWAP_DWORD(ahp->steps);
  892. ahp->cx = BYTESWAP_DWORD(ahp->cx);
  893. ahp->cy = BYTESWAP_DWORD(ahp->cy);
  894. ahp->bitcount = BYTESWAP_DWORD(ahp->bitcount);
  895. ahp->planes = BYTESWAP_DWORD(ahp->planes);
  896. ahp->rate = BYTESWAP_DWORD(ahp->rate);
  897. ahp->flags = BYTESWAP_DWORD(ahp->flags);
  898. rtp = NEXT_TAG(rtp);
  899. }
  900. else if(!memcmp(rtp->tag, rate, sizeof(rate)))
  901. {
  902. int cnt = rtp->size / sizeof(DWORD);
  903. DWORD *dwp = (DWORD *)(rtp+1);
  904. int i;
  905. for(i = 0; i < cnt; i++)
  906. dwp[i] = BYTESWAP_DWORD(dwp[i]);
  907. rtp = NEXT_TAG(rtp);
  908. }
  909. else if(!memcmp(rtp->tag, seq, sizeof(seq)))
  910. {
  911. int cnt = rtp->size / sizeof(DWORD);
  912. DWORD *dwp = (DWORD *)(rtp+1);
  913. int i;
  914. for(i = 0; i < cnt; i++)
  915. dwp[i] = BYTESWAP_DWORD(dwp[i]);
  916. rtp = NEXT_TAG(rtp);
  917. }
  918. else
  919. internal_error(__FILE__, __LINE__, "Unknown tag \"%c%c%c%c\" in RIFF file\n",
  920. isprint(rtp->tag[0]) ? rtp->tag[0] : '.',
  921. isprint(rtp->tag[1]) ? rtp->tag[1] : '.',
  922. isprint(rtp->tag[2]) ? rtp->tag[2] : '.',
  923. isprint(rtp->tag[3]) ? rtp->tag[3] : '.');
  924. if((UINT_PTR)rtp & 1)
  925. rtp = SKIP_TAG(rtp,1);
  926. }
  927. /* We must end correctly here */
  928. if((char *)rtp != (char *)rd->data + rd->size)
  929. parser_error("Animated %s contains invalid field size(s)", anistr);
  930. }
  931. ani->data = rd;
  932. if(memopt)
  933. {
  934. ani->memopt = *memopt;
  935. free(memopt);
  936. }
  937. else
  938. ani->memopt = WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE;
  939. return ani;
  940. }
  941. #undef NEXT_TAG
  942. /* Bitmaps */
  943. bitmap_t *new_bitmap(raw_data_t *rd, int *memopt)
  944. {
  945. bitmap_t *bmp = xmalloc(sizeof(bitmap_t));
  946. bmp->data = rd;
  947. if(memopt)
  948. {
  949. bmp->memopt = *memopt;
  950. free(memopt);
  951. }
  952. else
  953. bmp->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
  954. rd->size -= convert_bitmap(rd->data, rd->size);
  955. return bmp;
  956. }
  957. ver_words_t *new_ver_words(int i)
  958. {
  959. ver_words_t *w = xmalloc(sizeof(ver_words_t));
  960. w->words = xmalloc(sizeof(WORD));
  961. w->words[0] = (WORD)i;
  962. w->nwords = 1;
  963. return w;
  964. }
  965. ver_words_t *add_ver_words(ver_words_t *w, int i)
  966. {
  967. w->words = xrealloc(w->words, (w->nwords+1) * sizeof(WORD));
  968. w->words[w->nwords] = (WORD)i;
  969. w->nwords++;
  970. return w;
  971. }
  972. #define MSGTAB_BAD_PTR(p, b, l, r) (((l) - ((char *)(p) - (char *)(b))) > (r))
  973. messagetable_t *new_messagetable(raw_data_t *rd, int *memopt)
  974. {
  975. messagetable_t *msg = xmalloc(sizeof(messagetable_t));
  976. msgtab_block_t *mbp;
  977. DWORD nblk;
  978. DWORD i;
  979. WORD lo;
  980. WORD hi;
  981. msg->data = rd;
  982. if(memopt)
  983. {
  984. msg->memopt = *memopt;
  985. free(memopt);
  986. }
  987. else
  988. msg->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
  989. if(rd->size < sizeof(DWORD))
  990. parser_error("Invalid messagetable, size too small");
  991. nblk = *(DWORD *)rd->data;
  992. lo = WRC_LOWORD(nblk);
  993. hi = WRC_HIWORD(nblk);
  994. /* FIXME:
  995. * This test will fail for all n*2^16 blocks in the messagetable.
  996. * However, no sane person would want to have so many blocks
  997. * and have a table of megabytes attached.
  998. * So, I will assume that we have less than 2^16 blocks in the table
  999. * and all will just work out fine. Otherwise, we would need to test
  1000. * the ID, offset and length (and flag) fields to be very sure.
  1001. */
  1002. if(hi && lo)
  1003. internal_error(__FILE__, __LINE__, "Messagetable contains more than 65535 blocks; cannot determine endian\n");
  1004. if(!hi && !lo)
  1005. parser_error("Invalid messagetable block count 0");
  1006. if(!hi && lo) /* Messagetable byteorder == native byteorder */
  1007. {
  1008. #ifdef WORDS_BIGENDIAN
  1009. if(byteorder != WRC_BO_LITTLE) goto out;
  1010. #else
  1011. if(byteorder != WRC_BO_BIG) goto out;
  1012. #endif
  1013. /* Resource byteorder != native byteorder */
  1014. mbp = (msgtab_block_t *)&(((DWORD *)rd->data)[1]);
  1015. if(MSGTAB_BAD_PTR(mbp, rd->data, rd->size, nblk * sizeof(*mbp)))
  1016. parser_error("Messagetable's blocks are outside of defined data");
  1017. for(i = 0; i < nblk; i++)
  1018. {
  1019. msgtab_entry_t *mep, *next_mep;
  1020. DWORD id;
  1021. mep = (msgtab_entry_t *)(((char *)rd->data) + mbp[i].offset);
  1022. for(id = mbp[i].idlo; id <= mbp[i].idhi; id++)
  1023. {
  1024. if(MSGTAB_BAD_PTR(mep, rd->data, rd->size, mep->length))
  1025. parser_error("Messagetable's data for block %d, ID 0x%08x is outside of defined data", i, id);
  1026. if(mep->flags == 1) /* Docu says 'flags == 0x0001' for unicode */
  1027. {
  1028. WORD *wp = (WORD *)&mep[1];
  1029. int l = mep->length/2 - 2; /* Length included header */
  1030. int n;
  1031. if(mep->length & 1)
  1032. parser_error("Message 0x%08x is unicode (block %d), but has odd length (%d)", id, i, mep->length);
  1033. for(n = 0; n < l; n++)
  1034. wp[n] = BYTESWAP_WORD(wp[n]);
  1035. }
  1036. next_mep = (msgtab_entry_t *)(((char *)mep) + mep->length);
  1037. mep->length = BYTESWAP_WORD(mep->length);
  1038. mep->flags = BYTESWAP_WORD(mep->flags);
  1039. mep = next_mep;
  1040. }
  1041. mbp[i].idlo = BYTESWAP_DWORD(mbp[i].idlo);
  1042. mbp[i].idhi = BYTESWAP_DWORD(mbp[i].idhi);
  1043. mbp[i].offset = BYTESWAP_DWORD(mbp[i].offset);
  1044. }
  1045. }
  1046. if(hi && !lo) /* Messagetable byteorder != native byteorder */
  1047. {
  1048. #ifdef WORDS_BIGENDIAN
  1049. if(byteorder == WRC_BO_LITTLE) goto out;
  1050. #else
  1051. if(byteorder == WRC_BO_BIG) goto out;
  1052. #endif
  1053. /* Resource byteorder == native byteorder */
  1054. mbp = (msgtab_block_t *)&(((DWORD *)rd->data)[1]);
  1055. nblk = BYTESWAP_DWORD(nblk);
  1056. if(MSGTAB_BAD_PTR(mbp, rd->data, rd->size, nblk * sizeof(*mbp)))
  1057. parser_error("Messagetable's blocks are outside of defined data");
  1058. for(i = 0; i < nblk; i++)
  1059. {
  1060. msgtab_entry_t *mep;
  1061. DWORD id;
  1062. mbp[i].idlo = BYTESWAP_DWORD(mbp[i].idlo);
  1063. mbp[i].idhi = BYTESWAP_DWORD(mbp[i].idhi);
  1064. mbp[i].offset = BYTESWAP_DWORD(mbp[i].offset);
  1065. mep = (msgtab_entry_t *)(((char *)rd->data) + mbp[i].offset);
  1066. for(id = mbp[i].idlo; id <= mbp[i].idhi; id++)
  1067. {
  1068. mep->length = BYTESWAP_WORD(mep->length);
  1069. mep->flags = BYTESWAP_WORD(mep->flags);
  1070. if(MSGTAB_BAD_PTR(mep, rd->data, rd->size, mep->length))
  1071. parser_error("Messagetable's data for block %d, ID 0x%08x is outside of defined data", i, id);
  1072. if(mep->flags == 1) /* Docu says 'flags == 0x0001' for unicode */
  1073. {
  1074. WORD *wp = (WORD *)&mep[1];
  1075. int l = mep->length/2 - 2; /* Length included header */
  1076. int n;
  1077. if(mep->length & 1)
  1078. parser_error("Message 0x%08x is unicode (block %d), but has odd length (%d)", id, i, mep->length);
  1079. for(n = 0; n < l; n++)
  1080. wp[n] = BYTESWAP_WORD(wp[n]);
  1081. }
  1082. mep = (msgtab_entry_t *)(((char *)mep) + mep->length);
  1083. }
  1084. }
  1085. }
  1086. out:
  1087. return msg;
  1088. }
  1089. #undef MSGTAB_BAD_PTR
  1090. void copy_raw_data(raw_data_t *dst, raw_data_t *src, unsigned int offs, int len)
  1091. {
  1092. assert(offs <= src->size);
  1093. assert(offs + len <= src->size);
  1094. if(!dst->data)
  1095. {
  1096. dst->data = xmalloc(len);
  1097. dst->size = 0;
  1098. }
  1099. else
  1100. dst->data = xrealloc(dst->data, dst->size + len);
  1101. /* dst->size holds the offset to copy to */
  1102. memcpy(dst->data + dst->size, src->data + offs, len);
  1103. dst->size += len;
  1104. }
  1105. int *new_int(int i)
  1106. {
  1107. int *ip = xmalloc(sizeof(int));
  1108. *ip = i;
  1109. return ip;
  1110. }
  1111. stringtable_t *new_stringtable(lvc_t *lvc)
  1112. {
  1113. stringtable_t *stt = xmalloc(sizeof(stringtable_t));
  1114. memset( stt, 0, sizeof(*stt) );
  1115. if(lvc)
  1116. stt->lvc = *lvc;
  1117. return stt;
  1118. }
  1119. toolbar_t *new_toolbar(int button_width, int button_height, toolbar_item_t *items, int nitems)
  1120. {
  1121. toolbar_t *tb = xmalloc(sizeof(toolbar_t));
  1122. memset( tb, 0, sizeof(*tb) );
  1123. tb->button_width = button_width;
  1124. tb->button_height = button_height;
  1125. tb->nitems = nitems;
  1126. tb->items = items;
  1127. return tb;
  1128. }
  1129. dlginit_t *new_dlginit(raw_data_t *rd, int *memopt)
  1130. {
  1131. dlginit_t *di = xmalloc(sizeof(dlginit_t));
  1132. di->data = rd;
  1133. if(memopt)
  1134. {
  1135. di->memopt = *memopt;
  1136. free(memopt);
  1137. }
  1138. else
  1139. di->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE | WRC_MO_DISCARDABLE;
  1140. return di;
  1141. }
  1142. style_pair_t *new_style_pair(style_t *style, style_t *exstyle)
  1143. {
  1144. style_pair_t *sp = xmalloc(sizeof(style_pair_t));
  1145. sp->style = style;
  1146. sp->exstyle = exstyle;
  1147. return sp;
  1148. }
  1149. style_t *new_style(DWORD or_mask, DWORD and_mask)
  1150. {
  1151. style_t *st = xmalloc(sizeof(style_t));
  1152. st->or_mask = or_mask;
  1153. st->and_mask = and_mask;
  1154. return st;
  1155. }