Release 970120
[wine/multimedia.git] / loader / pe_resource.c
blob7c7e6afed4f73b1fc08517940e7de2d275af8490
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 "stackframe.h"
24 #include "neexe.h"
25 #include "accel.h"
26 #include "xmalloc.h"
27 #include "stddebug.h"
28 #include "debug.h"
30 #define PrintIdA(name) \
31 if (HIWORD((DWORD)name)) \
32 dprintf_resource( stddeb, "'%s'", name); \
33 else \
34 dprintf_resource( stddeb, "#%04x", LOWORD(name));
35 #define PrintIdW(name)
36 #define PrintId(name)
38 /**********************************************************************
39 * GetResDirEntryW
41 * Helper function - goes down one level of PE resource tree
44 LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(LPIMAGE_RESOURCE_DIRECTORY resdirptr,
45 LPCWSTR name,DWORD root)
47 int entrynum;
48 LPIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
49 int namelen;
51 if (HIWORD(name)) {
52 /* FIXME: what about #xxx names? */
53 entryTable = (LPIMAGE_RESOURCE_DIRECTORY_ENTRY) (
54 (BYTE *) resdirptr +
55 sizeof(IMAGE_RESOURCE_DIRECTORY));
56 namelen = lstrlen32W(name);
57 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
59 LPIMAGE_RESOURCE_DIR_STRING_U str =
60 (LPIMAGE_RESOURCE_DIR_STRING_U) (root +
61 entryTable[entrynum].u1.s.NameOffset);
62 if(namelen != str->Length)
63 continue;
64 if(lstrncmpi32W(name,str->NameString,str->Length)==0)
65 return (LPIMAGE_RESOURCE_DIRECTORY) (
66 root +
67 entryTable[entrynum].u2.s.OffsetToDirectory);
69 return NULL;
70 } else {
71 entryTable = (LPIMAGE_RESOURCE_DIRECTORY_ENTRY) (
72 (BYTE *) resdirptr +
73 sizeof(IMAGE_RESOURCE_DIRECTORY) +
74 resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
75 for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
76 if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name)
77 return (LPIMAGE_RESOURCE_DIRECTORY) (
78 root +
79 entryTable[entrynum].u2.s.OffsetToDirectory);
80 /* just use first entry if no default can be found */
81 if (!name && resdirptr->NumberOfIdEntries)
82 return (LPIMAGE_RESOURCE_DIRECTORY) (
83 root +
84 entryTable[0].u2.s.OffsetToDirectory);
85 return NULL;
89 /**********************************************************************
90 * GetResDirEntryA
92 * Helper function - goes down one level of PE resource tree
95 LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(LPIMAGE_RESOURCE_DIRECTORY resdirptr,
96 LPCSTR name,
97 DWORD root)
99 LPWSTR xname;
100 LPIMAGE_RESOURCE_DIRECTORY ret;
102 if (HIWORD((DWORD)name))
103 xname = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
104 else
105 xname = (LPWSTR)name;
107 ret=GetResDirEntryW(resdirptr,xname,root);
108 if (HIWORD((DWORD)name))
109 HeapFree( GetProcessHeap(), 0, xname );
110 return ret;
113 /**********************************************************************
114 * PE_FindResourceEx32W
116 HANDLE32 PE_FindResourceEx32W(
117 HINSTANCE32 hModule,LPCWSTR name,LPCWSTR type,WORD lang
119 PE_MODULE *pe;
120 NE_MODULE *pModule;
121 LPIMAGE_RESOURCE_DIRECTORY resdirptr;
122 DWORD root;
123 HANDLE32 result;
125 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
126 dprintf_resource(stddeb, "FindResource: module=%08x type=", hModule );
127 PrintId( type );
128 dprintf_resource( stddeb, " name=" );
129 PrintId( name );
130 dprintf_resource( stddeb, "\n" );
131 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
132 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */
133 if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
135 resdirptr = pe->pe_resource;
136 root = (DWORD) resdirptr;
137 if ((resdirptr = GetResDirEntryW(resdirptr, type, root)) == NULL)
138 return 0;
139 if ((resdirptr = GetResDirEntryW(resdirptr, name, root)) == NULL)
140 return 0;
141 result = (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT32)lang, root);
142 /* Try LANG_NEUTRAL, too */
143 if(!result)
144 return (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)0, root);
145 return result;
149 /**********************************************************************
150 * PE_LoadResource32
152 HANDLE32 PE_LoadResource32( HINSTANCE32 hModule, HANDLE32 hRsrc )
154 NE_MODULE *pModule;
155 PE_MODULE *pe;
157 if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
158 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
159 dprintf_resource(stddeb, "PE_LoadResource32: module=%04x res=%04x\n",
160 hModule, hRsrc );
161 if (!hRsrc) return 0;
163 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
164 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */
165 if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
166 return (HANDLE32) (pe->load_addr+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
168 #endif