blob: 29f13c68387bd025c21980ef72845c828fdc6bb4 [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"
Alexandre Julliard5ea22472000-06-13 01:10:29 +000016#include "wine/unicode.h"
Jim Aston2e1cafa1999-03-14 16:35:05 +000017#include "windef.h"
Stephane Lussierbb3c1642000-05-05 18:17:52 +000018#include "winnls.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000019#include "pe_image.h"
Alexandre Julliard18f92e71996-07-17 20:02:21 +000020#include "module.h"
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000021#include "heap.h"
Alexandre Julliard77b99181997-09-14 17:17:23 +000022#include "task.h"
23#include "process.h"
Alexandre Julliard18f92e71996-07-17 20:02:21 +000024#include "stackframe.h"
25#include "neexe.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 Julliard5ea22472000-06-13 01:10:29 +000075 if(strncmpiW(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);
Stephane Lussierbb3c1642000-05-05 18:17:52 +0000139
140 /* Try with only the primary language set */
141 if (!result)
142 {
143 lang = MAKELANGID(PRIMARYLANGID(lang), SUBLANG_DEFAULT);
144 result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
145 }
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000146 /* Try LANG_NEUTRAL, too */
147 if(!result)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000148 return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000149 return result;
150}
151
152
153/**********************************************************************
154 * PE_LoadResource32
155 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000156HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000157{
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000158 if (!hRsrc || !wm || wm->type!=MODULE32_PE)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000159 return 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000160 return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000161}
162
163
164/**********************************************************************
165 * PE_SizeofResource32
166 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000167DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
Alexandre Julliard349a9531997-02-02 19:01:52 +0000168{
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000169 /* we don't need hModule */
170 if (!hRsrc)
171 return 0;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000172 return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000173}
174
175/**********************************************************************
176 * PE_EnumResourceTypes32A
177 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000178BOOL
179PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000180 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000181 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000182 PIMAGE_RESOURCE_DIRECTORY resdir;
183 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000184 BOOL ret;
185 HANDLE heap = GetProcessHeap();
Alexandre Julliard349a9531997-02-02 19:01:52 +0000186
Alexandre Julliard77b99181997-09-14 17:17:23 +0000187 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000188 return FALSE;
189
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000190 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
191 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000192 ret = FALSE;
193 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
194 LPSTR name;
195
Marcus Meissner423813e1999-07-04 12:44:29 +0000196 if (et[i].u1.s.NameIsString)
197 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000198 else
Marcus Meissner423813e1999-07-04 12:44:29 +0000199 name = (LPSTR)(int)et[i].u1.Id;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000200 ret = lpfun(hmod,name,lparam);
201 if (HIWORD(name))
202 HeapFree(heap,0,name);
203 if (!ret)
204 break;
205 }
206 return ret;
207}
208
209/**********************************************************************
210 * PE_EnumResourceTypes32W
211 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000212BOOL
213PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000214 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000215 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000216 PIMAGE_RESOURCE_DIRECTORY resdir;
217 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000218 BOOL ret;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000219
Alexandre Julliard77b99181997-09-14 17:17:23 +0000220 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000221 return FALSE;
222
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000223 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
224 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000225 ret = FALSE;
226 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
227 LPWSTR type;
Marcus Meissner423813e1999-07-04 12:44:29 +0000228 if (et[i].u1.s.NameIsString)
229 type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000230 else
Marcus Meissner423813e1999-07-04 12:44:29 +0000231 type = (LPWSTR)(int)et[i].u1.Id;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000232
233 ret = lpfun(hmod,type,lparam);
234 if (!ret)
235 break;
236 }
237 return ret;
238}
239
240/**********************************************************************
241 * PE_EnumResourceNames32A
242 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000243BOOL
244PE_EnumResourceNamesA(
245 HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
Alexandre Julliard349a9531997-02-02 19:01:52 +0000246) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000247 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000248 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000249 PIMAGE_RESOURCE_DIRECTORY resdir;
250 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000251 BOOL ret;
252 HANDLE heap = GetProcessHeap();
Alexandre Julliard349a9531997-02-02 19:01:52 +0000253 LPWSTR typeW;
254
Alexandre Julliard77b99181997-09-14 17:17:23 +0000255 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000256 return FALSE;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000257 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000258 if (HIWORD(type))
259 typeW = HEAP_strdupAtoW(heap,0,type);
260 else
261 typeW = (LPWSTR)type;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000262 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000263 if (HIWORD(typeW))
264 HeapFree(heap,0,typeW);
265 if (!resdir)
266 return FALSE;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000267 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000268 ret = FALSE;
269 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
270 LPSTR name;
271
Marcus Meissner423813e1999-07-04 12:44:29 +0000272 if (et[i].u1.s.NameIsString)
273 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000274 else
Marcus Meissner423813e1999-07-04 12:44:29 +0000275 name = (LPSTR)(int)et[i].u1.Id;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000276 ret = lpfun(hmod,type,name,lparam);
277 if (HIWORD(name)) HeapFree(heap,0,name);
278 if (!ret)
279 break;
280 }
281 return ret;
282}
283
284/**********************************************************************
285 * PE_EnumResourceNames32W
286 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000287BOOL
288PE_EnumResourceNamesW(
289 HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
Alexandre Julliard349a9531997-02-02 19:01:52 +0000290) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000291 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000292 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000293 PIMAGE_RESOURCE_DIRECTORY resdir;
294 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000295 BOOL ret;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000296
Alexandre Julliard77b99181997-09-14 17:17:23 +0000297 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000298 return FALSE;
299
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000300 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000301 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000302 if (!resdir)
303 return FALSE;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000304 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000305 ret = FALSE;
306 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
307 LPWSTR name;
Marcus Meissner423813e1999-07-04 12:44:29 +0000308 if (et[i].u1.s.NameIsString)
309 name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000310 else
Marcus Meissner423813e1999-07-04 12:44:29 +0000311 name = (LPWSTR)(int)et[i].u1.Id;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000312 ret = lpfun(hmod,type,name,lparam);
313 if (!ret)
314 break;
315 }
316 return ret;
317}
318
319/**********************************************************************
320 * PE_EnumResourceNames32A
321 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000322BOOL
323PE_EnumResourceLanguagesA(
324 HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
Alexandre Julliard349a9531997-02-02 19:01:52 +0000325 LONG lparam
326) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000327 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000328 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000329 PIMAGE_RESOURCE_DIRECTORY resdir;
330 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000331 BOOL ret;
332 HANDLE heap = GetProcessHeap();
Alexandre Julliard349a9531997-02-02 19:01:52 +0000333 LPWSTR nameW,typeW;
334
Alexandre Julliard77b99181997-09-14 17:17:23 +0000335 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000336 return FALSE;
337
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000338 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000339 if (HIWORD(name))
340 nameW = HEAP_strdupAtoW(heap,0,name);
341 else
342 nameW = (LPWSTR)name;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000343 resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000344 if (HIWORD(nameW))
345 HeapFree(heap,0,nameW);
346 if (!resdir)
347 return FALSE;
348 if (HIWORD(type))
349 typeW = HEAP_strdupAtoW(heap,0,type);
350 else
351 typeW = (LPWSTR)type;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000352 resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000353 if (HIWORD(typeW))
354 HeapFree(heap,0,typeW);
355 if (!resdir)
356 return FALSE;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000357 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000358 ret = FALSE;
359 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000360 /* languages are just ids... I hopem */
Alexandre Julliard349a9531997-02-02 19:01:52 +0000361 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
362 if (!ret)
363 break;
364 }
365 return ret;
366}
367
368/**********************************************************************
369 * PE_EnumResourceLanguages32W
370 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000371BOOL
372PE_EnumResourceLanguagesW(
373 HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
Alexandre Julliard349a9531997-02-02 19:01:52 +0000374 LONG lparam
375) {
Alexandre Julliard77b99181997-09-14 17:17:23 +0000376 PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000377 int i;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000378 PIMAGE_RESOURCE_DIRECTORY resdir;
379 PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000380 BOOL ret;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000381
Alexandre Julliard77b99181997-09-14 17:17:23 +0000382 if (!pem || !pem->pe_resource)
Alexandre Julliard349a9531997-02-02 19:01:52 +0000383 return FALSE;
384
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000385 resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000386 resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000387 if (!resdir)
388 return FALSE;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000389 resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000390 if (!resdir)
391 return FALSE;
Uwe Bonnes73d6c131998-10-16 09:30:33 +0000392 et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
Alexandre Julliard349a9531997-02-02 19:01:52 +0000393 ret = FALSE;
394 for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
395 ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
396 if (!ret)
397 break;
398 }
399 return ret;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000400}