source: trunk/src/kernel32/winimgres.cpp@ 3765

Last change on this file since 3765 was 3765, checked in by sandervl, 25 years ago

findresource cleanup

File size: 24.8 KB
Line 
1/* $Id: winimgres.cpp,v 1.42 2000-06-28 18:08:36 sandervl Exp $ */
2
3/*
4 * Win32 PE Image class (resource methods)
5 *
6 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 * TODO: Check created resource objects before loading the resource!
12 * TODO: Support for 'DIB' resource type (VPBuddy)
13 *
14 */
15#include <os2win.h>
16#include <winnls.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20
21#include <misc.h>
22#include <winimagebase.h>
23#include <unicode.h>
24#include <heapstring.h>
25#include "pefile.h"
26#include "oslibmisc.h"
27
28#define DBG_LOCALLOG DBG_winimgres
29#include "dbglocal.h"
30
31#define MAX_RES 17
32typedef struct {
33 char *typename;
34 int namelen;
35} STD_RESTYPE;
36
37STD_RESTYPE ResType[MAX_RES] =
38 { {NULL, 0},
39 {"CURSOR", 6},
40 {"BITMAP", 6},
41 {"ICON", 4},
42 {"MENU", 4},
43 {"DIALOG", 6},
44 {"STRING", 6},
45 {"FONTDIR", 7},
46 {"FONT", 4},
47 {"ACCELERATOR", 11},
48 {"RCDATA", 6},
49 {"MESSAGETABLE",12},
50 {"GROUP_CURSOR",12},
51 {NULL, 0},
52 {"GROUP_ICON", 10},
53 {NULL, 0},
54 {"VERSION", 7}
55 };
56
57//SvL: VPBuddy bugfix, seems to load bitmaps with type name 'DIB'
58#define BITMAP_TYPENAME2 "DIB"
59
60//******************************************************************************
61//******************************************************************************
62ULONG Win32ImageBase::getResourceSizeA(LPSTR lpszName, LPSTR lpszType, ULONG lang)
63{
64 PIMAGE_RESOURCE_DATA_ENTRY pData = NULL;
65
66 pData = (PIMAGE_RESOURCE_DATA_ENTRY)findResourceA(lpszName, lpszType, lang);
67 if(pData == NULL) {
68 dprintf(("Win32ImageBase::getPEResourceSizeA: couldn't find resource %x (type %x, lang %x)", lpszName, lpszType, lang));
69 return 0;
70 }
71 return pData->Size;
72}
73//******************************************************************************
74//******************************************************************************
75ULONG Win32ImageBase::getResourceSizeW(LPWSTR lpszName, LPWSTR lpszType, ULONG lang)
76{
77 PIMAGE_RESOURCE_DATA_ENTRY pData = NULL;
78
79 pData = (PIMAGE_RESOURCE_DATA_ENTRY)findResourceW(lpszName, lpszType, lang);
80 if(pData == NULL) {
81 dprintf(("Win32ImageBase::getResourceSizeW: couldn't find resource %x (type %x, lang %x)", lpszName, lpszType, lang));
82 return 0;
83 }
84 return pData->Size;
85}
86//******************************************************************************
87//Returns pointer to data of resource handle
88//******************************************************************************
89char *Win32ImageBase::getResourceAddr(HRSRC hResource)
90{
91 PIMAGE_RESOURCE_DATA_ENTRY pData = (PIMAGE_RESOURCE_DATA_ENTRY)hResource;
92
93 if(pData == NULL) {
94 DebugInt3();
95 return NULL;
96 }
97 //ulRVAResourceSection contains the relative virtual address (relative to the start of the image)
98 //for the resource section (images loaded by the pe.exe and pe2lx/win32k)
99 //For LX images, this is 0 as OffsetToData contains a relative offset
100 return (char *)((char *)pResRootDir + (pData->OffsetToData - ulRVAResourceSection));
101}
102//******************************************************************************
103//******************************************************************************
104ULONG Win32ImageBase::getResourceSize(HRSRC hResource)
105{
106 PIMAGE_RESOURCE_DATA_ENTRY pData = (PIMAGE_RESOURCE_DATA_ENTRY)hResource;
107
108 if(pData == NULL) {
109 DebugInt3();
110 return NULL;
111 }
112 return pData->Size;
113}
114//******************************************************************************
115//findResource returns the pointer of the resource's IMAGE_RESOURCE_DATA_ENTRY structure
116//******************************************************************************
117HRSRC Win32ImageBase::findResourceA(LPCSTR lpszName, LPSTR lpszType, ULONG lang)
118{
119 PIMAGE_RESOURCE_DIRECTORY pResDirRet;
120 int typelen;
121 HRSRC hRes;
122
123 if(HIWORD(lpszType) != 0)
124 {
125 typelen = strlen(lpszType);
126
127 for(int i=0;i<MAX_RES;i++) {
128 if(ResType[i].namelen &&
129 ResType[i].namelen == typelen &&
130 stricmp(lpszType, ResType[i].typename) == 0)
131 break;
132 }
133 if(i != MAX_RES) {//standard res type
134 lpszType = (LPSTR)i;
135 }
136 }
137 pResDirRet = getResSubDirA(pResRootDir, lpszType);
138 if(!pResDirRet) {
139 SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
140 return NULL;
141 }
142 pResDirRet = getResSubDirA(pResDirRet, lpszName);
143 if(!pResDirRet) {
144 SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
145 return NULL;
146 }
147
148 switch(lang) {
149 case LANG_SYSTEM_DEFAULT:
150 lang = GetSystemDefaultLangID();
151 break;
152 case LANG_USER_DEFAULT:
153 lang = GetUserDefaultLangID();
154 break;
155 case LANG_NEUTRAL:
156 //TODO: Not correct; should take language associated with current thread
157 lang = LANG_NEUTRAL;
158 break;
159 case LANG_GETFIRST:
160 lang = GetUserDefaultLangID();
161 break;
162 }
163
164 hRes = (HRSRC)getResDataLang(pResDirRet, lang);
165 if(!hRes) {
166 //try primary language with default sublang
167 lang = MAKELANGID(PRIMARYLANGID(lang), SUBLANG_DEFAULT);
168 hRes = (HRSRC)getResDataLang(pResDirRet, lang);
169 if(!hRes) {
170 //try neutral language or get first entry if nothing found
171 hRes = (HRSRC)getResDataLang(pResDirRet, LANG_NEUTRAL, TRUE);
172 }
173 }
174
175 if((ULONG)lpszName != ID_GETFIRST && HIWORD(lpszName)) {
176 dprintf(("FindResource %s: resource %s (type %x, lang %x)", szModule, lpszName, lpszType, lang));
177 }
178 else dprintf(("FindResource %s: resource %x (type %x, lang %x)", szModule, lpszName, lpszType, lang));
179
180 return hRes;
181}
182//******************************************************************************
183//******************************************************************************
184HRSRC Win32ImageBase::findResourceW(LPWSTR lpszName, LPWSTR lpszType, ULONG lang)
185{
186 PIMAGE_RESOURCE_DIRECTORY pResDirRet;
187 char *astring1 = NULL;
188 int typelen;
189 HRSRC hRes;
190
191 if(HIWORD(lpszType) != 0 && lpszType[0] != (WCHAR)'#')
192 {
193 astring1 = UnicodeToAsciiString(lpszType);
194 typelen = strlen(astring1);
195
196 for(int i=0;i<MAX_RES;i++) {
197 if(ResType[i].namelen &&
198 ResType[i].namelen == typelen &&
199 stricmp(astring1, ResType[i].typename) == 0)
200 break;
201 }
202 if(i != MAX_RES) {//standard res type
203 lpszType = (LPWSTR)i;
204 }
205 FreeAsciiString(astring1);
206 }
207 pResDirRet = getResSubDirW(pResRootDir, lpszType);
208 if(!pResDirRet) {
209 SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
210 return NULL;
211 }
212 pResDirRet = getResSubDirW(pResDirRet, lpszName);
213 if(!pResDirRet) {
214 SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
215 return NULL;
216 }
217
218 switch(lang) {
219 case LANG_SYSTEM_DEFAULT:
220 lang = GetSystemDefaultLangID();
221 break;
222 case LANG_USER_DEFAULT:
223 lang = GetUserDefaultLangID();
224 break;
225 case LANG_NEUTRAL:
226 //TODO: Not correct; should take language associated with current thread
227 lang = LANG_NEUTRAL;
228 break;
229 case LANG_GETFIRST:
230 lang = GetUserDefaultLangID();
231 break;
232 }
233
234 hRes = (HRSRC)getResDataLang(pResDirRet, lang);
235 if(!hRes) {
236 //try primary language with default sublang
237 lang = MAKELANGID(PRIMARYLANGID(lang), SUBLANG_DEFAULT);
238 hRes = (HRSRC)getResDataLang(pResDirRet, lang);
239 if(!hRes) {
240 //try neutral language or get first entry if nothing found
241 hRes = (HRSRC)getResDataLang(pResDirRet, LANG_NEUTRAL, TRUE);
242 }
243 }
244
245 return hRes;
246}
247//******************************************************************************
248//******************************************************************************
249ULONG Win32ImageBase::getVersionSize()
250{
251 return getResourceSizeW((LPWSTR)1, (LPWSTR)NTRT_VERSION);
252}
253//******************************************************************************
254//******************************************************************************
255BOOL Win32ImageBase::getVersionStruct(char *verstruct, ULONG bufLength)
256{
257 HRSRC hRes;
258
259 if(verstruct == NULL || bufLength == 0) {
260 SetLastError(ERROR_INVALID_PARAMETER);
261 return FALSE;
262 }
263 hRes = findResourceW((LPWSTR)ID_GETFIRST, (LPWSTR)NTRT_VERSION, LANG_GETFIRST);
264 if(hRes == NULL) {
265 //last error already set by findResourceW
266 dprintf(("Win32PeLdrImage::getVersionStruct: couldn't find version resource!"));
267 return 0;
268 }
269 memcpy(verstruct, getResourceAddr(hRes), min(bufLength, getResourceSize(hRes)));
270 return TRUE;
271}
272
273
274/**
275 * The EnumResourceNames function searches a module for each
276 * resource of the specified type and passes the name of each
277 * resource it locates to an application-defined callback function
278 *
279 * @returns If the function succeeds, the return value is nonzero.
280 * If the function fails, the return value is zero
281 * @param hmod The specified module handle.
282 * @param lpszType pointer to resource type
283 * @param lpEnumFunc pointer to callback function
284 * @param lParam application-defined parameter
285 * @sketch IF not resources in module THEN return fail.
286 * Validate parameters.
287 * Get the subdirectory for the specified type.
288 * IF found THEN
289 * BEGIN
290 * Find the number of directory entries.
291 * Find directory entries.
292 * LOOP thru all entries while the callback function returns true
293 * BEGIN
294 * Name = pointer to ASCII name string or Id.
295 * call callback function.
296 * END
297 * END
298 * ELSE
299 * fail.
300 * return
301 * @status completely implemented and tested.
302 * @author knut st. osmundsen
303 * @remark The EnumResourceNames function continues to enumerate resource
304 * names until the callback function returns FALSE or all resource
305 * names have been enumerated
306 */
307BOOL Win32ImageBase::enumResourceNamesA(HMODULE hmod,
308 LPCTSTR lpszType,
309 ENUMRESNAMEPROCA lpEnumFunc,
310 LONG lParam)
311{
312 BOOL fRet;
313 PIMAGE_RESOURCE_DIRECTORY pResDirOurType;
314 PIMAGE_RESOURCE_DIRECTORY_ENTRY paResDirEntries;
315
316 if (pResRootDir == NULL)
317 {
318 SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
319 return FALSE;
320 }
321
322 /* validate parameters - FIXME... Exception handler??? */
323 if ((ULONG)lpszType >= 0xc0000000) //....
324 {
325 SetLastError(ERROR_INVALID_PARAMETER);
326 return FALSE;
327 }
328
329 if ((ULONG)lpEnumFunc < 0x10000 || (ULONG)lpEnumFunc >= 0xc0000000)
330 {
331 SetLastError(ERROR_NOACCESS);
332 return FALSE;
333 }
334
335 //reminder:
336 //1st level -> types
337 //2nd level -> names
338 //3rd level -> language
339
340 pResDirOurType = getResSubDirA(pResRootDir, lpszType);
341 if (pResDirOurType != NULL)
342 {
343 char *pszASCII = NULL;
344 unsigned cch = 0;
345 unsigned cResEntries;
346 unsigned i;
347
348 fRet = TRUE;
349 cResEntries = pResDirOurType->NumberOfNamedEntries + pResDirOurType->NumberOfIdEntries;
350 paResDirEntries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG)pResDirOurType + sizeof(*pResDirOurType));
351 for (i = 0; i < cResEntries && fRet; i++)
352 {
353 LPSTR lpszName;
354
355 if (paResDirEntries[i].u1.s.NameIsString)
356 {
357 PIMAGE_RESOURCE_DIR_STRING_U pResDirString =
358 (PIMAGE_RESOURCE_DIR_STRING_U)(paResDirEntries[i].u1.s.NameOffset + (ULONG)pResRootDir);
359
360 /* ASCII buffer allocation/adjustment? */
361 if (cch <= pResDirString->Length)
362 {
363 void *pszTmp;
364 cch = max(pResDirString->Length + 1, 32);
365 pszTmp = pszASCII != NULL ? realloc(pszASCII, cch) : malloc(cch);
366 if (pszTmp == NULL)
367 {
368 fRet = FALSE;
369 break;
370 }
371 pszASCII = (char*)pszTmp;
372 }
373 lstrcpynWtoA(pszASCII, pResDirString->NameString, pResDirString->Length+1);
374 lpszName = pszASCII;
375 }
376 else
377 lpszName = (LPSTR)paResDirEntries[i].u1.Id;
378
379 fRet = lpEnumFunc(hmod, lpszType, lpszName, lParam);
380 }
381
382 if (pszASCII != NULL)
383 free(pszASCII);
384 }
385 else
386 {
387 SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
388 fRet = FALSE;
389 }
390
391 return fRet > 0 ? TRUE : FALSE;
392}
393
394
395/**
396 * The EnumResourceNames function searches a module for each
397 * resource of the specified type and passes the name of each
398 * resource it locates to an application-defined callback function
399 *
400 * @returns If the function succeeds, the return value is nonzero.
401 * If the function fails, the return value is zero
402 * @param hmod The specified module handle.
403 * @param lpszType pointer to resource type
404 * @param lpEnumFunc pointer to callback function
405 * @param lParam application-defined parameter
406 * @sketch IF not resources in module THEN return fail.
407 * Validate parameters.
408 * Get the subdirectory for the specified type.
409 * IF found THEN
410 * BEGIN
411 * Find the number of directory entries.
412 * Find directory entries.
413 * LOOP thru all entries while the callback function returns true
414 * BEGIN
415 * Name = pointer to ASCII name string or Id.
416 * call callback function.
417 * END
418 * END
419 * ELSE
420 * fail.
421 * return
422 * @status completely implemented and tested.
423 * @author knut st. osmundsen
424 * @remark The EnumResourceNames function continues to enumerate resource
425 * names until the callback function returns FALSE or all resource
426 * names have been enumerated
427 */
428BOOL Win32ImageBase::enumResourceNamesW(HMODULE hmod,
429 LPCWSTR lpszType,
430 ENUMRESNAMEPROCW lpEnumFunc,
431 LONG lParam)
432{
433 BOOL fRet;
434 PIMAGE_RESOURCE_DIRECTORY pResDirOurType;
435 PIMAGE_RESOURCE_DIRECTORY_ENTRY paResDirEntries;
436
437 if (pResRootDir == NULL)
438 {
439 SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
440 return FALSE;
441 }
442
443 /* validate parameters - FIXME... Exception handler??? */
444 if ((ULONG)lpszType >= 0xc0000000) //....
445 {
446 SetLastError(ERROR_INVALID_PARAMETER);
447 return FALSE;
448 }
449
450 if ((ULONG)lpEnumFunc < 0x10000 || (ULONG)lpEnumFunc >= 0xc0000000)
451 {
452 SetLastError(ERROR_NOACCESS);
453 return FALSE;
454 }
455
456
457 //reminder:
458 //1st level -> types
459 //2nd level -> names
460 //3rd level -> language
461
462 pResDirOurType = getResSubDirW(pResRootDir, lpszType);
463 if (pResDirOurType != NULL)
464 {
465 unsigned cResEntries;
466 unsigned i;
467
468 fRet = TRUE;
469 cResEntries = pResDirOurType->NumberOfNamedEntries + pResDirOurType->NumberOfIdEntries;
470 paResDirEntries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG)pResDirOurType + sizeof(*pResDirOurType));
471 for (i = 0; i < cResEntries && fRet; i++)
472 {
473 LPWSTR lpszName;
474
475 if (paResDirEntries[i].u1.s.NameIsString)
476 lpszName = (LPWSTR)(paResDirEntries[i].u1.s.NameOffset + (ULONG)pResRootDir + 2);
477 else
478 lpszName = (LPWSTR)paResDirEntries[i].u1.Id;
479
480 fRet = lpEnumFunc(hmod, lpszType, lpszName, lParam);
481 }
482 }
483 else
484 {
485 SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
486 fRet = FALSE;
487 }
488
489 return fRet > 0;
490}
491
492
493
494/**
495 * This function finds a resource (sub)directory within a given resource directory.
496 * @returns Pointer to resource directory. NULL if not found or not a directory.
497 * @param pResDirToSearch Pointer to resource directory to search. (any level)
498 * @param lpszName Resource ID string.
499 * @sketch
500 * @status completely implemented
501 * @author knut st. osmundsen
502 */
503PIMAGE_RESOURCE_DIRECTORY Win32ImageBase::getResSubDirW(PIMAGE_RESOURCE_DIRECTORY pResDirToSearch,
504 LPCWSTR lpszName)
505{
506 PIMAGE_RESOURCE_DIRECTORY_ENTRY paResDirEntries;
507 int i;
508 int idName = -1;
509
510 /* lpszName */
511 if ((ULONG)lpszName != ID_GETFIRST && HIWORD(lpszName) != 0)
512 {
513 if (lpszName[0] == '#')
514 {
515 char szBuf[10];
516 lstrcpynWtoA(szBuf, (WCHAR*)(lpszName + 1), sizeof(szBuf));
517 idName = atoi(szBuf);
518 }
519 }
520 else
521 idName = (int)lpszName;
522
523 paResDirEntries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG)pResDirToSearch + sizeof(*pResDirToSearch));
524 if(idName == ID_GETFIRST) {
525 return paResDirEntries[0].u2.s.DataIsDirectory ?
526 (PIMAGE_RESOURCE_DIRECTORY) (paResDirEntries[0].u2.s.OffsetToDirectory + (ULONG)pResRootDir)
527 : NULL;
528 }
529
530 if (idName != -1)
531 { /* idName */
532 paResDirEntries += pResDirToSearch->NumberOfNamedEntries;
533
534 for (i = 0; i < pResDirToSearch->NumberOfIdEntries; i++)
535 if (paResDirEntries[i].u1.Id == (WORD)idName)
536 return paResDirEntries[i].u2.s.DataIsDirectory ?
537 (PIMAGE_RESOURCE_DIRECTORY) (paResDirEntries[i].u2.s.OffsetToDirectory + (ULONG)pResRootDir /*?*/
538 /*- ulRVAResourceSection*/)
539 : NULL;
540 }
541 else
542 { /* string name */
543 int cusName = lstrlenW(lpszName);
544
545 for (i = 0; i < pResDirToSearch->NumberOfNamedEntries; i++)
546 {
547 PIMAGE_RESOURCE_DIR_STRING_U pResDirStr =
548 (PIMAGE_RESOURCE_DIR_STRING_U)(paResDirEntries[i].u1.s.NameOffset + (ULONG)pResRootDir /*?*/);
549
550 //SvL: Must do case insensitive string compare here
551 if (pResDirStr->Length == cusName
552 && lstrncmpiW(pResDirStr->NameString, lpszName, cusName) == 0)
553 {
554 return paResDirEntries[i].u2.s.DataIsDirectory ?
555 (PIMAGE_RESOURCE_DIRECTORY) (paResDirEntries[i].u2.s.OffsetToDirectory + (ULONG)pResRootDir
556 /*- ulRVAResourceSection*/)
557 : NULL;
558 }
559 }
560 }
561
562 return NULL;
563}
564
565/**
566 * This function finds a resource (sub)directory within a given resource directory.
567 * @returns Pointer to resource directory. NULL if not found or not a directory.
568 * @param pResDirToSearch Pointer to resource directory to search. (any level)
569 * @param lpszName Resource ID string.
570 * @sketch
571 * @status completely implemented
572 * @author knut st. osmundsen
573 */
574PIMAGE_RESOURCE_DIRECTORY Win32ImageBase::getResSubDirA(PIMAGE_RESOURCE_DIRECTORY pResDirToSearch,
575 LPCTSTR lpszName)
576{
577 PIMAGE_RESOURCE_DIRECTORY pResDirRet;
578 LPCWSTR lpszwName;
579
580 /* lpszName */
581 if ((ULONG)lpszName != ID_GETFIRST && HIWORD(lpszName) != 0)
582 {
583 lpszwName = AsciiToUnicodeString((char*)lpszName);
584 if (lpszwName == NULL)
585 return NULL;
586 }
587 else
588 lpszwName = (LPWSTR)lpszName;
589
590 pResDirRet = getResSubDirW(pResDirToSearch, lpszwName);
591
592 if ((ULONG)lpszName != ID_GETFIRST && HIWORD(lpszwName) != 0)
593 free((void*)lpszwName);
594
595 return pResDirRet;
596}
597//******************************************************************************
598/**
599 * This function finds a resource data entry within a given resource directory.
600 * @returns Pointer to resource data entry. NULL if not found
601 * @param pResDirToSearch Pointer to resource directory to search. (lang level)
602 * @param language Resource language id
603 * @param fGetDefault TRUE -> get first available resource if not found
604 * @sketch
605 * @status completely implemented
606 * @author Sander van Leeuwen
607 */
608//******************************************************************************
609PIMAGE_RESOURCE_DATA_ENTRY
610 Win32ImageBase::getResDataLang(PIMAGE_RESOURCE_DIRECTORY pResDirToSearch,
611 ULONG language, BOOL fGetDefault)
612{
613 PIMAGE_RESOURCE_DIRECTORY_ENTRY paResDirEntries;
614 int i;
615
616 paResDirEntries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG)pResDirToSearch + sizeof(*pResDirToSearch));
617
618 if(pResDirToSearch->NumberOfNamedEntries) {
619 DebugInt3();
620 }
621 paResDirEntries += pResDirToSearch->NumberOfNamedEntries;
622
623 for (i = 0; i < pResDirToSearch->NumberOfIdEntries; i++) {
624 if (paResDirEntries[i].u1.Id == language)
625 {
626 return (PIMAGE_RESOURCE_DATA_ENTRY) (paResDirEntries[i].u2.s.OffsetToDirectory + (ULONG)pResRootDir);
627 }
628 }
629
630 // if nothing found and fGetDefault is true, return first entry
631 if(fGetDefault)
632 {
633 return (PIMAGE_RESOURCE_DATA_ENTRY) (paResDirEntries[0].u2.s.OffsetToDirectory + (ULONG)pResRootDir);
634 }
635 return NULL;
636}
637//******************************************************************************
638//******************************************************************************
639BOOL Win32ImageBase::enumResourceTypesA(HMODULE hmod, ENUMRESTYPEPROCA lpEnumFunc,
640 LONG lParam)
641{
642 PIMAGE_RESOURCE_DIRECTORY prdType;
643 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;
644 PIMAGE_RESOURCE_DIR_STRING_U pstring;
645 ULONG i, nameOffset;
646 BOOL fRet;
647
648 if (pResRootDir == NULL)
649 {
650 SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
651 return FALSE;
652 }
653
654 if ((ULONG)lpEnumFunc < 0x10000 || (ULONG)lpEnumFunc >= 0xc0000000)
655 {
656 SetLastError(ERROR_NOACCESS);
657 return FALSE;
658 }
659
660 //reminder:
661 //1st level -> types
662 //2nd level -> names
663 //3rd level -> language
664
665 /* set pointer to first resource type entry */
666 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG)pResRootDir + sizeof(IMAGE_RESOURCE_DIRECTORY));
667
668 for (i=0; i<pResRootDir->NumberOfNamedEntries+pResRootDir->NumberOfIdEntries && fRet; i++)
669 {
670 /* locate directory or each resource type */
671 prdType = (PIMAGE_RESOURCE_DIRECTORY)((int)pResRootDir + (int)prde->u2.OffsetToData);
672
673 if (prde->u1.s.NameIsString)
674 {//name or id entry?
675 //SvL: 30-10-'97, high bit is set, so clear to get real offset
676 nameOffset = prde->u1.Name & ~0x80000000;
677
678 pstring = (PIMAGE_RESOURCE_DIR_STRING_U)((ULONG)pResRootDir + nameOffset);
679 char *typename = (char *)malloc(pstring->Length+1);
680 lstrcpynWtoA(typename, pstring->NameString, pstring->Length+1);
681 typename[pstring->Length] = 0;
682
683 fRet = lpEnumFunc(hmod, typename, lParam);
684 free(typename);
685 }
686 else {
687 fRet = lpEnumFunc(hmod, (LPSTR)prde->u1.Id, lParam);
688 }
689
690 /* increment to next entry */
691 prde++;
692 }
693 return fRet > 0 ? TRUE : FALSE;
694}
695//******************************************************************************
696//******************************************************************************
697BOOL Win32ImageBase::enumResourceTypesW(HMODULE hmod, ENUMRESTYPEPROCW lpEnumFunc,
698 LONG lParam)
699{
700 PIMAGE_RESOURCE_DIRECTORY prdType;
701 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;
702 PIMAGE_RESOURCE_DIR_STRING_U pstring;
703 ULONG i, nameOffset;
704 BOOL fRet;
705
706 if (pResRootDir == NULL)
707 {
708 SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
709 return FALSE;
710 }
711
712 if ((ULONG)lpEnumFunc < 0x10000 || (ULONG)lpEnumFunc >= 0xc0000000)
713 {
714 SetLastError(ERROR_NOACCESS);
715 return FALSE;
716 }
717
718 //reminder:
719 //1st level -> types
720 //2nd level -> names
721 //3rd level -> language
722
723 /* set pointer to first resource type entry */
724 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG)pResRootDir + sizeof(IMAGE_RESOURCE_DIRECTORY));
725
726 for (i=0; i<pResRootDir->NumberOfNamedEntries+pResRootDir->NumberOfIdEntries && fRet; i++)
727 {
728 /* locate directory or each resource type */
729 prdType = (PIMAGE_RESOURCE_DIRECTORY)((int)pResRootDir + (int)prde->u2.OffsetToData);
730
731 if (prde->u1.s.NameIsString)
732 {//name or id entry?
733 //SvL: 30-10-'97, high bit is set, so clear to get real offset
734 nameOffset = prde->u1.Name & ~0x80000000;
735
736 pstring = (PIMAGE_RESOURCE_DIR_STRING_U)((ULONG)pResRootDir + nameOffset);
737 fRet = lpEnumFunc(hmod, pstring->NameString, lParam);
738 }
739 else fRet = lpEnumFunc(hmod, (LPWSTR)prde->u1.Id, lParam);
740
741 /* increment to next entry */
742 prde++;
743 }
744 return fRet > 0 ? TRUE : FALSE;
745}
746//******************************************************************************
747//******************************************************************************
Note: See TracBrowser for help on using the repository browser.