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;
34 #define PrintId(name) \
35 if (HIWORD((DWORD)name)) \
36 dprintf_resource( stddeb, "'%s'", name); \
38 dprintf_resource( stddeb, "#%04x", LOWORD(name));
43 /**********************************************************************
46 * Helper function - goes down one level of PE resource tree
49 PIMAGE_RESOURCE_DIRECTORY
GetResDirEntry(PIMAGE_RESOURCE_DIRECTORY resdirptr
,
54 PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable
;
58 /* FIXME: what about #xxx names? */
59 entryTable
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
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
)
70 if(STRING32_lstrcmpniW(name
,str
->NameString
,str
->Length
)==0)
71 return (PIMAGE_RESOURCE_DIRECTORY
) (
73 (entryTable
[entrynum
].OffsetToData
& 0x7fffffff));
77 entryTable
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) (
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
) (
85 (entryTable
[entrynum
].OffsetToData
& 0x7fffffff));
90 /**********************************************************************
91 * FindResource (KERNEL.60)
93 HANDLE32
FindResource32( HINSTANCE hModule
, LPCWSTR name
, LPCWSTR type
)
98 PIMAGE_RESOURCE_DIRECTORY resdirptr
;
102 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
103 dprintf_resource(stddeb
, "FindResource: module=%08x type=", hModule
);
105 dprintf_resource( stddeb
, " 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
)
116 if ((resdirptr
= GetResDirEntry(resdirptr
, name
, root
)) == NULL
)
118 result
= GetResDirEntry(resdirptr
, (LPCWSTR
)language
, root
);
119 /* Try LANG_NEUTRAL, too */
121 return GetResDirEntry(resdirptr
, (LPCWSTR
)0, root
);
125 return LIBRES_FindResource( hModule
, name
, type
);
130 /**********************************************************************
131 * LoadResource (KERNEL.61)
133 HANDLE32
LoadResource32( HINSTANCE hModule
, HANDLE32 hRsrc
)
139 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
140 dprintf_resource(stddeb
, "LoadResource: module=%04x res=%04x\n",
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
);
149 return LIBRES_LoadResource( hModule
, hRsrc
);
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 */
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",
179 if (!hRsrc
) return 0;
180 fprintf(stderr
,"AccessResource32: not implemented\n");
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",
193 fprintf(stderr
,"SizeofResource32: not implemented\n");
197 /**********************************************************************
198 * LoadAccelerators [USER.177]
200 HANDLE32
WIN32_LoadAcceleratorsW(HINSTANCE instance
, LPCWSTR lpTableName
)
207 ACCELHEADER
*lpAccelTbl
;
210 if (HIWORD(lpTableName
))
211 dprintf_accel( stddeb
, "LoadAccelerators: %04x '%s'\n",
212 instance
, (char *)( lpTableName
) );
214 dprintf_accel( stddeb
, "LoadAccelerators: %04x %04x\n",
215 instance
, LOWORD(lpTableName
) );
217 if (!(hRsrc
= FindResource32( instance
, lpTableName
,
218 (LPCWSTR
)RT_ACCELERATOR
)))
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
);
232 lpAccelTbl
->tbl
[i
].wIDval
= *((WORD
*)lp
);
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
);
245 fprintf(stderr
,"LoadAcceleratorsW: not implemented\n");
250 HANDLE32
WIN32_LoadAcceleratorsA(HINSTANCE instance
, LPCSTR lpTableName
)
254 if (HIWORD(lpTableName
))
255 uni
=STRING32_DupAnsiToUni(lpTableName
);
257 uni
=(LPWSTR
)lpTableName
;
258 result
=WIN32_LoadAcceleratorsW(instance
,uni
);
264 /**********************************************************************
268 WIN32_LoadStringW(HINSTANCE instance
, DWORD resource_id
, LPWSTR buffer
, int buflen
)
270 HANDLE32 hmem
, hrsrc
;
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
);
284 p
= LockResource32(hmem
);
285 string_num
= resource_id
& 0x000f;
286 for (i
= 0; i
< string_num
; i
++)
289 dprintf_resource( stddeb
, "strlen = %d\n", (int)*p
);
291 i
= MIN(buflen
- 1, *p
);
295 memcpy(buffer
, p
+ 1, i
* sizeof (WCHAR
));
296 buffer
[i
] = (WCHAR
) 0;
299 buffer
[0] = (WCHAR
) 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);
307 dprintf_resource(stddeb
,"LoadString // '%s' copied !\n", buffer
);
311 /**********************************************************************
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
);
321 *buffer
++ = (char) *buffer2
++;
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 /**********************************************************************
340 HBITMAP
WIN32_LoadBitmapW( HANDLE instance
, LPCWSTR name
)
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
);
368 /**********************************************************************
371 HBITMAP
WIN32_LoadBitmapA( HANDLE instance
, LPCSTR name
)
375 res
= WIN32_LoadBitmapW(instance
,(LPWSTR
)name
);
377 LPWSTR uni
=STRING32_DupAnsiToUni(name
);
378 res
=WIN32_LoadBitmapW(instance
,uni
);
384 /**********************************************************************
386 * LoadMenu helper function
388 BYTE
* WIN32_ParseMenu(HMENU hMenu
,BYTE
*it
)
390 char entry
[200]; /* buffer for ANSI names */
399 /* POPUP entries have no ID, but a sub menu */
402 wMenuID
= CreatePopupMenu();
403 len
= STRING32_lstrlenW((LPWSTR
)it
);
405 it
+= sizeof(WCHAR
)*(len
+1);
406 it
= WIN32_ParseMenu(wMenuID
,it
);
411 len
= STRING32_lstrlenW((LPWSTR
)it
);
412 it
+= sizeof(WCHAR
)*(len
+1);
413 if(!wMenuID
&& !*utext
)
414 flags
|= MF_SEPARATOR
;
416 if(len
>=bufsize
) continue; /* hack hack */
417 STRING32_UniToAnsi(entry
,utext
);
418 AppendMenu(hMenu
,flags
,wMenuID
,MAKE_SEGPTR(entry
));
419 }while(!(flags
& MF_END
));
423 /*****************************************************************
424 * LoadMenuIndirectW (USER32.371)
426 HMENU
WIN32_LoadMenuIndirectW(void *menu
)
429 HMENU hMenu
= CreateMenu();
432 fprintf(stderr
,"Unknown menu header\n");
434 WIN32_ParseMenu(hMenu
,it
);
438 /*****************************************************************
439 * LoadMenuW (USER32.372)
441 HMENU
WIN32_LoadMenuW(HANDLE instance
, LPCWSTR name
)
444 hrsrc
=FindResource32(instance
,name
,(LPWSTR
)RT_MENU
);
446 return WIN32_LoadMenuIndirectW(LoadResource32(instance
, hrsrc
));
449 /*****************************************************************
450 * LoadMenuIndirectA (USER32.370)
452 HMENU
WIN32_LoadMenuIndirectA(void *menu
)
454 fprintf(stderr
,"WIN32_LoadMenuIndirectA not implemented\n");
458 /*****************************************************************
459 * LoadMenuA (USER32.370)
461 HMENU
WIN32_LoadMenuA(HANDLE instance
,LPCSTR name
)
465 res
= WIN32_LoadMenuW(instance
,(LPWSTR
)name
);
467 LPWSTR uni
=STRING32_DupAnsiToUni(name
);
468 res
=WIN32_LoadMenuW(instance
,uni
);