Release 960717
[wine/multimedia.git] / loader / pe_resource.c
blob917877224db55c0a04f6e8f70566a366a42ae785
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 "kernel32.h"
19 #include "pe_image.h"
20 #include "module.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 "string32.h"
29 #include "stddebug.h"
30 #include "debug.h"
32 int language = 0x0409;
34 #define PrintIdA(name) \
35 if (HIWORD((DWORD)name)) \
36 dprintf_resource( stddeb, "'%s'", name); \
37 else \
38 dprintf_resource( stddeb, "#%04x", LOWORD(name));
39 #define PrintIdW(name)
40 #define PrintId(name)
42 /**********************************************************************
43 * GetResDirEntryW
45 * Helper function - goes down one level of PE resource tree
48 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
49 LPCWSTR name,
50 DWORD root)
52 int entrynum;
53 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
54 int namelen;
56 if (HIWORD(name)) {
57 /* FIXME: what about #xxx names? */
58 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
59 (BYTE *) resdirptr +
60 sizeof(IMAGE_RESOURCE_DIRECTORY));
61 namelen = lstrlen32W(name);
62 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
64 PIMAGE_RESOURCE_DIR_STRING_U str =
65 (PIMAGE_RESOURCE_DIR_STRING_U) (root +
66 (entryTable[entrynum].Name & 0x7fffffff));
67 if(namelen != str->Length)
68 continue;
69 if(lstrncmpi32W(name,str->NameString,str->Length)==0)
70 return (PIMAGE_RESOURCE_DIRECTORY) (
71 root +
72 (entryTable[entrynum].OffsetToData & 0x7fffffff));
74 return NULL;
75 } else {
76 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
77 (BYTE *) resdirptr +
78 sizeof(IMAGE_RESOURCE_DIRECTORY) +
79 resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
80 for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
81 if ((DWORD)entryTable[entrynum].Name == (DWORD)name)
82 return (PIMAGE_RESOURCE_DIRECTORY) (
83 root +
84 (entryTable[entrynum].OffsetToData & 0x7fffffff));
85 return NULL;
89 /**********************************************************************
90 * GetResDirEntryA
92 * Helper function - goes down one level of PE resource tree
95 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY resdirptr,
96 LPCSTR name,
97 DWORD root)
99 LPWSTR xname;
100 PIMAGE_RESOURCE_DIRECTORY ret;
102 if (HIWORD((DWORD)name))
103 xname = STRING32_DupAnsiToUni(name);
104 else
105 xname = (LPWSTR)name;
107 ret=GetResDirEntryW(resdirptr,xname,root);
108 if (HIWORD((DWORD)name))
109 free(xname);
110 return ret;
113 /**********************************************************************
114 * PE_FindResource32W
116 HANDLE32 PE_FindResource32W( HINSTANCE hModule, LPCWSTR name, LPCWSTR type )
118 PE_MODULE *pe;
119 NE_MODULE *pModule;
120 PIMAGE_RESOURCE_DIRECTORY resdirptr;
121 DWORD root;
122 HANDLE32 result;
124 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
125 dprintf_resource(stddeb, "FindResource: module=%08x type=", hModule );
126 PrintId( type );
127 dprintf_resource( stddeb, " name=" );
128 PrintId( name );
129 dprintf_resource( stddeb, "\n" );
130 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
131 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */
132 if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
134 resdirptr = (PIMAGE_RESOURCE_DIRECTORY) pe->pe_resource;
135 root = (DWORD) resdirptr;
136 if ((resdirptr = GetResDirEntryW(resdirptr, type, root)) == NULL)
137 return 0;
138 if ((resdirptr = GetResDirEntryW(resdirptr, name, root)) == NULL)
139 return 0;
140 result = (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)language, root);
141 /* Try LANG_NEUTRAL, too */
142 if(!result)
143 return (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)0, root);
144 return result;
148 /**********************************************************************
149 * PE_LoadResource32
151 HANDLE32 PE_LoadResource32( HINSTANCE hModule, HANDLE32 hRsrc )
153 NE_MODULE *pModule;
154 PE_MODULE *pe;
156 if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
157 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
158 dprintf_resource(stddeb, "PE_LoadResource32: module=%04x res=%04x\n",
159 hModule, hRsrc );
160 if (!hRsrc) return 0;
162 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
163 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */
164 if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
165 return (HANDLE32) (pe->load_addr+((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
167 #endif