Mercurial > mplayer.hg
annotate loader/resource.c @ 17335:3e49b98ad314
Less ugly and easier to extend getFunctions
author | reimar |
---|---|
date | Sat, 07 Jan 2006 19:53:51 +0000 |
parents | f5537cc95b02 |
children | 0783dd397f74 |
rev | line source |
---|---|
1 | 1 /* |
2 * Resources | |
3 * | |
4 * Copyright 1993 Robert J. Amstadt | |
5 * Copyright 1995 Alexandre Julliard | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
11000
diff
changeset
|
6 * |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
11000
diff
changeset
|
7 * Modified for use with MPlayer, detailed CVS changelog at |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
11000
diff
changeset
|
8 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
11000
diff
changeset
|
9 * $Id$ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
11000
diff
changeset
|
10 * |
1 | 11 */ |
7386 | 12 #include "config.h" |
1 | 13 |
14 #include <assert.h> | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
1
diff
changeset
|
15 #include <stdio.h> |
1 | 16 #include <stdlib.h> |
17 #include <string.h> | |
18 #include <sys/types.h> | |
19 #include <sys/stat.h> | |
20 #include <fcntl.h> | |
21 #include <unistd.h> | |
7386 | 22 |
23 #include "wine/winbase.h" | |
24 #include "wine/windef.h" | |
25 #include "wine/winuser.h" | |
26 #include "wine/heap.h" | |
27 #include "wine/module.h" | |
28 #include "wine/debugtools.h" | |
29 #include "wine/winerror.h" | |
30 #include "loader.h" | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
1
diff
changeset
|
31 |
1 | 32 #define CP_ACP 0 |
33 | |
34 WORD WINE_LanguageId=0x409;//english | |
35 | |
36 #define HRSRC_MAP_BLOCKSIZE 16 | |
37 | |
38 typedef struct _HRSRC_ELEM | |
39 { | |
40 HANDLE hRsrc; | |
41 WORD type; | |
42 } HRSRC_ELEM; | |
43 | |
44 typedef struct _HRSRC_MAP | |
45 { | |
46 int nAlloc; | |
47 int nUsed; | |
48 HRSRC_ELEM *elem; | |
49 } HRSRC_MAP; | |
50 | |
51 static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type, | |
52 LPCSTR name, WORD lang, int unicode) | |
53 { | |
54 HRSRC hRsrc = 0; | |
55 LPWSTR typeStr, nameStr; | |
56 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); | |
57 | |
58 if(!wm) | |
59 return 0; | |
60 /* 32-bit PE module */ | |
61 | |
62 | |
63 if ( HIWORD( type ) && (!unicode)) | |
64 typeStr = HEAP_strdupAtoW( GetProcessHeap(), 0, type ); | |
65 else | |
66 typeStr = (LPWSTR)type; | |
67 if ( HIWORD( name ) && (!unicode)) | |
68 nameStr = HEAP_strdupAtoW( GetProcessHeap(), 0, name ); | |
69 else | |
70 nameStr = (LPWSTR)name; | |
71 | |
72 hRsrc = PE_FindResourceExW( wm, nameStr, typeStr, lang ); | |
73 | |
74 if ( HIWORD( type ) && (!unicode)) | |
75 HeapFree( GetProcessHeap(), 0, typeStr ); | |
76 if ( HIWORD( name ) && (!unicode)) | |
77 HeapFree( GetProcessHeap(), 0, nameStr ); | |
78 | |
79 return hRsrc; | |
80 } | |
81 | |
82 /********************************************************************** | |
83 * RES_FindResource | |
84 */ | |
85 | |
86 static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type, | |
87 LPCSTR name, WORD lang, int unicode ) | |
88 { | |
89 HRSRC hRsrc; | |
90 // __TRY | |
91 // { | |
92 hRsrc = RES_FindResource2(hModule, type, name, lang, unicode); | |
93 // } | |
94 // __EXCEPT(page_fault) | |
95 // { | |
96 // WARN("page fault\n"); | |
97 // SetLastError(ERROR_INVALID_PARAMETER); | |
98 // return 0; | |
99 // } | |
100 // __ENDTRY | |
101 return hRsrc; | |
102 } | |
103 | |
104 /********************************************************************** | |
105 * RES_SizeofResource | |
106 */ | |
107 static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc) | |
108 { | |
109 DWORD size = 0; | |
110 HRSRC hRsrc32; | |
111 | |
112 // HMODULE16 hMod16 = MapHModuleLS( hModule ); | |
113 // NE_MODULE *pModule = NE_GetPtr( hMod16 ); | |
114 // WINE_MODREF *wm = pModule && pModule->module32? | |
115 // MODULE32_LookupHMODULE( pModule->module32 ) : NULL; | |
116 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); | |
117 | |
118 if ( !hModule || !hRsrc ) return 0; | |
119 | |
120 /* 32-bit PE module */ | |
121 /* If we got a 16-bit hRsrc, convert it */ | |
122 // hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); | |
123 if(!HIWORD(hRsrc)) | |
124 { | |
125 printf("16-bit hRsrcs not supported\n"); | |
126 return 0; | |
127 } | |
128 size = PE_SizeofResource( hModule, hRsrc ); | |
129 return size; | |
130 } | |
131 | |
132 /********************************************************************** | |
133 * RES_AccessResource | |
134 */ | |
135 static HFILE RES_AccessResource( HMODULE hModule, HRSRC hRsrc ) | |
136 { | |
137 HFILE hFile = HFILE_ERROR; | |
138 | |
139 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); | |
140 | |
141 if ( !hModule || !hRsrc ) return HFILE_ERROR; | |
142 | |
143 /* 32-bit PE module */ | |
144 FIXME("32-bit modules not yet supported.\n" ); | |
145 hFile = HFILE_ERROR; | |
146 | |
147 return hFile; | |
148 } | |
149 | |
150 /********************************************************************** | |
151 * RES_LoadResource | |
152 */ | |
153 static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc) | |
154 { | |
155 HGLOBAL hMem = 0; | |
156 HRSRC hRsrc32; | |
157 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); | |
158 | |
159 | |
160 if ( !hModule || !hRsrc ) return 0; | |
161 | |
162 /* 32-bit PE module */ | |
163 | |
164 /* If we got a 16-bit hRsrc, convert it */ | |
165 // hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); | |
166 if(!HIWORD(hRsrc)) | |
167 { | |
168 printf("16-bit hRsrcs not supported\n"); | |
169 return 0; | |
170 } | |
171 hMem = PE_LoadResource( wm, hRsrc ); | |
172 | |
173 return hMem; | |
174 } | |
175 | |
176 /********************************************************************** | |
177 * RES_LockResource | |
178 */ | |
179 static LPVOID RES_LockResource( HGLOBAL handle ) | |
180 { | |
181 LPVOID bits = NULL; | |
182 | |
183 TRACE("(%08x, %s)\n", handle, "PE" ); | |
184 | |
185 bits = (LPVOID)handle; | |
186 | |
187 return bits; | |
188 } | |
189 | |
190 /********************************************************************** | |
191 * RES_FreeResource | |
192 */ | |
193 static WIN_BOOL RES_FreeResource( HGLOBAL handle ) | |
194 { | |
195 HGLOBAL retv = handle; | |
196 return (WIN_BOOL)retv; | |
197 } | |
198 | |
199 /********************************************************************** | |
200 * FindResourceA (KERNEL32.128) | |
201 */ | |
202 HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) | |
203 { | |
204 return RES_FindResource( hModule, type, name, | |
205 WINE_LanguageId, 0); | |
206 } | |
207 HANDLE WINAPI FindResourceW( HMODULE hModule, LPCWSTR name, LPCWSTR type ) | |
208 { | |
209 return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, | |
210 WINE_LanguageId, 1); | |
211 } | |
212 | |
213 /********************************************************************** | |
214 * FindResourceExA (KERNEL32.129) | |
215 */ | |
216 HANDLE WINAPI FindResourceExA( HMODULE hModule, | |
217 LPCSTR type, LPCSTR name, WORD lang ) | |
218 { | |
219 return RES_FindResource( hModule, type, name, | |
220 lang, 0 ); | |
221 } | |
222 | |
223 HANDLE WINAPI FindResourceExW( HMODULE hModule, | |
224 LPCWSTR type, LPCWSTR name, WORD lang ) | |
225 { | |
226 return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, | |
227 lang, 1 ); | |
228 } | |
229 | |
230 | |
231 | |
232 /********************************************************************** | |
233 * LockResource (KERNEL32.384) | |
234 */ | |
235 LPVOID WINAPI LockResource( HGLOBAL handle ) | |
236 { | |
237 return RES_LockResource( handle ); | |
238 } | |
239 | |
240 | |
241 /********************************************************************** | |
242 * FreeResource (KERNEL32.145) | |
243 */ | |
244 WIN_BOOL WINAPI FreeResource( HGLOBAL handle ) | |
245 { | |
246 return RES_FreeResource( handle ); | |
247 } | |
248 | |
249 | |
250 /********************************************************************** | |
251 * AccessResource (KERNEL32.64) | |
252 */ | |
253 INT WINAPI AccessResource( HMODULE hModule, HRSRC hRsrc ) | |
254 { | |
255 return RES_AccessResource( hModule, hRsrc ); | |
256 } | |
257 /********************************************************************** | |
258 * SizeofResource (KERNEL32.522) | |
259 */ | |
260 DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc ) | |
261 { | |
262 return RES_SizeofResource( hModule, hRsrc ); | |
263 } | |
264 | |
265 | |
266 INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id, | |
267 LPWSTR buffer, INT buflen ); | |
268 | |
269 /********************************************************************** | |
270 * LoadStringA (USER32.375) | |
271 */ | |
272 INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id, | |
273 LPSTR buffer, INT buflen ) | |
274 { | |
275 INT retval; | |
276 INT wbuflen; | |
277 INT abuflen; | |
278 LPWSTR wbuf = NULL; | |
279 LPSTR abuf = NULL; | |
280 | |
281 if ( buffer != NULL && buflen > 0 ) | |
282 *buffer = 0; | |
283 | |
284 wbuflen = LoadStringW(instance,resource_id,NULL,0); | |
285 if ( !wbuflen ) | |
286 return 0; | |
287 wbuflen ++; | |
288 | |
289 retval = 0; | |
7386 | 290 wbuf = (LPWSTR) HeapAlloc( GetProcessHeap(), 0, wbuflen * sizeof(WCHAR) ); |
1 | 291 wbuflen = LoadStringW(instance,resource_id,wbuf,wbuflen); |
292 if ( wbuflen > 0 ) | |
293 { | |
294 abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,NULL,0,NULL,NULL); | |
295 if ( abuflen > 0 ) | |
296 { | |
297 if ( buffer == NULL || buflen == 0 ) | |
298 retval = abuflen; | |
299 else | |
300 { | |
7386 | 301 abuf = (LPSTR) HeapAlloc( GetProcessHeap(), 0, abuflen * sizeof(CHAR) ); |
1 | 302 abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,abuf,abuflen,NULL,NULL); |
303 if ( abuflen > 0 ) | |
304 { | |
305 abuflen = min(abuflen,buflen - 1); | |
306 memcpy( buffer, abuf, abuflen ); | |
307 buffer[abuflen] = 0; | |
308 retval = abuflen; | |
309 } | |
310 HeapFree( GetProcessHeap(), 0, abuf ); | |
311 } | |
312 } | |
313 } | |
314 HeapFree( GetProcessHeap(), 0, wbuf ); | |
315 | |
316 return retval; | |
317 } | |
318 | |
319 /********************************************************************** | |
320 * LoadStringW (USER32.376) | |
321 */ | |
322 INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id, | |
323 LPWSTR buffer, INT buflen ) | |
324 { | |
325 HGLOBAL hmem; | |
326 HRSRC hrsrc; | |
327 WCHAR *p; | |
328 int string_num; | |
329 int i; | |
330 | |
331 if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */ | |
332 resource_id = (UINT)(-((INT)resource_id)); | |
333 TRACE("instance = %04x, id = %04x, buffer = %08x, " | |
334 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen); | |
335 | |
336 /* Use bits 4 - 19 (incremented by 1) as resourceid, mask out | |
337 * 20 - 31. */ | |
338 hrsrc = FindResourceW( instance, (LPCWSTR)(((resource_id>>4)&0xffff)+1), | |
339 RT_STRINGW ); | |
340 if (!hrsrc) return 0; | |
341 hmem = LoadResource( instance, hrsrc ); | |
342 if (!hmem) return 0; | |
343 | |
7386 | 344 p = (WCHAR*) LockResource(hmem); |
1 | 345 string_num = resource_id & 0x000f; |
346 for (i = 0; i < string_num; i++) | |
347 p += *p + 1; | |
348 | |
349 TRACE("strlen = %d\n", (int)*p ); | |
350 | |
351 if (buffer == NULL) return *p; | |
352 i = min(buflen - 1, *p); | |
353 if (i > 0) { | |
354 memcpy(buffer, p + 1, i * sizeof (WCHAR)); | |
355 buffer[i] = (WCHAR) 0; | |
356 } else { | |
357 if (buflen > 1) { | |
358 buffer[0] = (WCHAR) 0; | |
359 return 0; | |
360 } | |
361 #if 0 | |
11000 | 362 WARN("Don't know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1); |
1 | 363 #endif |
364 } | |
365 | |
366 TRACE("String loaded !\n"); | |
367 return i; | |
368 } | |
369 | |
370 /* Messages...used by FormatMessage32* (KERNEL32.something) | |
371 * | |
372 * They can be specified either directly or using a message ID and | |
373 * loading them from the resource. | |
374 * | |
375 * The resourcedata has following format: | |
376 * start: | |
377 * 0: DWORD nrofentries | |
378 * nrofentries * subentry: | |
379 * 0: DWORD firstentry | |
380 * 4: DWORD lastentry | |
381 * 8: DWORD offset from start to the stringentries | |
382 * | |
383 * (lastentry-firstentry) * stringentry: | |
384 * 0: WORD len (0 marks end) | |
385 * 2: WORD flags | |
386 * 4: CHAR[len-4] | |
387 * (stringentry i of a subentry refers to the ID 'firstentry+i') | |
388 * | |
389 * Yes, ANSI strings in win32 resources. Go figure. | |
390 */ | |
391 | |
392 /********************************************************************** | |
393 * LoadMessageA (internal) | |
394 */ | |
395 INT WINAPI LoadMessageA( HMODULE instance, UINT id, WORD lang, | |
396 LPSTR buffer, INT buflen ) | |
397 { | |
398 HGLOBAL hmem; | |
399 HRSRC hrsrc; | |
400 PMESSAGE_RESOURCE_DATA mrd; | |
401 PMESSAGE_RESOURCE_BLOCK mrb; | |
402 PMESSAGE_RESOURCE_ENTRY mre; | |
403 int i,slen; | |
404 | |
405 TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen); | |
406 | |
407 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/ | |
408 hrsrc = FindResourceExW(instance,RT_MESSAGELISTW,(LPWSTR)1,lang); | |
409 if (!hrsrc) return 0; | |
410 hmem = LoadResource( instance, hrsrc ); | |
411 if (!hmem) return 0; | |
412 | |
413 mrd = (PMESSAGE_RESOURCE_DATA)LockResource(hmem); | |
414 mre = NULL; | |
415 mrb = &(mrd->Blocks[0]); | |
416 for (i=mrd->NumberOfBlocks;i--;) { | |
417 if ((id>=mrb->LowId) && (id<=mrb->HighId)) { | |
418 mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mrd)+mrb->OffsetToEntries); | |
419 id -= mrb->LowId; | |
420 break; | |
421 } | |
422 mrb++; | |
423 } | |
424 if (!mre) | |
425 return 0; | |
426 for (i=id;i--;) { | |
427 if (!mre->Length) | |
428 return 0; | |
429 mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mre)+(mre->Length)); | |
430 } | |
431 slen=mre->Length; | |
432 TRACE(" - strlen=%d\n",slen); | |
433 i = min(buflen - 1, slen); | |
434 if (buffer == NULL) | |
435 return slen; | |
436 if (i>0) { | |
437 lstrcpynA(buffer,(char*)mre->Text,i); | |
438 buffer[i]=0; | |
439 } else { | |
440 if (buflen>1) { | |
441 buffer[0]=0; | |
442 return 0; | |
443 } | |
444 } | |
445 if (buffer) | |
446 TRACE("'%s' copied !\n", buffer); | |
447 return i; | |
448 } | |
449 | |
450 | |
451 | |
452 /********************************************************************** | |
453 * EnumResourceTypesA (KERNEL32.90) | |
454 */ | |
455 WIN_BOOL WINAPI EnumResourceTypesA( HMODULE hmodule,ENUMRESTYPEPROCA lpfun, | |
456 LONG lParam) | |
457 { | |
458 /* FIXME: move WINE_MODREF stuff here */ | |
459 return PE_EnumResourceTypesA(hmodule,lpfun,lParam); | |
460 } | |
461 | |
462 /********************************************************************** | |
463 * EnumResourceNamesA (KERNEL32.88) | |
464 */ | |
465 WIN_BOOL WINAPI EnumResourceNamesA( HMODULE hmodule, LPCSTR type, | |
466 ENUMRESNAMEPROCA lpfun, LONG lParam ) | |
467 { | |
468 /* FIXME: move WINE_MODREF stuff here */ | |
469 return PE_EnumResourceNamesA(hmodule,type,lpfun,lParam); | |
470 } | |
471 /********************************************************************** | |
472 * EnumResourceLanguagesA (KERNEL32.86) | |
473 */ | |
474 WIN_BOOL WINAPI EnumResourceLanguagesA( HMODULE hmodule, LPCSTR type, | |
475 LPCSTR name, ENUMRESLANGPROCA lpfun, | |
476 LONG lParam) | |
477 { | |
478 /* FIXME: move WINE_MODREF stuff here */ | |
479 return PE_EnumResourceLanguagesA(hmodule,type,name,lpfun,lParam); | |
480 } | |
481 /********************************************************************** | |
482 * LoadResource (KERNEL32.370) | |
483 */ | |
484 HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc ) | |
485 { | |
486 return RES_LoadResource( hModule, hRsrc); | |
487 } |