Release 961222
[wine/multimedia.git] / loader / pe_resource.c
blob74b74bc2b1653790daf64760b116fd5cb1696727
1 #ifndef WINELIB
2 /*
3 * PE (Portable Execute) File Resources
5 * Copyright 1995 Thomas Sandford
6 * Copyright 1996 Martin von Loewis
8 * Based on the Win16 resource handling code in loader/resource.c
9 * Copyright 1993 Robert J. Amstadt
10 * Copyright 1995 Alexandre Julliard
12 * This is not even at ALPHA level yet. Don't expect it to work!
15 #include <sys/types.h>
16 #include "wintypes.h"
17 #include "windows.h"
18 #include "pe_image.h"
19 #include "module.h"
20 #include "heap.h"
21 #include "handle32.h"
22 #include "libres.h"
23 #include "resource32.h"
24 #include "stackframe.h"
25 #include "neexe.h"
26 #include "accel.h"
27 #include "xmalloc.h"
28 #include "stddebug.h"
29 #include "debug.h"
31 #define PrintIdA(name) \
32 if (HIWORD((DWORD)name)) \
33 dprintf_resource( stddeb, "'%s'", name); \
34 else \
35 dprintf_resource( stddeb, "#%04x", LOWORD(name));
36 #define PrintIdW(name)
37 #define PrintId(name)
39 /**********************************************************************
40 * GetResDirEntryW
42 * Helper function - goes down one level of PE resource tree
45 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
46 LPCWSTR name,
47 DWORD root)
49 int entrynum;
50 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
51 int namelen;
53 if (HIWORD(name)) {
54 /* FIXME: what about #xxx names? */
55 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
56 (BYTE *) resdirptr +
57 sizeof(IMAGE_RESOURCE_DIRECTORY));
58 namelen = lstrlen32W(name);
59 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
61 PIMAGE_RESOURCE_DIR_STRING_U str =
62 (PIMAGE_RESOURCE_DIR_STRING_U) (root +
63 (entryTable[entrynum].Name & 0x7fffffff));
64 if(namelen != str->Length)
65 continue;
66 if(lstrncmpi32W(name,str->NameString,str->Length)==0)
67 return (PIMAGE_RESOURCE_DIRECTORY) (
68 root +
69 (entryTable[entrynum].OffsetToData & 0x7fffffff));
71 return NULL;
72 } else {
73 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
74 (BYTE *) resdirptr +
75 sizeof(IMAGE_RESOURCE_DIRECTORY) +
76 resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
77 for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
78 if ((DWORD)entryTable[entrynum].Name == (DWORD)name)
79 return (PIMAGE_RESOURCE_DIRECTORY) (
80 root +
81 (entryTable[entrynum].OffsetToData & 0x7fffffff));
82 /* just use first entry if no default can be found */
83 if (!name && resdirptr->NumberOfIdEntries)
84 return (PIMAGE_RESOURCE_DIRECTORY) (
85 root +
86 (entryTable[0].OffsetToData & 0x7fffffff));
87 return NULL;
91 /**********************************************************************
92 * GetResDirEntryA
94 * Helper function - goes down one level of PE resource tree
97 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY resdirptr,
98 LPCSTR name,
99 DWORD root)
101 LPWSTR xname;
102 PIMAGE_RESOURCE_DIRECTORY ret;
104 if (HIWORD((DWORD)name))
105 xname = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
106 else
107 xname = (LPWSTR)name;
109 ret=GetResDirEntryW(resdirptr,xname,root);
110 if (HIWORD((DWORD)name))
111 HeapFree( GetProcessHeap(), 0, xname );
112 return ret;
115 /**********************************************************************
116 * PE_FindResourceEx32W
118 HANDLE32 PE_FindResourceEx32W(
119 HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type, WORD lang
122 PE_MODULE *pe;
123 NE_MODULE *pModule;
124 PIMAGE_RESOURCE_DIRECTORY resdirptr;
125 DWORD root;
126 HANDLE32 result;
128 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
129 dprintf_resource(stddeb, "FindResource: module=%08x type=", hModule );
130 PrintId( type );
131 dprintf_resource( stddeb, " name=" );
132 PrintId( name );
133 dprintf_resource( stddeb, "\n" );
134 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
135 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */
136 if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
138 resdirptr = (PIMAGE_RESOURCE_DIRECTORY) pe->pe_resource;
139 root = (DWORD) resdirptr;
140 if ((resdirptr = GetResDirEntryW(resdirptr, type, root)) == NULL)
141 return 0;
142 if ((resdirptr = GetResDirEntryW(resdirptr, name, root)) == NULL)
143 return 0;
144 result = (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT32)lang, root);
145 /* Try LANG_NEUTRAL, too */
146 if(!result)
147 return (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)0, root);
148 return result;
152 /**********************************************************************
153 * PE_LoadResource32
155 HANDLE32 PE_LoadResource32( HINSTANCE32 hModule, HANDLE32 hRsrc )
157 NE_MODULE *pModule;
158 PE_MODULE *pe;
160 if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
161 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
162 dprintf_resource(stddeb, "PE_LoadResource32: module=%04x res=%04x\n",
163 hModule, hRsrc );
164 if (!hRsrc) return 0;
166 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
167 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */
168 if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
169 return (HANDLE32) (pe->load_addr+((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
171 #endif