blob: 9c752d3777072d10fbbf35e9a176936d23d7c2eb [file] [log] [blame]
Alexandre Julliardaca05781994-10-17 18:12:41 +00001/*
Alexandre Julliard18f92e71996-07-17 20:02:21 +00002 * PE (Portable Execute) File Resources
Alexandre Julliardaca05781994-10-17 18:12:41 +00003 *
Alexandre Julliard18f92e71996-07-17 20:02:21 +00004 * Copyright 1995 Thomas Sandford
5 * Copyright 1996 Martin von Loewis
Alexandre Julliardaca05781994-10-17 18:12:41 +00006 *
Alexandre Julliard18f92e71996-07-17 20:02:21 +00007 * Based on the Win16 resource handling code in loader/resource.c
8 * Copyright 1993 Robert J. Amstadt
9 * Copyright 1995 Alexandre Julliard
Alexandre Julliard349a9531997-02-02 19:01:52 +000010 * Copyright 1997 Marcus Meissner
Alexandre Julliardaca05781994-10-17 18:12:41 +000011 */
12
Alexandre Julliard21979011997-03-05 08:22:35 +000013#include <stdlib.h>
Alexandre Julliardaca05781994-10-17 18:12:41 +000014#include <sys/types.h>
Marcus Meissner04c3e1d1999-02-19 10:37:02 +000015#include "wine/winestring.h"
Jim Aston2e1cafa1999-03-14 16:35:05 +000016#include "windef.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000017#include "pe_image.h"
Alexandre Julliard18f92e71996-07-17 20:02:21 +000018#include "module.h"
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000019#include "heap.h"
Alexandre Julliard77b99181997-09-14 17:17:23 +000020#include "task.h"
21#include "process.h"
Alexandre Julliard18f92e71996-07-17 20:02:21 +000022#include "libres.h"
Alexandre Julliard18f92e71996-07-17 20:02:21 +000023#include "stackframe.h"
24#include "neexe.h"
Alexandre Julliard89f079b1999-08-08 18:54:47 +000025#include "crtdll.h"
Alexandre Julliarda099a551999-06-12 15:45:58 +000026#include "debugtools.h"
Alexandre Julliardaca05781994-10-17 18:12:41 +000027
Alexandre Julliard349a9531997-02-02 19:01:52 +000028/**********************************************************************
Alexandre Julliard77b99181997-09-14 17:17:23 +000029 * HMODULE32toPE_MODREF
Alexandre Julliard349a9531997-02-02 19:01:52 +000030 *
Alexandre Julliard77b99181997-09-14 17:17:23 +000031 * small helper function to get a PE_MODREF from a passed HMODULE32
Alexandre Julliard349a9531997-02-02 19:01:52 +000032 */
Alexandre Julliard77b99181997-09-14 17:17:23 +000033static PE_MODREF*
Alexandre Julliarda3960291999-02-26 11:11:13 +000034HMODULE32toPE_MODREF(HMODULE hmod) {
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000035 WINE_MODREF *wm;
Alexandre Julliard349a9531997-02-02 19:01:52 +000036
Ulrich Weigand1d90d691999-02-24 14:27:07 +000037 wm = MODULE32_LookupHMODULE( hmod );
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000038 if (!wm || wm->type!=MODULE32_PE)
39 return NULL;
40 return &(wm->binfmt.pe);
Alexandre Julliard349a9531997-02-02 19:01:52 +000041}
Alexandre Julliard18f92e71996-07-17 20:02:21 +000042
43/**********************************************************************
44 * GetResDirEntryW
45 *
46 * Helper function - goes down one level of PE resource tree
47 *
48 */
Uwe Bonnes73d6c131998-10-16 09:30:33 +000049PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
Alexandre Julliard44ed71f1997-12-21 19:17:50 +000050 LPCWSTR name,DWORD root,
Alexandre Julliarda3960291999-02-26 11:11:13 +000051 BOOL allowdefault)
Alexandre Julliardaca05781994-10-17 18:12:41 +000052{
Alexandre Julliard18f92e71996-07-17 20:02:21 +000053 int entrynum;
Uwe Bonnes73d6c131998-10-16 09:30:33 +000054 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
Alexandre Julliard01d63461997-01-20 19:43:45 +000055 int namelen;
Alexandre Julliardaca05781994-10-17 18:12:41 +000056
Alexandre Julliard18f92e71996-07-17 20:02:21 +000057 if (HIWORD(name)) {
Alexandre Julliard21979011997-03-05 08:22:35 +000058 if (name[0]=='#') {
59 char buf[10];
60
61 lstrcpynWtoA(buf,name+1,10);
Alexandre Julliard44ed71f1997-12-21 19:17:50 +000062 return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
Alexandre Julliard21979011997-03-05 08:22:35 +000063 }
Uwe Bonnes73d6c131998-10-16 09:30:33 +000064 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
Alexandre Julliard18f92e71996-07-17 20:02:21 +000065 (BYTE *) resdirptr +
66 sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliarda3960291999-02-26 11:11:13 +000067 namelen = lstrlenW(name);
Alexandre Julliard18f92e71996-07-17 20:02:21 +000068 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
69 {
Uwe Bonnes73d6c131998-10-16 09:30:33 +000070 PIMAGE_RESOURCE_DIR_STRING_U str =
71 (PIMAGE_RESOURCE_DIR_STRING_U) (root +
Alexandre Julliard01d63461997-01-20 19:43:45 +000072 entryTable[entrynum].u1.s.NameOffset);
Alexandre Julliard18f92e71996-07-17 20:02:21 +000073 if(namelen != str->Length)
74 continue;
Alexandre Julliard89f079b1999-08-08 18:54:47 +000075 if(CRTDLL__wcsnicmp(name,str->NameString,str->Length)==0)
Uwe Bonnes73d6c131998-10-16 09:30:33 +000076 return (PIMAGE_RESOURCE_DIRECTORY) (
Alexandre Julliard18f92e71996-07-17 20:02:21 +000077 root +
Alexandre Julliard01d63461997-01-20 19:43:45 +000078 entryTable[entrynum].u2.s.OffsetToDirectory);
Alexandre Julliardaca05781994-10-17 18:12:41 +000079 }
Alexandre Julliard18f92e71996-07-17 20:02:21 +000080 return NULL;
81 } else {
Uwe Bonnes73d6c131998-10-16 09:30:33 +000082 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
Alexandre Julliard18f92e71996-07-17 20:02:21 +000083 (BYTE *) resdirptr +
84 sizeof(IMAGE_RESOURCE_DIRECTORY) +
85 resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
86 for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
Alexandre Julliard01d63461997-01-20 19:43:45 +000087 if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name)
Uwe Bonnes73d6c131998-10-16 09:30:33 +000088 return (PIMAGE_RESOURCE_DIRECTORY) (
Alexandre Julliard18f92e71996-07-17 20:02:21 +000089 root +
Alexandre Julliard01d63461997-01-20 19:43:45 +000090 entryTable[entrynum].u2.s.OffsetToDirectory);
Alexandre Julliardac9c9b01996-07-28 18:50:11 +000091 /* just use first entry if no default can be found */
Alexandre Julliard44ed71f1997-12-21 19:17:50 +000092 if (allowdefault && !name && resdirptr->NumberOfIdEntries)
Uwe Bonnes73d6c131998-10-16 09:30:33 +000093 return (PIMAGE_RESOURCE_DIRECTORY) (
Alexandre Julliardac9c9b01996-07-28 18:50:11 +000094 root +
Alexandre Julliard01d63461997-01-20 19:43:45 +000095 entryTable[0].u2.s.OffsetToDirectory);
Alexandre Julliard18f92e71996-07-17 20:02:21 +000096 return NULL;
97 }
Alexandre Julliardaca05781994-10-17 18:12:41 +000098}
99
100/**********************************************************************
Ulrich Weigand9a614951999-01-31 10:13:13 +0000101 * GetResDirEntryA
102 */
103PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
104 LPCSTR name, DWORD root,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000105 BOOL allowdefault )
Ulrich Weigand9a614951999-01-31 10:13:13 +0000106{
107 PIMAGE_RESOURCE_DIRECTORY retv;
108 LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name )
109 : (LPWSTR)name;
110
111 retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
112
113 if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
114
115 return retv;
116}
117
118/**********************************************************************
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000119 * PE_FindResourceEx32W
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000120 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000121HANDLE PE_FindResourceExW(
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000122 WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
Alexandre Julliard01d63461997-01-20 19:43:45 +0000123) {
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000124 PIMAGE_RESOURCE_DIRECTORY resdirptr;
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000125 DWORD root;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000126 HANDLE result;
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000127 PE_MODREF *pem = &(wm->binfmt.pe);
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000128
Alexandre Julliard77b99181997-09-14 17:17:23 +0000129 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000130 return 0;
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000131
Alexandre Julliard77b99181997-09-14 17:17:23 +0000132 resdirptr = pem->pe_resource;
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000133 root = (DWORD) resdirptr;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000134 if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000135 return 0;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000136 if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000137 return 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000138 result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000139 /* Try LANG_NEUTRAL, too */
140 if(!result)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000141 return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000142 return result;
143}
144
145
146/**********************************************************************
147 * PE_LoadResource32
148 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000149HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000150{
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000151 if (!hRsrc || !wm || wm->type!=MODULE32_PE)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000152 return 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000153 return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000154}
155
156
157/**********************************************************************
158 * PE_SizeofResource32
159 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000160DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
Alexandre Julliard349a9531997-02-02 19:01:52 +0000161{
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000162 /* we don't need hModule */
163 if (!hRsrc)
164 return 0;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000165 return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000166}
167
168/**********************************************************************
169 * PE_EnumResourceTypes32A
170 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000171BOOL
172PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000173 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000174 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000175 PIMAGE_RESOURCE_DIRECTORY resdir;
176 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000177 BOOL ret;
178 HANDLE heap = GetProcessHeap();
Alexandre Julliard349a9531997-02-02 19:01:52 +0000179
Alexandre Julliard77b99181997-09-14 17:17:23 +0000180 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000181 return FALSE;
182
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000183 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
184 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000185 ret = FALSE;
186 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
187 LPSTR name;
188
Marcus Meissner423813e1999-07-04 12:44:29 +0000189 if (et[i].u1.s.NameIsString)
190 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000191 else
Marcus Meissner423813e1999-07-04 12:44:29 +0000192 name = (LPSTR)(int)et[i].u1.Id;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000193 ret = lpfun(hmod,name,lparam);
194 if (HIWORD(name))
195 HeapFree(heap,0,name);
196 if (!ret)
197 break;
198 }
199 return ret;
200}
201
202/**********************************************************************
203 * PE_EnumResourceTypes32W
204 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000205BOOL
206PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000207 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000208 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000209 PIMAGE_RESOURCE_DIRECTORY resdir;
210 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000211 BOOL ret;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000212
Alexandre Julliard77b99181997-09-14 17:17:23 +0000213 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000214 return FALSE;
215
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000216 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
217 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000218 ret = FALSE;
219 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
220 LPWSTR type;
Marcus Meissner423813e1999-07-04 12:44:29 +0000221 if (et[i].u1.s.NameIsString)
222 type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000223 else
Marcus Meissner423813e1999-07-04 12:44:29 +0000224 type = (LPWSTR)(int)et[i].u1.Id;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000225
226 ret = lpfun(hmod,type,lparam);
227 if (!ret)
228 break;
229 }
230 return ret;
231}
232
233/**********************************************************************
234 * PE_EnumResourceNames32A
235 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000236BOOL
237PE_EnumResourceNamesA(
238 HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
Alexandre Julliard349a9531997-02-02 19:01:52 +0000239) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000240 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000241 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000242 PIMAGE_RESOURCE_DIRECTORY resdir;
243 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000244 BOOL ret;
245 HANDLE heap = GetProcessHeap();
Alexandre Julliard349a9531997-02-02 19:01:52 +0000246 LPWSTR typeW;
247
Alexandre Julliard77b99181997-09-14 17:17:23 +0000248 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000249 return FALSE;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000250 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000251 if (HIWORD(type))
252 typeW = HEAP_strdupAtoW(heap,0,type);
253 else
254 typeW = (LPWSTR)type;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000255 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000256 if (HIWORD(typeW))
257 HeapFree(heap,0,typeW);
258 if (!resdir)
259 return FALSE;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000260 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000261 ret = FALSE;
262 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
263 LPSTR name;
264
Marcus Meissner423813e1999-07-04 12:44:29 +0000265 if (et[i].u1.s.NameIsString)
266 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000267 else
Marcus Meissner423813e1999-07-04 12:44:29 +0000268 name = (LPSTR)(int)et[i].u1.Id;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000269 ret = lpfun(hmod,type,name,lparam);
270 if (HIWORD(name)) HeapFree(heap,0,name);
271 if (!ret)
272 break;
273 }
274 return ret;
275}
276
277/**********************************************************************
278 * PE_EnumResourceNames32W
279 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000280BOOL
281PE_EnumResourceNamesW(
282 HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
Alexandre Julliard349a9531997-02-02 19:01:52 +0000283) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000284 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000285 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000286 PIMAGE_RESOURCE_DIRECTORY resdir;
287 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000288 BOOL ret;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000289
Alexandre Julliard77b99181997-09-14 17:17:23 +0000290 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000291 return FALSE;
292
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000293 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000294 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000295 if (!resdir)
296 return FALSE;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000297 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000298 ret = FALSE;
299 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
300 LPWSTR name;
Marcus Meissner423813e1999-07-04 12:44:29 +0000301 if (et[i].u1.s.NameIsString)
302 name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000303 else
Marcus Meissner423813e1999-07-04 12:44:29 +0000304 name = (LPWSTR)(int)et[i].u1.Id;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000305 ret = lpfun(hmod,type,name,lparam);
306 if (!ret)
307 break;
308 }
309 return ret;
310}
311
312/**********************************************************************
313 * PE_EnumResourceNames32A
314 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000315BOOL
316PE_EnumResourceLanguagesA(
317 HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
Alexandre Julliard349a9531997-02-02 19:01:52 +0000318 LONG lparam
319) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000320 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000321 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000322 PIMAGE_RESOURCE_DIRECTORY resdir;
323 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000324 BOOL ret;
325 HANDLE heap = GetProcessHeap();
Alexandre Julliard349a9531997-02-02 19:01:52 +0000326 LPWSTR nameW,typeW;
327
Alexandre Julliard77b99181997-09-14 17:17:23 +0000328 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000329 return FALSE;
330
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000331 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000332 if (HIWORD(name))
333 nameW = HEAP_strdupAtoW(heap,0,name);
334 else
335 nameW = (LPWSTR)name;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000336 resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000337 if (HIWORD(nameW))
338 HeapFree(heap,0,nameW);
339 if (!resdir)
340 return FALSE;
341 if (HIWORD(type))
342 typeW = HEAP_strdupAtoW(heap,0,type);
343 else
344 typeW = (LPWSTR)type;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000345 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000346 if (HIWORD(typeW))
347 HeapFree(heap,0,typeW);
348 if (!resdir)
349 return FALSE;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000350 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000351 ret = FALSE;
352 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000353 /* languages are just ids... I hopem */
Alexandre Julliard349a9531997-02-02 19:01:52 +0000354 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
355 if (!ret)
356 break;
357 }
358 return ret;
359}
360
361/**********************************************************************
362 * PE_EnumResourceLanguages32W
363 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000364BOOL
365PE_EnumResourceLanguagesW(
366 HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
Alexandre Julliard349a9531997-02-02 19:01:52 +0000367 LONG lparam
368) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000369 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000370 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000371 PIMAGE_RESOURCE_DIRECTORY resdir;
372 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000373 BOOL ret;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000374
Alexandre Julliard77b99181997-09-14 17:17:23 +0000375 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000376 return FALSE;
377
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000378 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000379 resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000380 if (!resdir)
381 return FALSE;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000382 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000383 if (!resdir)
384 return FALSE;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000385 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000386 ret = FALSE;
387 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
388 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
389 if (!ret)
390 break;
391 }
392 return ret;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000393}