Added stubs for riched32.dll.
[wine/wine-kai.git] / loader / pe_resource.c
blob4123875293b024069ba130a631450a60b41f8876
1 /*
2 * PE (Portable Execute) File Resources
4 * Copyright 1995 Thomas Sandford
5 * Copyright 1996 Martin von Loewis
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
13 #include <stdlib.h>
14 #include <sys/types.h>
15 #include "wine/winestring.h"
16 #include "windef.h"
17 #include "pe_image.h"
18 #include "module.h"
19 #include "heap.h"
20 #include "task.h"
21 #include "process.h"
22 #include "stackframe.h"
23 #include "neexe.h"
24 #include "crtdll.h"
25 #include "debugtools.h"
27 /**********************************************************************
28 * HMODULE32toPE_MODREF
30 * small helper function to get a PE_MODREF from a passed HMODULE32
32 static PE_MODREF*
33 HMODULE32toPE_MODREF(HMODULE hmod) {
34 WINE_MODREF *wm;
36 wm = MODULE32_LookupHMODULE( hmod );
37 if (!wm || wm->type!=MODULE32_PE)
38 return NULL;
39 return &(wm->binfmt.pe);
42 /**********************************************************************
43 * GetResDirEntryW
45 * Helper function - goes down one level of PE resource tree
48 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
49 LPCWSTR name,DWORD root,
50 BOOL allowdefault)
52 int entrynum;
53 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
54 int namelen;
56 if (HIWORD(name)) {
57 if (name[0]=='#') {
58 char buf[10];
60 lstrcpynWtoA(buf,name+1,10);
61 return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
63 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
64 (BYTE *) resdirptr +
65 sizeof(IMAGE_RESOURCE_DIRECTORY));
66 namelen = lstrlenW(name);
67 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
69 PIMAGE_RESOURCE_DIR_STRING_U str =
70 (PIMAGE_RESOURCE_DIR_STRING_U) (root +
71 entryTable[entrynum].u1.s.NameOffset);
72 if(namelen != str->Length)
73 continue;
74 if(CRTDLL__wcsnicmp(name,str->NameString,str->Length)==0)
75 return (PIMAGE_RESOURCE_DIRECTORY) (
76 root +
77 entryTable[entrynum].u2.s.OffsetToDirectory);
79 return NULL;
80 } else {
81 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
82 (BYTE *) resdirptr +
83 sizeof(IMAGE_RESOURCE_DIRECTORY) +
84 resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
85 for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
86 if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name)
87 return (PIMAGE_RESOURCE_DIRECTORY) (
88 root +
89 entryTable[entrynum].u2.s.OffsetToDirectory);
90 /* just use first entry if no default can be found */
91 if (allowdefault && !name && resdirptr->NumberOfIdEntries)
92 return (PIMAGE_RESOURCE_DIRECTORY) (
93 root +
94 entryTable[0].u2.s.OffsetToDirectory);
95 return NULL;
99 /**********************************************************************
100 * GetResDirEntryA
102 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
103 LPCSTR name, DWORD root,
104 BOOL allowdefault )
106 PIMAGE_RESOURCE_DIRECTORY retv;
107 LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name )
108 : (LPWSTR)name;
110 retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
112 if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
114 return retv;
117 /**********************************************************************
118 * PE_FindResourceEx32W
120 HANDLE PE_FindResourceExW(
121 WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
123 PIMAGE_RESOURCE_DIRECTORY resdirptr;
124 DWORD root;
125 HANDLE result;
126 PE_MODREF *pem = &(wm->binfmt.pe);
128 if (!pem || !pem->pe_resource)
129 return 0;
131 resdirptr = pem->pe_resource;
132 root = (DWORD) resdirptr;
133 if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
134 return 0;
135 if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
136 return 0;
137 result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
138 /* Try LANG_NEUTRAL, too */
139 if(!result)
140 return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
141 return result;
145 /**********************************************************************
146 * PE_LoadResource32
148 HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
150 if (!hRsrc || !wm || wm->type!=MODULE32_PE)
151 return 0;
152 return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
156 /**********************************************************************
157 * PE_SizeofResource32
159 DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
161 /* we don't need hModule */
162 if (!hRsrc)
163 return 0;
164 return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
167 /**********************************************************************
168 * PE_EnumResourceTypes32A
170 BOOL
171 PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
172 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
173 int i;
174 PIMAGE_RESOURCE_DIRECTORY resdir;
175 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
176 BOOL ret;
177 HANDLE heap = GetProcessHeap();
179 if (!pem || !pem->pe_resource)
180 return FALSE;
182 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
183 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
184 ret = FALSE;
185 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
186 LPSTR name;
188 if (et[i].u1.s.NameIsString)
189 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
190 else
191 name = (LPSTR)(int)et[i].u1.Id;
192 ret = lpfun(hmod,name,lparam);
193 if (HIWORD(name))
194 HeapFree(heap,0,name);
195 if (!ret)
196 break;
198 return ret;
201 /**********************************************************************
202 * PE_EnumResourceTypes32W
204 BOOL
205 PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
206 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
207 int i;
208 PIMAGE_RESOURCE_DIRECTORY resdir;
209 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
210 BOOL ret;
212 if (!pem || !pem->pe_resource)
213 return FALSE;
215 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
216 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
217 ret = FALSE;
218 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
219 LPWSTR type;
220 if (et[i].u1.s.NameIsString)
221 type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
222 else
223 type = (LPWSTR)(int)et[i].u1.Id;
225 ret = lpfun(hmod,type,lparam);
226 if (!ret)
227 break;
229 return ret;
232 /**********************************************************************
233 * PE_EnumResourceNames32A
235 BOOL
236 PE_EnumResourceNamesA(
237 HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
239 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
240 int i;
241 PIMAGE_RESOURCE_DIRECTORY resdir;
242 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
243 BOOL ret;
244 HANDLE heap = GetProcessHeap();
245 LPWSTR typeW;
247 if (!pem || !pem->pe_resource)
248 return FALSE;
249 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
250 if (HIWORD(type))
251 typeW = HEAP_strdupAtoW(heap,0,type);
252 else
253 typeW = (LPWSTR)type;
254 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
255 if (HIWORD(typeW))
256 HeapFree(heap,0,typeW);
257 if (!resdir)
258 return FALSE;
259 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
260 ret = FALSE;
261 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
262 LPSTR name;
264 if (et[i].u1.s.NameIsString)
265 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
266 else
267 name = (LPSTR)(int)et[i].u1.Id;
268 ret = lpfun(hmod,type,name,lparam);
269 if (HIWORD(name)) HeapFree(heap,0,name);
270 if (!ret)
271 break;
273 return ret;
276 /**********************************************************************
277 * PE_EnumResourceNames32W
279 BOOL
280 PE_EnumResourceNamesW(
281 HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
283 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
284 int i;
285 PIMAGE_RESOURCE_DIRECTORY resdir;
286 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
287 BOOL ret;
289 if (!pem || !pem->pe_resource)
290 return FALSE;
292 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
293 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
294 if (!resdir)
295 return FALSE;
296 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
297 ret = FALSE;
298 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
299 LPWSTR name;
300 if (et[i].u1.s.NameIsString)
301 name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
302 else
303 name = (LPWSTR)(int)et[i].u1.Id;
304 ret = lpfun(hmod,type,name,lparam);
305 if (!ret)
306 break;
308 return ret;
311 /**********************************************************************
312 * PE_EnumResourceNames32A
314 BOOL
315 PE_EnumResourceLanguagesA(
316 HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
317 LONG lparam
319 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
320 int i;
321 PIMAGE_RESOURCE_DIRECTORY resdir;
322 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
323 BOOL ret;
324 HANDLE heap = GetProcessHeap();
325 LPWSTR nameW,typeW;
327 if (!pem || !pem->pe_resource)
328 return FALSE;
330 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
331 if (HIWORD(name))
332 nameW = HEAP_strdupAtoW(heap,0,name);
333 else
334 nameW = (LPWSTR)name;
335 resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
336 if (HIWORD(nameW))
337 HeapFree(heap,0,nameW);
338 if (!resdir)
339 return FALSE;
340 if (HIWORD(type))
341 typeW = HEAP_strdupAtoW(heap,0,type);
342 else
343 typeW = (LPWSTR)type;
344 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
345 if (HIWORD(typeW))
346 HeapFree(heap,0,typeW);
347 if (!resdir)
348 return FALSE;
349 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
350 ret = FALSE;
351 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
352 /* languages are just ids... I hopem */
353 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
354 if (!ret)
355 break;
357 return ret;
360 /**********************************************************************
361 * PE_EnumResourceLanguages32W
363 BOOL
364 PE_EnumResourceLanguagesW(
365 HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
366 LONG lparam
368 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
369 int i;
370 PIMAGE_RESOURCE_DIRECTORY resdir;
371 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
372 BOOL ret;
374 if (!pem || !pem->pe_resource)
375 return FALSE;
377 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
378 resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
379 if (!resdir)
380 return FALSE;
381 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
382 if (!resdir)
383 return FALSE;
384 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
385 ret = FALSE;
386 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
387 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
388 if (!ret)
389 break;
391 return ret;