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

Last change on this file since 1872 was 1872, checked in by bird, 26 years ago

Implemented EnumResourceNamesA/W.

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