Mercurial > mplayer.hg
annotate loader/pe_resource.c @ 34756:df3ff52039fe
Add code to support CC subtitles in ASTC and MOV.
Code to actually use these will be added later, since it
needs special code in FFmpeg.
Code for MOV is already read, ASTC might take longer.
author | reimar |
---|---|
date | Sat, 07 Apr 2012 00:10:27 +0000 |
parents | 0f1b5b68af32 |
children |
rev | line source |
---|---|
1 | 1 /* |
2 * PE (Portable Execute) File Resources | |
3 * | |
4 * Copyright 1995 Thomas Sandford | |
5 * Copyright 1996 Martin von Loewis | |
6 * | |
7 * Based on the Win16 resource handling code in loader/resource.c | |
8 * Copyright 1993 Robert J. Amstadt | |
9 * Copyright 1995 Alexandre Julliard | |
10 * Copyright 1997 Marcus Meissner | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
7386
diff
changeset
|
11 * |
18783 | 12 * Modified for use with MPlayer, detailed changelog at |
13 * http://svn.mplayerhq.hu/mplayer/trunk/ | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
7386
diff
changeset
|
14 * |
1 | 15 */ |
7386 | 16 #include "config.h" |
1 | 17 |
18 #include <stdlib.h> | |
19 #include <sys/types.h> | |
7386 | 20 #include "wine/winestring.h" |
21 #include "wine/windef.h" | |
22 #include "wine/pe_image.h" | |
23 #include "wine/module.h" | |
24 #include "wine/heap.h" | |
1 | 25 //#include "task.h" |
26 //#include "process.h" | |
27 //#include "stackframe.h" | |
7386 | 28 #include "wine/debugtools.h" |
29 #include "ext.h" | |
1 | 30 |
31 /********************************************************************** | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
32 * HMODULE32toPE_MODREF |
1 | 33 * |
34 * small helper function to get a PE_MODREF from a passed HMODULE32 | |
35 */ | |
36 static PE_MODREF* | |
37 HMODULE32toPE_MODREF(HMODULE hmod) { | |
38 WINE_MODREF *wm; | |
39 | |
40 wm = MODULE32_LookupHMODULE( hmod ); | |
41 if (!wm || wm->type!=MODULE32_PE) | |
42 return NULL; | |
43 return &(wm->binfmt.pe); | |
44 } | |
45 | |
46 /********************************************************************** | |
47 * GetResDirEntryW | |
48 * | |
49 * Helper function - goes down one level of PE resource tree | |
50 * | |
51 */ | |
52 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr, | |
53 LPCWSTR name,DWORD root, | |
54 WIN_BOOL allowdefault) | |
55 { | |
56 int entrynum; | |
57 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable; | |
58 int namelen; | |
59 | |
60 if (HIWORD(name)) { | |
61 if (name[0]=='#') { | |
62 char buf[10]; | |
63 | |
64 lstrcpynWtoA(buf,name+1,10); | |
65 return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault); | |
66 } | |
67 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
68 (BYTE *) resdirptr + |
1 | 69 sizeof(IMAGE_RESOURCE_DIRECTORY)); |
70 namelen = lstrlenW(name); | |
71 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++) | |
72 { | |
73 PIMAGE_RESOURCE_DIR_STRING_U str = | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
74 (PIMAGE_RESOURCE_DIR_STRING_U) (root + |
1 | 75 entryTable[entrynum].u1.s.NameOffset); |
76 if(namelen != str->Length) | |
77 continue; | |
78 if(wcsnicmp(name,str->NameString,str->Length)==0) | |
79 return (PIMAGE_RESOURCE_DIRECTORY) ( | |
80 root + | |
81 entryTable[entrynum].u2.s.OffsetToDirectory); | |
82 } | |
83 return NULL; | |
84 } else { | |
85 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
86 (BYTE *) resdirptr + |
1 | 87 sizeof(IMAGE_RESOURCE_DIRECTORY) + |
88 resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)); | |
89 for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++) | |
90 if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name) | |
91 return (PIMAGE_RESOURCE_DIRECTORY) ( | |
92 root + | |
93 entryTable[entrynum].u2.s.OffsetToDirectory); | |
94 /* just use first entry if no default can be found */ | |
95 if (allowdefault && !name && resdirptr->NumberOfIdEntries) | |
96 return (PIMAGE_RESOURCE_DIRECTORY) ( | |
97 root + | |
98 entryTable[0].u2.s.OffsetToDirectory); | |
99 return NULL; | |
100 } | |
101 } | |
102 | |
103 /********************************************************************** | |
104 * GetResDirEntryA | |
105 */ | |
106 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr, | |
107 LPCSTR name, DWORD root, | |
108 WIN_BOOL allowdefault ) | |
109 { | |
110 PIMAGE_RESOURCE_DIRECTORY retv; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
111 LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name ) |
1 | 112 : (LPWSTR)name; |
113 | |
114 retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault ); | |
115 | |
116 if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW ); | |
117 | |
118 return retv; | |
119 } | |
120 | |
121 /********************************************************************** | |
122 * PE_FindResourceEx32W | |
123 */ | |
124 HANDLE PE_FindResourceExW( | |
125 WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang | |
126 ) { | |
127 PIMAGE_RESOURCE_DIRECTORY resdirptr; | |
128 DWORD root; | |
129 HANDLE result; | |
130 PE_MODREF *pem = &(wm->binfmt.pe); | |
131 | |
132 if (!pem || !pem->pe_resource) | |
133 return 0; | |
134 | |
135 resdirptr = pem->pe_resource; | |
136 root = (DWORD) resdirptr; | |
137 if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL) | |
138 return 0; | |
139 if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL) | |
140 return 0; | |
141 result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE); | |
142 /* Try LANG_NEUTRAL, too */ | |
143 if(!result) | |
144 return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE); | |
145 return result; | |
146 } | |
147 | |
148 | |
149 /********************************************************************** | |
150 * PE_LoadResource32 | |
151 */ | |
152 HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc ) | |
153 { | |
154 if (!hRsrc || !wm || wm->type!=MODULE32_PE) | |
155 return 0; | |
156 return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData); | |
157 } | |
158 | |
159 | |
160 /********************************************************************** | |
161 * PE_SizeofResource32 | |
162 */ | |
163 DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc ) | |
164 { | |
165 /* we don't need hModule */ | |
166 if (!hRsrc) | |
167 return 0; | |
168 return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size; | |
169 } | |
170 | |
171 /********************************************************************** | |
172 * PE_EnumResourceTypes32A | |
173 */ | |
174 WIN_BOOL | |
175 PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) { | |
176 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
177 int i; | |
178 PIMAGE_RESOURCE_DIRECTORY resdir; | |
179 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
180 WIN_BOOL ret; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
181 HANDLE heap = GetProcessHeap(); |
1 | 182 |
183 if (!pem || !pem->pe_resource) | |
184 return FALSE; | |
185 | |
186 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
187 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
188 ret = FALSE; | |
189 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
190 LPSTR name; | |
191 | |
192 if (et[i].u1.s.NameIsString) | |
193 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset)); | |
194 else | |
195 name = (LPSTR)(int)et[i].u1.Id; | |
196 ret = lpfun(hmod,name,lparam); | |
197 if (HIWORD(name)) | |
198 HeapFree(heap,0,name); | |
199 if (!ret) | |
200 break; | |
201 } | |
202 return ret; | |
203 } | |
204 | |
205 /********************************************************************** | |
206 * PE_EnumResourceTypes32W | |
207 */ | |
208 WIN_BOOL | |
209 PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) { | |
210 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
211 int i; | |
212 PIMAGE_RESOURCE_DIRECTORY resdir; | |
213 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
214 WIN_BOOL ret; | |
215 | |
216 if (!pem || !pem->pe_resource) | |
217 return FALSE; | |
218 | |
219 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
220 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
221 ret = FALSE; | |
222 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
223 LPWSTR type; | |
224 if (et[i].u1.s.NameIsString) | |
225 type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset); | |
226 else | |
227 type = (LPWSTR)(int)et[i].u1.Id; | |
228 | |
229 ret = lpfun(hmod,type,lparam); | |
230 if (!ret) | |
231 break; | |
232 } | |
233 return ret; | |
234 } | |
235 | |
236 /********************************************************************** | |
237 * PE_EnumResourceNames32A | |
238 */ | |
239 WIN_BOOL | |
240 PE_EnumResourceNamesA( | |
241 HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam | |
242 ) { | |
243 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
244 int i; | |
245 PIMAGE_RESOURCE_DIRECTORY resdir; | |
246 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
247 WIN_BOOL ret; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
248 HANDLE heap = GetProcessHeap(); |
1 | 249 LPWSTR typeW; |
250 | |
251 if (!pem || !pem->pe_resource) | |
252 return FALSE; | |
253 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
254 if (HIWORD(type)) | |
255 typeW = HEAP_strdupAtoW(heap,0,type); | |
256 else | |
257 typeW = (LPWSTR)type; | |
258 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE); | |
259 if (HIWORD(typeW)) | |
260 HeapFree(heap,0,typeW); | |
261 if (!resdir) | |
262 return FALSE; | |
263 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
264 ret = FALSE; | |
265 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
266 LPSTR name; | |
267 | |
268 if (et[i].u1.s.NameIsString) | |
269 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset)); | |
270 else | |
271 name = (LPSTR)(int)et[i].u1.Id; | |
272 ret = lpfun(hmod,type,name,lparam); | |
273 if (HIWORD(name)) HeapFree(heap,0,name); | |
274 if (!ret) | |
275 break; | |
276 } | |
277 return ret; | |
278 } | |
279 | |
280 /********************************************************************** | |
281 * PE_EnumResourceNames32W | |
282 */ | |
283 WIN_BOOL | |
284 PE_EnumResourceNamesW( | |
285 HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam | |
286 ) { | |
287 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
288 int i; | |
289 PIMAGE_RESOURCE_DIRECTORY resdir; | |
290 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
291 WIN_BOOL ret; | |
292 | |
293 if (!pem || !pem->pe_resource) | |
294 return FALSE; | |
295 | |
296 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
297 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE); | |
298 if (!resdir) | |
299 return FALSE; | |
300 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
301 ret = FALSE; | |
302 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
303 LPWSTR name; | |
304 if (et[i].u1.s.NameIsString) | |
305 name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset); | |
306 else | |
307 name = (LPWSTR)(int)et[i].u1.Id; | |
308 ret = lpfun(hmod,type,name,lparam); | |
309 if (!ret) | |
310 break; | |
311 } | |
312 return ret; | |
313 } | |
314 | |
315 /********************************************************************** | |
316 * PE_EnumResourceNames32A | |
317 */ | |
318 WIN_BOOL | |
319 PE_EnumResourceLanguagesA( | |
320 HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun, | |
321 LONG lparam | |
322 ) { | |
323 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
324 int i; | |
325 PIMAGE_RESOURCE_DIRECTORY resdir; | |
326 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
327 WIN_BOOL ret; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
328 HANDLE heap = GetProcessHeap(); |
1 | 329 LPWSTR nameW,typeW; |
330 | |
331 if (!pem || !pem->pe_resource) | |
332 return FALSE; | |
333 | |
334 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
335 if (HIWORD(name)) | |
336 nameW = HEAP_strdupAtoW(heap,0,name); | |
337 else | |
338 nameW = (LPWSTR)name; | |
339 resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE); | |
340 if (HIWORD(nameW)) | |
341 HeapFree(heap,0,nameW); | |
342 if (!resdir) | |
343 return FALSE; | |
344 if (HIWORD(type)) | |
345 typeW = HEAP_strdupAtoW(heap,0,type); | |
346 else | |
347 typeW = (LPWSTR)type; | |
348 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE); | |
349 if (HIWORD(typeW)) | |
350 HeapFree(heap,0,typeW); | |
351 if (!resdir) | |
352 return FALSE; | |
353 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
354 ret = FALSE; | |
355 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
356 /* languages are just ids... I hopem */ | |
357 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam); | |
358 if (!ret) | |
359 break; | |
360 } | |
361 return ret; | |
362 } | |
363 | |
364 /********************************************************************** | |
365 * PE_EnumResourceLanguages32W | |
366 */ | |
367 WIN_BOOL | |
368 PE_EnumResourceLanguagesW( | |
369 HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun, | |
370 LONG lparam | |
371 ) { | |
372 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
373 int i; | |
374 PIMAGE_RESOURCE_DIRECTORY resdir; | |
375 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
376 WIN_BOOL ret; | |
377 | |
378 if (!pem || !pem->pe_resource) | |
379 return FALSE; | |
380 | |
381 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
382 resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE); | |
383 if (!resdir) | |
384 return FALSE; | |
385 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE); | |
386 if (!resdir) | |
387 return FALSE; | |
388 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
389 ret = FALSE; | |
390 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
391 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam); | |
392 if (!ret) | |
393 break; | |
394 } | |
395 return ret; | |
396 } |