Added __wine_get_main_args to retrieve command-line arguments for the
[wine/multimedia.git] / tools / wrc / readres.c
blobd57c42f3dbf09657a0eedd199776ad20718277f0
1 /*
2 * Read a .res file and create a resource-tree
4 * Copyright 1998 Bertho A. Stultiens
6 */
8 #include "config.h"
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <assert.h>
15 #include "wrc.h"
16 #include "readres.h"
17 #include "newstruc.h"
18 #include "utils.h"
19 #include "genres.h"
21 struct resheader32 {
22 DWORD ressize; /* 0 */
23 DWORD hdrsize; /* 0x20 */
24 WORD restype1; /* 0xffff */
25 WORD restype2; /* 0 */
26 WORD resname1; /* 0xffff */
27 WORD resname2; /* 0 */
28 DWORD dversion; /* 0 */
29 WORD memopt; /* 0 */
30 WORD language; /* 0 */
31 DWORD version; /* 0 */
32 DWORD characts; /* 0 */
33 } emptyheader = {0, 0x20, 0xffff, 0, 0xffff, 0, 0, 0, 0, 0, 0},
34 emptyheaderSWAPPED = {0, BYTESWAP_DWORD(0x20), 0xffff, 0, 0xffff, 0, 0, 0, 0, 0, 0};
37 *****************************************************************************
38 * Function :
39 * Syntax :
40 * Input :
41 * Output :
42 * Description :
43 * Remarks :
44 *****************************************************************************
47 *****************************************************************************
48 * Function :
49 * Syntax :
50 * Input :
51 * Output :
52 * Description :
53 * Remarks :
54 *****************************************************************************
57 *****************************************************************************
58 * Function :
59 * Syntax :
60 * Input :
61 * Output :
62 * Description :
63 * Remarks :
64 *****************************************************************************
66 int read_data(FILE *fp, size_t size, void *buf)
68 int r;
69 int pos = ftell(fp);
70 r = fread(buf, 1, size, fp);
71 if(r == size)
72 return 0;
73 if(r == 0 && ftell(fp) - pos > 0)
74 return 1;
75 else
76 return -1;
80 *****************************************************************************
81 * Function :
82 * Syntax :
83 * Input :
84 * Output :
85 * Description :
86 * Remarks :
87 *****************************************************************************
89 enum res_e res_type_from_id(name_id_t *nid)
91 if(nid->type == name_str)
92 return res_usr;
94 if(nid->type != name_ord)
95 internal_error(__FILE__, __LINE__, "Invalid name_id descriptor %d", nid->type);
97 switch(nid->name.i_name)
99 case WRC_RT_CURSOR: return res_cur;
100 case WRC_RT_BITMAP: return res_bmp;
101 case WRC_RT_ICON: return res_ico;
102 case WRC_RT_MENU: return res_men;
103 case WRC_RT_DIALOG: return res_dlg;
104 case WRC_RT_STRING: return res_stt;
105 case WRC_RT_FONTDIR: return res_fntdir;
106 case WRC_RT_FONT: return res_fnt;
107 case WRC_RT_ACCELERATOR: return res_acc;
108 case WRC_RT_RCDATA: return res_rdt;
109 case WRC_RT_MESSAGETABLE: return res_msg;
110 case WRC_RT_GROUP_CURSOR: return res_curg;
111 case WRC_RT_GROUP_ICON: return res_icog;
112 case WRC_RT_VERSION: return res_ver;
113 case WRC_RT_TOOLBAR: return res_toolbar;
115 default:
116 case WRC_RT_DLGINCLUDE:
117 case WRC_RT_PLUGPLAY:
118 case WRC_RT_VXD:
119 case WRC_RT_ANICURSOR:
120 case WRC_RT_ANIICON:
121 warning("Cannot be sure of resource type, using usertype settings");
122 return res_usr;
127 *****************************************************************************
128 * Function :
129 * Syntax :
130 * Input :
131 * Output :
132 * Description :
133 * Remarks :
134 *****************************************************************************
136 #define get_word(idx) (*((WORD *)(&res->data[idx])))
137 #define get_dword(idx) (*((DWORD *)(&res->data[idx])))
139 static resource_t *read_res32(FILE *fp)
141 static char wrong_format[] = "Wrong resfile format (32bit)";
142 DWORD ressize;
143 DWORD hdrsize;
144 DWORD totsize;
145 WORD memopt;
146 WORD language;
147 int err;
148 res_t *res;
149 resource_t *rsc;
150 resource_t *tail = NULL;
151 resource_t *list = NULL;
152 name_id_t *type = NULL;
153 name_id_t *name = NULL;
154 int idx;
155 enum res_e res_type;
156 user_t *usrres;
158 while(1)
160 /* Get headersize and resource size */
161 err = read_data(fp, sizeof(ressize), &ressize);
162 if(err < 0)
163 break;
164 else if(err > 0)
165 error(wrong_format);
166 err = read_data(fp, sizeof(hdrsize), &hdrsize);
167 if(err)
168 error(wrong_format);
170 /* Align sizes and compute total size */
171 totsize = hdrsize;
172 if(hdrsize & 3)
174 warning("Hu? .res header needed alignment (anything can happen now)");
175 totsize += 4 - (hdrsize & 3);
177 totsize += ressize;
178 if(ressize & 3)
179 totsize += 4 - (ressize & 3);
181 /* Read in entire data-block */
182 fseek(fp, -8, SEEK_CUR);
183 res = new_res();
184 if(res->allocsize < totsize)
185 grow_res(res, totsize - res->allocsize + 8);
186 err = read_data(fp, totsize, res->data);
187 if(err)
188 error(wrong_format);
190 res->dataidx = hdrsize;
191 res->size = hdrsize + ressize;
193 /* Analyse the content of the header */
194 idx = 8;
195 /* Get restype */
196 if(get_word(idx) == 0xffff)
198 idx += sizeof(WORD);
199 type = new_name_id();
200 type->type = name_ord;
201 type->name.i_name = get_word(idx);
202 idx += sizeof(WORD);
204 else if(get_word(idx) == 0)
206 error("ResType name has zero length (32 bit)");
208 else
210 int tag = idx;
211 string_t *str;
212 while(1)
214 idx += sizeof(WORD);
215 if(!get_word(idx))
216 break;
218 idx += sizeof(WORD);
219 str = new_string();
220 str->type = str_unicode;
221 str->size = (idx - tag) / 2;
222 str->str.wstr = (short *)xmalloc(idx-tag+2);
223 memcpy(str->str.wstr, &res->data[tag], idx-tag);
224 str->str.wstr[str->size] = 0;
225 type = new_name_id();
226 type->type = name_str;
227 type->name.s_name = str;
229 /* Get resname */
230 if(get_word(idx) == 0xffff)
232 idx += sizeof(WORD);
233 name = new_name_id();
234 name->type = name_ord;
235 name->name.i_name = get_word(idx);
236 idx += sizeof(WORD);
238 else if(get_word(idx) == 0)
240 error("ResName name has zero length (32 bit)");
242 else
244 int tag = idx;
245 string_t *str;
246 while(1)
248 idx += sizeof(WORD);
249 if(!get_word(idx))
250 break;
252 idx += sizeof(WORD);
253 str = new_string();
254 str->type = str_unicode;
255 str->size = (idx - tag) / 2;
256 str->str.wstr = (short *)xmalloc(idx-tag+2);
257 memcpy(str->str.wstr, &res->data[tag], idx-tag);
258 str->str.wstr[str->size] = 0;
259 name = new_name_id();
260 name->type = name_str;
261 name->name.s_name = str;
264 /* align */
265 if(idx & 0x3)
266 idx += 4 - (idx & 3);
268 idx += sizeof(DWORD); /* Skip DataVersion */
269 memopt = get_word(idx);
270 idx += sizeof(WORD);
271 language = get_word(idx);
273 /* Build a resource_t list */
274 res_type = res_type_from_id(type);
275 if(res_type == res_usr)
277 /* User-type has custom ResType for .[s|h] generation */
278 usrres = new_user(type, NULL, new_int(memopt));
280 else
281 usrres = NULL;
282 rsc = new_resource(res_type,
283 usrres,
284 memopt,
285 new_language(PRIMARYLANGID(language),
286 SUBLANGID(language)));
287 rsc->binres = res;
288 rsc->name = name;
289 rsc->c_name = make_c_name(get_c_typename(res_type), name, rsc->lan);
290 if(!list)
292 list = rsc;
293 tail = rsc;
295 else
297 rsc->prev = tail;
298 tail->next = rsc;
299 tail = rsc;
302 return list;
306 *****************************************************************************
307 * Function :
308 * Syntax :
309 * Input :
310 * Output :
311 * Description :
312 * Remarks :
313 *****************************************************************************
315 static resource_t *read_res16(FILE *fp)
317 internal_error(__FILE__, __LINE__, "Can't yet read 16 bit .res files");
318 return NULL;
322 *****************************************************************************
323 * Function : read_resfile
324 * Syntax : resource_t *read_resfile(char *inname)
325 * Input :
326 * Output :
327 * Description :
328 * Remarks :
329 *****************************************************************************
331 resource_t *read_resfile(char *inname)
333 FILE *fp;
334 struct resheader32 rh;
335 int is32bit = 1;
336 resource_t *top;
338 fp = fopen(inname, "rb");
339 if(!fp)
340 error("Could not open inputfile %s", inname);
342 /* Determine 16 or 32 bit .res file */
343 if(fread(&rh, 1, sizeof(rh), fp) != sizeof(rh))
344 is32bit = 0;
345 else
347 if(!memcmp(&emptyheader, &rh, sizeof(rh)))
348 is32bit = 1;
349 else if(!memcmp(&emptyheaderSWAPPED, &rh, sizeof(rh)))
350 error("Binary .res-file has its byteorder swapped");
351 else
352 is32bit = 0;
355 if(is32bit && !win32)
356 error("Cannot convert 32-bit .res-file into 16-bit resources (and will, hopefully never, implement it)");
358 if(!is32bit && win32)
359 error("Cannot (yet) convert 16-bit .res-file into 32-bit resources");
361 if(!is32bit)
363 fseek(fp, 0, SEEK_SET);
364 top = read_res16(fp);
366 else
368 top = read_res32(fp);
371 fclose(fp);
373 return top;