Release 960606
[wine/multimedia.git] / win32 / resource.c
blob4b4598d461ee062c60d0dbcf9c3b7d71e16fce11
1 /*
2 * Win32 Resources
4 * Copyright 1995 Thomas Sandford
5 * Copyright 1996 Martin von Loewis
7 * Based on the Win16 resource handling code in loader/resource.c
8 * Copyright 1993 Robert J. Amstadt
9 * Copyright 1995 Alexandre Julliard
11 * This is not even at ALPHA level yet. Don't expect it to work!
14 #include <sys/types.h>
15 #include "wintypes.h"
16 #include "windows.h"
17 #include "kernel32.h"
18 #include "pe_image.h"
19 #include "module.h"
20 #include "handle32.h"
21 #include "libres.h"
22 #include "resource32.h"
23 #include "stackframe.h"
24 #include "neexe.h"
25 #include "accel.h"
26 #include "xmalloc.h"
27 #include "string32.h"
28 #include "stddebug.h"
29 #include "debug.h"
31 int language = 0x0409;
33 #if 0
34 #define PrintId(name) \
35 if (HIWORD((DWORD)name)) \
36 dprintf_resource( stddeb, "'%s'", name); \
37 else \
38 dprintf_resource( stddeb, "#%04x", LOWORD(name));
39 #else
40 #define PrintId(name)
41 #endif
43 /**********************************************************************
44 * GetResDirEntry
46 * Helper function - goes down one level of PE resource tree
49 PIMAGE_RESOURCE_DIRECTORY GetResDirEntry(PIMAGE_RESOURCE_DIRECTORY resdirptr,
50 LPCWSTR name,
51 DWORD root)
53 int entrynum;
54 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
55 int namelen;
57 if (HIWORD(name)) {
58 /* FIXME: what about #xxx names? */
59 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
60 (BYTE *) resdirptr +
61 sizeof(IMAGE_RESOURCE_DIRECTORY));
62 namelen = STRING32_lstrlenW(name);
63 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
65 PIMAGE_RESOURCE_DIR_STRING_U str =
66 (PIMAGE_RESOURCE_DIR_STRING_U) (root +
67 (entryTable[entrynum].Name & 0x7fffffff));
68 if(namelen != str->Length)
69 continue;
70 if(STRING32_lstrcmpniW(name,str->NameString,str->Length)==0)
71 return (PIMAGE_RESOURCE_DIRECTORY) (
72 root +
73 (entryTable[entrynum].OffsetToData & 0x7fffffff));
75 return NULL;
76 } else {
77 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
78 (BYTE *) resdirptr +
79 sizeof(IMAGE_RESOURCE_DIRECTORY) +
80 resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
81 for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
82 if ((DWORD)entryTable[entrynum].Name == (DWORD)name)
83 return (PIMAGE_RESOURCE_DIRECTORY) (
84 root +
85 (entryTable[entrynum].OffsetToData & 0x7fffffff));
86 return NULL;
90 /**********************************************************************
91 * FindResource (KERNEL.60)
93 HANDLE32 FindResource32( HINSTANCE hModule, LPCWSTR name, LPCWSTR type )
95 #ifndef WINELIB
96 PE_MODULE *pe;
97 NE_MODULE *pModule;
98 PIMAGE_RESOURCE_DIRECTORY resdirptr;
99 DWORD root;
100 HANDLE32 result;
102 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
103 dprintf_resource(stddeb, "FindResource: module=%08x type=", hModule );
104 PrintId( type );
105 dprintf_resource( stddeb, " name=" );
106 PrintId( name );
107 dprintf_resource( stddeb, "\n" );
108 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
109 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */
110 if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
112 resdirptr = (PIMAGE_RESOURCE_DIRECTORY) pe->pe_resource;
113 root = (DWORD) resdirptr;
114 if ((resdirptr = GetResDirEntry(resdirptr, type, root)) == NULL)
115 return 0;
116 if ((resdirptr = GetResDirEntry(resdirptr, name, root)) == NULL)
117 return 0;
118 result = GetResDirEntry(resdirptr, (LPCWSTR)language, root);
119 /* Try LANG_NEUTRAL, too */
120 if(!result)
121 return GetResDirEntry(resdirptr, (LPCWSTR)0, root);
122 return result;
124 #else
125 return LIBRES_FindResource( hModule, name, type );
126 #endif
130 /**********************************************************************
131 * LoadResource (KERNEL.61)
133 HANDLE32 LoadResource32( HINSTANCE hModule, HANDLE32 hRsrc )
135 #ifndef WINELIB
136 NE_MODULE *pModule;
137 PE_MODULE *pe;
139 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
140 dprintf_resource(stddeb, "LoadResource: module=%04x res=%04x\n",
141 hModule, hRsrc );
142 if (!hRsrc) return 0;
144 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
145 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */
146 if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
147 return (HANDLE32) (pe->load_addr+((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
148 #else
149 return LIBRES_LoadResource( hModule, hRsrc );
150 #endif
154 /**********************************************************************
155 * LockResource (KERNEL.62)
157 LPVOID LockResource32( HANDLE32 handle )
159 return (LPVOID) handle;
162 /**********************************************************************
163 * FreeResource (KERNEL.63)
165 BOOL FreeResource32( HANDLE32 handle )
167 /* no longer used in Win32 */
168 return TRUE;
171 /**********************************************************************
172 * AccessResource (KERNEL.64)
174 INT AccessResource32( HINSTANCE hModule, HRSRC hRsrc )
176 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
177 dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n",
178 hModule, hRsrc );
179 if (!hRsrc) return 0;
180 fprintf(stderr,"AccessResource32: not implemented\n");
181 return 0;
185 /**********************************************************************
186 * SizeofResource (KERNEL.65)
188 DWORD SizeofResource32( HINSTANCE hModule, HRSRC hRsrc )
190 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
191 dprintf_resource(stddeb, "SizeofResource: module=%04x res=%04x\n",
192 hModule, hRsrc );
193 fprintf(stderr,"SizeofResource32: not implemented\n");
194 return 0;
197 /**********************************************************************
198 * LoadAccelerators [USER.177]
200 HANDLE32 WIN32_LoadAcceleratorsW(HINSTANCE instance, LPCWSTR lpTableName)
202 #if 0
203 HANDLE32 hAccel;
204 HANDLE32 rsc_mem;
205 HANDLE32 hRsrc;
206 BYTE *lp;
207 ACCELHEADER *lpAccelTbl;
208 int i, n;
210 if (HIWORD(lpTableName))
211 dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
212 instance, (char *)( lpTableName ) );
213 else
214 dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
215 instance, LOWORD(lpTableName) );
217 if (!(hRsrc = FindResource32( instance, lpTableName,
218 (LPCWSTR)RT_ACCELERATOR )))
219 return 0;
220 if (!(rsc_mem = LoadResource32( instance, hRsrc ))) return 0;
222 lp = (BYTE *)LockResource32(rsc_mem);
223 n = SizeofResource( instance, hRsrc ) / sizeof(ACCELENTRY);
224 hAccel = GlobalAlloc16(GMEM_MOVEABLE,
225 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
226 lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
227 lpAccelTbl->wCount = 0;
228 for (i = 0; i < n; i++) {
229 lpAccelTbl->tbl[i].type = *(lp++);
230 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
231 lp += 2;
232 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
233 lp += 2;
234 if (lpAccelTbl->tbl[i].wEvent == 0) break;
235 dprintf_accel(stddeb,
236 "Accelerator #%u / event=%04X id=%04X type=%02X \n",
237 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
238 lpAccelTbl->tbl[i].type);
239 lpAccelTbl->wCount++;
241 GlobalUnlock16(hAccel);
242 FreeResource( rsc_mem );
243 return hAccel;
244 #else
245 fprintf(stderr,"LoadAcceleratorsW: not implemented\n");
246 return 0;
247 #endif
250 HANDLE32 WIN32_LoadAcceleratorsA(HINSTANCE instance, LPCSTR lpTableName)
252 LPWSTR uni;
253 HANDLE32 result;
254 if (HIWORD(lpTableName))
255 uni=STRING32_DupAnsiToUni(lpTableName);
256 else
257 uni=(LPWSTR)lpTableName;
258 result=WIN32_LoadAcceleratorsW(instance,uni);
259 if (HIWORD(uni))
260 free(uni);
261 return result;
264 /**********************************************************************
265 * LoadString
268 WIN32_LoadStringW(HINSTANCE instance, DWORD resource_id, LPWSTR buffer, int buflen)
270 HANDLE32 hmem, hrsrc;
271 WCHAR *p;
272 int string_num;
273 int i;
275 dprintf_resource(stddeb, "LoadString: instance = %04x, id = %04x, buffer = %08x, "
276 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
278 hrsrc = FindResource32( instance, (LPCWSTR)((resource_id>>4)+1),
279 (LPCWSTR)RT_STRING );
280 if (!hrsrc) return 0;
281 hmem = LoadResource32( instance, hrsrc );
282 if (!hmem) return 0;
284 p = LockResource32(hmem);
285 string_num = resource_id & 0x000f;
286 for (i = 0; i < string_num; i++)
287 p += *p + 1;
289 dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
291 i = MIN(buflen - 1, *p);
292 if (buffer == NULL)
293 return i;
294 if (i > 0) {
295 memcpy(buffer, p + 1, i * sizeof (WCHAR));
296 buffer[i] = (WCHAR) 0;
297 } else {
298 if (buflen > 1) {
299 buffer[0] = (WCHAR) 0;
300 return 0;
302 #if 0
303 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
304 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
305 #endif
307 dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
308 return i;
311 /**********************************************************************
312 * LoadStringA
315 WIN32_LoadStringA(HINSTANCE instance, DWORD resource_id, LPSTR buffer, int buflen)
317 WCHAR *buffer2 = xmalloc(buflen*2);
318 int retval = WIN32_LoadStringW(instance, resource_id, buffer2, buflen);
320 while (*buffer2)
321 *buffer++ = (char) *buffer2++;
322 *buffer = 0;
323 return retval;
326 HICON LoadIconW32(HINSTANCE hisnt, LPCWSTR lpszIcon)
329 return LoadIcon(0, IDI_APPLICATION);
332 HICON LoadIconA32(HINSTANCE hinst, LPCSTR lpszIcon)
335 return LoadIconW32(hinst, lpszIcon);
337 /**********************************************************************
338 * LoadBitmapW
340 HBITMAP WIN32_LoadBitmapW( HANDLE instance, LPCWSTR name )
342 HBITMAP hbitmap = 0;
343 HDC hdc;
344 HANDLE32 hRsrc;
345 HANDLE32 handle;
346 BITMAPINFO *info;
348 if (!instance) /* OEM bitmap */
350 if (HIWORD((int)name)) return 0;
351 return OBM_LoadBitmap( LOWORD((int)name) );
354 if (!(hRsrc = FindResource32( instance, name,
355 (LPWSTR)RT_BITMAP ))) return 0;
356 if (!(handle = LoadResource32( instance, hRsrc ))) return 0;
358 info = (BITMAPINFO *)LockResource32( handle );
359 if ((hdc = GetDC(0)) != 0)
361 char *bits = (char *)info + DIB_BitmapInfoSize( info, DIB_RGB_COLORS );
362 hbitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
363 bits, info, DIB_RGB_COLORS );
364 ReleaseDC( 0, hdc );
366 return hbitmap;
368 /**********************************************************************
369 * LoadBitmapA
371 HBITMAP WIN32_LoadBitmapA( HANDLE instance, LPCSTR name )
373 HBITMAP res;
374 if(!HIWORD(name))
375 res = WIN32_LoadBitmapW(instance,(LPWSTR)name);
376 else{
377 LPWSTR uni=STRING32_DupAnsiToUni(name);
378 res=WIN32_LoadBitmapW(instance,uni);
379 free(uni);
381 return res;
384 /*****************************************************************
385 * LoadMenuW (USER32.372)
387 HMENU WIN32_LoadMenuW(HANDLE instance, LPCWSTR name)
389 HANDLE32 hrsrc;
390 hrsrc=FindResource32(instance,name,(LPWSTR)RT_MENU);
391 if(!hrsrc)return 0;
392 return LoadMenuIndirect32W( LoadResource32(instance, hrsrc) );
395 /*****************************************************************
396 * LoadMenuA (USER32.370)
398 HMENU WIN32_LoadMenuA(HANDLE instance,LPCSTR name)
400 HMENU res;
401 if(!HIWORD(name))
402 res = WIN32_LoadMenuW(instance,(LPWSTR)name);
403 else{
404 LPWSTR uni=STRING32_DupAnsiToUni(name);
405 res=WIN32_LoadMenuW(instance,uni);
406 free(uni);
408 return res;