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>
22 #include "resource32.h"
23 #include "stackframe.h"
31 int language = 0x0409;
33 #define PrintIdA(name) \
34 if (HIWORD((DWORD)name)) \
35 dprintf_resource( stddeb, "'%s'", name); \
37 dprintf_resource( stddeb, "#%04x", LOWORD(name));
38 #define PrintIdW(name)
41 /**********************************************************************
44 * Helper function - goes down one level of PE resource tree
47 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
52 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
56 /* FIXME: what about #xxx names? */
57 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
59 sizeof(IMAGE_RESOURCE_DIRECTORY));
60 namelen = lstrlen32W(name);
61 for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
63 PIMAGE_RESOURCE_DIR_STRING_U str =
64 (PIMAGE_RESOURCE_DIR_STRING_U) (root +
65 (entryTable[entrynum].Name & 0x7fffffff));
66 if(namelen != str->Length)
68 if(lstrncmpi32W(name,str->NameString,str->Length)==0)
69 return (PIMAGE_RESOURCE_DIRECTORY) (
71 (entryTable[entrynum].OffsetToData & 0x7fffffff));
75 entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
77 sizeof(IMAGE_RESOURCE_DIRECTORY) +
78 resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
79 for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
80 if ((DWORD)entryTable[entrynum].Name == (DWORD)name)
81 return (PIMAGE_RESOURCE_DIRECTORY) (
83 (entryTable[entrynum].OffsetToData & 0x7fffffff));
88 /**********************************************************************
91 * Helper function - goes down one level of PE resource tree
94 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY resdirptr,
99 PIMAGE_RESOURCE_DIRECTORY ret;
101 if (HIWORD((DWORD)name))
102 xname = STRING32_DupAnsiToUni(name);
104 xname = (LPWSTR)name;
106 ret=GetResDirEntryW(resdirptr,xname,root);
107 if (HIWORD((DWORD)name))
112 /**********************************************************************
113 * FindResourceA (KERNEL32.128)
115 HANDLE32 FindResource32A( HINSTANCE hModule, LPCSTR name, LPCSTR type ) {
119 if (HIWORD((DWORD)name))
120 xname = STRING32_DupAnsiToUni(name);
122 xname = (LPWSTR)name;
123 if (HIWORD((DWORD)type))
124 xtype = STRING32_DupAnsiToUni(type);
126 xtype = (LPWSTR)type;
127 ret=FindResource32W(hModule,xname,xtype);
128 if (HIWORD((DWORD)name))
130 if (HIWORD((DWORD)type))
135 /**********************************************************************
136 * FindResourceW (KERNEL32.131)
138 HANDLE32 FindResource32W( HINSTANCE hModule, LPCWSTR name, LPCWSTR type )
143 PIMAGE_RESOURCE_DIRECTORY resdirptr;
147 /* Sometimes we get passed hModule = 0x00000000. FIXME: is GetTaskDS()
150 if (!hModule) hModule = GetTaskDS();
151 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
152 dprintf_resource(stddeb, "FindResource: module=%08x type=", hModule );
154 dprintf_resource( stddeb, " name=" );
156 dprintf_resource( stddeb, "\n" );
157 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
158 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */
159 if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
161 resdirptr = (PIMAGE_RESOURCE_DIRECTORY) pe->pe_resource;
162 root = (DWORD) resdirptr;
163 if ((resdirptr = GetResDirEntryW(resdirptr, type, root)) == NULL)
165 if ((resdirptr = GetResDirEntryW(resdirptr, name, root)) == NULL)
167 result = (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)language, root);
168 /* Try LANG_NEUTRAL, too */
170 return (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)0, root);
174 return LIBRES_FindResource( hModule, name, type );
179 /**********************************************************************
180 * LoadResource (KERNEL32.370)
182 HANDLE32 LoadResource32( HINSTANCE hModule, HANDLE32 hRsrc )
188 if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
189 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
190 dprintf_resource(stddeb, "LoadResource: module=%04x res=%04x\n",
192 if (!hRsrc) return 0;
194 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
195 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */
196 if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
197 return (HANDLE32) (pe->load_addr+((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
199 return LIBRES_LoadResource( hModule, hRsrc );
204 /**********************************************************************
205 * LockResource (KERNEL.62)
207 LPVOID LockResource32( HANDLE32 handle )
209 return (LPVOID) handle;
212 /**********************************************************************
213 * FreeResource (KERNEL.63)
215 BOOL FreeResource32( HANDLE32 handle )
217 /* no longer used in Win32 */
221 /**********************************************************************
222 * AccessResource (KERNEL.64)
224 INT AccessResource32( HINSTANCE hModule, HRSRC hRsrc )
226 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
227 dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n",
229 if (!hRsrc) return 0;
230 fprintf(stderr,"AccessResource32: not implemented\n");
235 /**********************************************************************
236 * SizeofResource (KERNEL.65)
238 DWORD SizeofResource32( HINSTANCE hModule, HRSRC hRsrc )
240 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
241 dprintf_resource(stddeb, "SizeofResource: module=%04x res=%04x\n",
243 fprintf(stderr,"SizeofResource32: not implemented\n");
247 /**********************************************************************
248 * LoadAccelerators [USER.177]
250 HANDLE32 WIN32_LoadAcceleratorsW(HINSTANCE instance, LPCWSTR lpTableName)
257 ACCELHEADER *lpAccelTbl;
260 if (HIWORD(lpTableName))
261 dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
262 instance, (char *)( lpTableName ) );
264 dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
265 instance, LOWORD(lpTableName) );
267 if (!(hRsrc = FindResource32( instance, lpTableName,
268 (LPCWSTR)RT_ACCELERATOR )))
270 if (!(rsc_mem = LoadResource32( instance, hRsrc ))) return 0;
272 lp = (BYTE *)LockResource32(rsc_mem);
273 n = SizeofResource( instance, hRsrc ) / sizeof(ACCELENTRY);
274 hAccel = GlobalAlloc16(GMEM_MOVEABLE,
275 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
276 lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
277 lpAccelTbl->wCount = 0;
278 for (i = 0; i < n; i++) {
279 lpAccelTbl->tbl[i].type = *(lp++);
280 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
282 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
284 if (lpAccelTbl->tbl[i].wEvent == 0) break;
285 dprintf_accel(stddeb,
286 "Accelerator #%u / event=%04X id=%04X type=%02X \n",
287 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
288 lpAccelTbl->tbl[i].type);
289 lpAccelTbl->wCount++;
291 GlobalUnlock16(hAccel);
292 FreeResource( rsc_mem );
295 fprintf(stderr,"LoadAcceleratorsW: not implemented\n");
296 return 0x100; /* Return something anyway */
300 HANDLE32 WIN32_LoadAcceleratorsA(HINSTANCE instance, LPCSTR lpTableName)
304 if (HIWORD(lpTableName))
305 uni=STRING32_DupAnsiToUni(lpTableName);
307 uni=(LPWSTR)lpTableName;
308 result=WIN32_LoadAcceleratorsW(instance,uni);
314 /**********************************************************************
318 WIN32_LoadStringW(HINSTANCE instance, DWORD resource_id, LPWSTR buffer, int buflen)
320 HANDLE32 hmem, hrsrc;
325 dprintf_resource(stddeb, "LoadString: instance = %04x, id = %04x, buffer = %08x, "
326 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
328 hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1),
329 (LPCWSTR)RT_STRING );
330 if (!hrsrc) return 0;
331 hmem = LoadResource32( instance, hrsrc );
334 p = LockResource32(hmem);
335 string_num = resource_id & 0x000f;
336 for (i = 0; i < string_num; i++)
339 dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
341 i = MIN(buflen - 1, *p);
345 memcpy(buffer, p + 1, i * sizeof (WCHAR));
346 buffer[i] = (WCHAR) 0;
349 buffer[0] = (WCHAR) 0;
353 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
354 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
357 dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
361 /**********************************************************************
365 WIN32_LoadStringA(HINSTANCE instance, DWORD resource_id, LPSTR buffer, int buflen)
367 WCHAR *buffer2 = xmalloc(buflen*2);
368 int retval = WIN32_LoadStringW(instance, resource_id, buffer2, buflen);
371 *buffer++ = (char) *buffer2++;
376 HICON LoadIconW32(HINSTANCE hisnt, LPCWSTR lpszIcon)
379 return LoadIcon(0, IDI_APPLICATION);
382 HICON LoadIconA32(HINSTANCE hinst, LPCSTR lpszIcon)
385 return LoadIconW32(hinst, lpszIcon);
387 /**********************************************************************
390 HBITMAP WIN32_LoadBitmapW( HANDLE instance, LPCWSTR name )
398 if (!instance) /* OEM bitmap */
400 if (HIWORD((int)name)) return 0;
401 return OBM_LoadBitmap( LOWORD((int)name) );
404 if (!(hRsrc = FindResource32W( instance, name,
405 (LPWSTR)RT_BITMAP ))) return 0;
406 if (!(handle = LoadResource32( instance, hRsrc ))) return 0;
408 info = (BITMAPINFO *)LockResource32( handle );
409 if ((hdc = GetDC(0)) != 0)
411 char *bits = (char *)info + DIB_BitmapInfoSize( info, DIB_RGB_COLORS );
412 hbitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
413 bits, info, DIB_RGB_COLORS );
418 /**********************************************************************
421 HBITMAP WIN32_LoadBitmapA( HANDLE instance, LPCSTR name )
425 res = WIN32_LoadBitmapW(instance,(LPWSTR)name);
427 LPWSTR uni=STRING32_DupAnsiToUni(name);
428 res=WIN32_LoadBitmapW(instance,uni);
434 /*****************************************************************
435 * LoadMenuW (USER32.372)
437 HMENU WIN32_LoadMenuW(HANDLE instance, LPCWSTR name)
440 hrsrc=FindResource32W(instance,name,(LPWSTR)RT_MENU);
442 return LoadMenuIndirect32W( LoadResource32(instance, hrsrc) );
445 /*****************************************************************
446 * LoadMenuA (USER32.370)
448 HMENU WIN32_LoadMenuA(HANDLE instance,LPCSTR name)
452 res = WIN32_LoadMenuW(instance,(LPWSTR)name);
454 LPWSTR uni=STRING32_DupAnsiToUni(name);
455 res=WIN32_LoadMenuW(instance,uni);