Mercurial > mplayer.hg
annotate loader/pe_resource.c @ 23572:a00685941686
demux_mkv very long seek fix
The seek code searching for the closest position in the index used
"int64_t min_diff=0xFFFFFFFL" as the initial "further from the goal
than any real alternative" value. The unit is milliseconds so seeks more
than about 75 hours past the end of the file would fail to recognize the
last index position as the best match. This was triggered in practice by
chapter seek code which apparently uses a seek of 1000000000 seconds
forward to mean "seek to the end". The practical effect was that trying
to seek to the next chapter in a file without chapters made MPlayer
block until it finished reading the file from the current position to
the end.
Fixed by increasing the initial value from FFFFFFF to FFFFFFFFFFFFFFF.
author | uau |
---|---|
date | Wed, 20 Jun 2007 18:19:03 +0000 |
parents | 0783dd397f74 |
children | b70f5ac9c001 |
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 * $Id$ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
7386
diff
changeset
|
15 * |
1 | 16 */ |
7386 | 17 #include "config.h" |
1 | 18 |
19 #include <stdlib.h> | |
20 #include <sys/types.h> | |
7386 | 21 #include "wine/winestring.h" |
22 #include "wine/windef.h" | |
23 #include "wine/pe_image.h" | |
24 #include "wine/module.h" | |
25 #include "wine/heap.h" | |
1 | 26 //#include "task.h" |
27 //#include "process.h" | |
28 //#include "stackframe.h" | |
7386 | 29 #include "wine/debugtools.h" |
30 #include "ext.h" | |
1 | 31 |
32 /********************************************************************** | |
33 * HMODULE32toPE_MODREF | |
34 * | |
35 * small helper function to get a PE_MODREF from a passed HMODULE32 | |
36 */ | |
37 static PE_MODREF* | |
38 HMODULE32toPE_MODREF(HMODULE hmod) { | |
39 WINE_MODREF *wm; | |
40 | |
41 wm = MODULE32_LookupHMODULE( hmod ); | |
42 if (!wm || wm->type!=MODULE32_PE) | |
43 return NULL; | |
44 return &(wm->binfmt.pe); | |
45 } | |
46 | |
47 /********************************************************************** | |
48 * GetResDirEntryW | |
49 * | |
50 * Helper function - goes down one level of PE resource tree | |
51 * | |
52 */ | |
53 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr, | |
54 LPCWSTR name,DWORD root, | |
55 WIN_BOOL allowdefault) | |
56 { | |
57 int entrynum; | |
58 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable; | |
59 int namelen; | |
60 | |
61 if (HIWORD(name)) { | |
62 if (name[0]=='#') { | |
63 char buf[10]; | |
64 | |
65 lstrcpynWtoA(buf,name+1,10); | |
66 return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault); | |
67 } | |
68 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( | |
69 (BYTE *) resdirptr + | |
70 sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
71 namelen = lstrlenW(name); | |
72 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++) | |
73 { | |
74 PIMAGE_RESOURCE_DIR_STRING_U str = | |
75 (PIMAGE_RESOURCE_DIR_STRING_U) (root + | |
76 entryTable[entrynum].u1.s.NameOffset); | |
77 if(namelen != str->Length) | |
78 continue; | |
79 if(wcsnicmp(name,str->NameString,str->Length)==0) | |
80 return (PIMAGE_RESOURCE_DIRECTORY) ( | |
81 root + | |
82 entryTable[entrynum].u2.s.OffsetToDirectory); | |
83 } | |
84 return NULL; | |
85 } else { | |
86 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( | |
87 (BYTE *) resdirptr + | |
88 sizeof(IMAGE_RESOURCE_DIRECTORY) + | |
89 resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)); | |
90 for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++) | |
91 if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name) | |
92 return (PIMAGE_RESOURCE_DIRECTORY) ( | |
93 root + | |
94 entryTable[entrynum].u2.s.OffsetToDirectory); | |
95 /* just use first entry if no default can be found */ | |
96 if (allowdefault && !name && resdirptr->NumberOfIdEntries) | |
97 return (PIMAGE_RESOURCE_DIRECTORY) ( | |
98 root + | |
99 entryTable[0].u2.s.OffsetToDirectory); | |
100 return NULL; | |
101 } | |
102 } | |
103 | |
104 /********************************************************************** | |
105 * GetResDirEntryA | |
106 */ | |
107 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr, | |
108 LPCSTR name, DWORD root, | |
109 WIN_BOOL allowdefault ) | |
110 { | |
111 PIMAGE_RESOURCE_DIRECTORY retv; | |
112 LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name ) | |
113 : (LPWSTR)name; | |
114 | |
115 retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault ); | |
116 | |
117 if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW ); | |
118 | |
119 return retv; | |
120 } | |
121 | |
122 /********************************************************************** | |
123 * PE_FindResourceEx32W | |
124 */ | |
125 HANDLE PE_FindResourceExW( | |
126 WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang | |
127 ) { | |
128 PIMAGE_RESOURCE_DIRECTORY resdirptr; | |
129 DWORD root; | |
130 HANDLE result; | |
131 PE_MODREF *pem = &(wm->binfmt.pe); | |
132 | |
133 if (!pem || !pem->pe_resource) | |
134 return 0; | |
135 | |
136 resdirptr = pem->pe_resource; | |
137 root = (DWORD) resdirptr; | |
138 if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL) | |
139 return 0; | |
140 if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL) | |
141 return 0; | |
142 result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE); | |
143 /* Try LANG_NEUTRAL, too */ | |
144 if(!result) | |
145 return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE); | |
146 return result; | |
147 } | |
148 | |
149 | |
150 /********************************************************************** | |
151 * PE_LoadResource32 | |
152 */ | |
153 HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc ) | |
154 { | |
155 if (!hRsrc || !wm || wm->type!=MODULE32_PE) | |
156 return 0; | |
157 return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData); | |
158 } | |
159 | |
160 | |
161 /********************************************************************** | |
162 * PE_SizeofResource32 | |
163 */ | |
164 DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc ) | |
165 { | |
166 /* we don't need hModule */ | |
167 if (!hRsrc) | |
168 return 0; | |
169 return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size; | |
170 } | |
171 | |
172 /********************************************************************** | |
173 * PE_EnumResourceTypes32A | |
174 */ | |
175 WIN_BOOL | |
176 PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) { | |
177 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
178 int i; | |
179 PIMAGE_RESOURCE_DIRECTORY resdir; | |
180 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
181 WIN_BOOL ret; | |
182 HANDLE heap = GetProcessHeap(); | |
183 | |
184 if (!pem || !pem->pe_resource) | |
185 return FALSE; | |
186 | |
187 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
188 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
189 ret = FALSE; | |
190 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
191 LPSTR name; | |
192 | |
193 if (et[i].u1.s.NameIsString) | |
194 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset)); | |
195 else | |
196 name = (LPSTR)(int)et[i].u1.Id; | |
197 ret = lpfun(hmod,name,lparam); | |
198 if (HIWORD(name)) | |
199 HeapFree(heap,0,name); | |
200 if (!ret) | |
201 break; | |
202 } | |
203 return ret; | |
204 } | |
205 | |
206 /********************************************************************** | |
207 * PE_EnumResourceTypes32W | |
208 */ | |
209 WIN_BOOL | |
210 PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) { | |
211 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
212 int i; | |
213 PIMAGE_RESOURCE_DIRECTORY resdir; | |
214 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
215 WIN_BOOL ret; | |
216 | |
217 if (!pem || !pem->pe_resource) | |
218 return FALSE; | |
219 | |
220 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
221 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
222 ret = FALSE; | |
223 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
224 LPWSTR type; | |
225 if (et[i].u1.s.NameIsString) | |
226 type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset); | |
227 else | |
228 type = (LPWSTR)(int)et[i].u1.Id; | |
229 | |
230 ret = lpfun(hmod,type,lparam); | |
231 if (!ret) | |
232 break; | |
233 } | |
234 return ret; | |
235 } | |
236 | |
237 /********************************************************************** | |
238 * PE_EnumResourceNames32A | |
239 */ | |
240 WIN_BOOL | |
241 PE_EnumResourceNamesA( | |
242 HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam | |
243 ) { | |
244 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
245 int i; | |
246 PIMAGE_RESOURCE_DIRECTORY resdir; | |
247 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
248 WIN_BOOL ret; | |
249 HANDLE heap = GetProcessHeap(); | |
250 LPWSTR typeW; | |
251 | |
252 if (!pem || !pem->pe_resource) | |
253 return FALSE; | |
254 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
255 if (HIWORD(type)) | |
256 typeW = HEAP_strdupAtoW(heap,0,type); | |
257 else | |
258 typeW = (LPWSTR)type; | |
259 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE); | |
260 if (HIWORD(typeW)) | |
261 HeapFree(heap,0,typeW); | |
262 if (!resdir) | |
263 return FALSE; | |
264 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
265 ret = FALSE; | |
266 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
267 LPSTR name; | |
268 | |
269 if (et[i].u1.s.NameIsString) | |
270 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset)); | |
271 else | |
272 name = (LPSTR)(int)et[i].u1.Id; | |
273 ret = lpfun(hmod,type,name,lparam); | |
274 if (HIWORD(name)) HeapFree(heap,0,name); | |
275 if (!ret) | |
276 break; | |
277 } | |
278 return ret; | |
279 } | |
280 | |
281 /********************************************************************** | |
282 * PE_EnumResourceNames32W | |
283 */ | |
284 WIN_BOOL | |
285 PE_EnumResourceNamesW( | |
286 HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam | |
287 ) { | |
288 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
289 int i; | |
290 PIMAGE_RESOURCE_DIRECTORY resdir; | |
291 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
292 WIN_BOOL ret; | |
293 | |
294 if (!pem || !pem->pe_resource) | |
295 return FALSE; | |
296 | |
297 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
298 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE); | |
299 if (!resdir) | |
300 return FALSE; | |
301 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
302 ret = FALSE; | |
303 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
304 LPWSTR name; | |
305 if (et[i].u1.s.NameIsString) | |
306 name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset); | |
307 else | |
308 name = (LPWSTR)(int)et[i].u1.Id; | |
309 ret = lpfun(hmod,type,name,lparam); | |
310 if (!ret) | |
311 break; | |
312 } | |
313 return ret; | |
314 } | |
315 | |
316 /********************************************************************** | |
317 * PE_EnumResourceNames32A | |
318 */ | |
319 WIN_BOOL | |
320 PE_EnumResourceLanguagesA( | |
321 HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun, | |
322 LONG lparam | |
323 ) { | |
324 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
325 int i; | |
326 PIMAGE_RESOURCE_DIRECTORY resdir; | |
327 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
328 WIN_BOOL ret; | |
329 HANDLE heap = GetProcessHeap(); | |
330 LPWSTR nameW,typeW; | |
331 | |
332 if (!pem || !pem->pe_resource) | |
333 return FALSE; | |
334 | |
335 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
336 if (HIWORD(name)) | |
337 nameW = HEAP_strdupAtoW(heap,0,name); | |
338 else | |
339 nameW = (LPWSTR)name; | |
340 resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE); | |
341 if (HIWORD(nameW)) | |
342 HeapFree(heap,0,nameW); | |
343 if (!resdir) | |
344 return FALSE; | |
345 if (HIWORD(type)) | |
346 typeW = HEAP_strdupAtoW(heap,0,type); | |
347 else | |
348 typeW = (LPWSTR)type; | |
349 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE); | |
350 if (HIWORD(typeW)) | |
351 HeapFree(heap,0,typeW); | |
352 if (!resdir) | |
353 return FALSE; | |
354 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
355 ret = FALSE; | |
356 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
357 /* languages are just ids... I hopem */ | |
358 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam); | |
359 if (!ret) | |
360 break; | |
361 } | |
362 return ret; | |
363 } | |
364 | |
365 /********************************************************************** | |
366 * PE_EnumResourceLanguages32W | |
367 */ | |
368 WIN_BOOL | |
369 PE_EnumResourceLanguagesW( | |
370 HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun, | |
371 LONG lparam | |
372 ) { | |
373 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); | |
374 int i; | |
375 PIMAGE_RESOURCE_DIRECTORY resdir; | |
376 PIMAGE_RESOURCE_DIRECTORY_ENTRY et; | |
377 WIN_BOOL ret; | |
378 | |
379 if (!pem || !pem->pe_resource) | |
380 return FALSE; | |
381 | |
382 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; | |
383 resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE); | |
384 if (!resdir) | |
385 return FALSE; | |
386 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE); | |
387 if (!resdir) | |
388 return FALSE; | |
389 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); | |
390 ret = FALSE; | |
391 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { | |
392 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam); | |
393 if (!ret) | |
394 break; | |
395 } | |
396 return ret; | |
397 } |