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
= GlobalAlloc(GMEM_MOVEABLE
,
225 sizeof(ACCELHEADER
) + (n
+ 1)*sizeof(ACCELENTRY
));
226 lpAccelTbl
= (LPACCELHEADER
)GlobalLock(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 GlobalUnlock(hAccel
);
242 FreeResource( rsc_mem
);
245 fprintf(stderr
,"LoadAcceleratorsW: not implemented\n");
250 HANDLE32
WIN32_LoadAcceleratorsA(HINSTANCE instance
, LPCSTR lpTableName
)
252 LPWSTR uni
=STRING32_DupAnsiToUni(lpTableName
);
253 HANDLE32 result
=WIN32_LoadAcceleratorsW(instance
,uni
);
258 /**********************************************************************
262 WIN32_LoadStringW(HINSTANCE instance
, DWORD resource_id
, LPWSTR buffer
, int buflen
)
264 HANDLE32 hmem
, hrsrc
;
269 dprintf_resource(stddeb
, "LoadString: instance = %04x, id = %04x, buffer = %08x, "
270 "length = %d\n", instance
, (int)resource_id
, (int) buffer
, buflen
);
272 hrsrc
= FindResource32( instance
, (LPCWSTR
)((resource_id
>>4)+1),
273 (LPCWSTR
)RT_STRING
);
274 if (!hrsrc
) return 0;
275 hmem
= LoadResource32( instance
, hrsrc
);
278 p
= LockResource32(hmem
);
279 string_num
= resource_id
& 0x000f;
280 for (i
= 0; i
< string_num
; i
++)
283 dprintf_resource( stddeb
, "strlen = %d\n", (int)*p
);
285 i
= MIN(buflen
- 1, *p
);
289 memcpy(buffer
, p
+ 1, i
* sizeof (WCHAR
));
290 buffer
[i
] = (WCHAR
) 0;
293 buffer
[0] = (WCHAR
) 0;
297 fprintf(stderr
,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen
, *p
);
298 fprintf(stderr
,"LoadString // and try to obtain string '%s'\n", p
+ 1);
301 dprintf_resource(stddeb
,"LoadString // '%s' copied !\n", buffer
);
305 /**********************************************************************
309 WIN32_LoadStringA(HINSTANCE instance
, DWORD resource_id
, LPSTR buffer
, int buflen
)
311 WCHAR
*buffer2
= xmalloc(buflen
*2);
312 int retval
= WIN32_LoadStringW(instance
, resource_id
, buffer2
, buflen
);
315 *buffer
++ = (char) *buffer2
++;
320 HICON
LoadIconW32(HINSTANCE hisnt
, LPCTSTR lpszIcon
)
323 return LoadIcon(0, IDI_APPLICATION
);
326 HICON
LoadIconA32(HINSTANCE hinst
, LPCTSTR lpszIcon
)
329 return LoadIconW32(hinst
, lpszIcon
);
331 /**********************************************************************
334 HBITMAP
WIN32_LoadBitmapW( HANDLE instance
, LPCWSTR name
)
342 if (!instance
) /* OEM bitmap */
344 if (HIWORD((int)name
)) return 0;
345 return OBM_LoadBitmap( LOWORD((int)name
) );
348 if (!(hRsrc
= FindResource32( instance
, name
,
349 (LPWSTR
)RT_BITMAP
))) return 0;
350 if (!(handle
= LoadResource32( instance
, hRsrc
))) return 0;
352 info
= (BITMAPINFO
*)LockResource32( handle
);
353 if ((hdc
= GetDC(0)) != 0)
355 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, DIB_RGB_COLORS
);
356 hbitmap
= CreateDIBitmap( hdc
, &info
->bmiHeader
, CBM_INIT
,
357 bits
, info
, DIB_RGB_COLORS
);
362 /**********************************************************************
365 HBITMAP
WIN32_LoadBitmapA( HANDLE instance
, LPCSTR name
)
369 res
= WIN32_LoadBitmapW(instance
,(LPWSTR
)name
);
371 LPWSTR uni
=STRING32_DupAnsiToUni(name
);
372 res
=WIN32_LoadBitmapW(instance
,uni
);
378 /**********************************************************************
380 * LoadMenu helper function
382 BYTE
* WIN32_ParseMenu(HMENU hMenu
,BYTE
*it
)
384 char entry
[200]; /* buffer for ANSI names */
393 /* POPUP entries have no ID, but a sub menu */
396 wMenuID
= CreatePopupMenu();
397 len
= STRING32_lstrlenW((LPWSTR
)it
);
399 it
+= sizeof(WCHAR
)*(len
+1);
400 it
= WIN32_ParseMenu(wMenuID
,it
);
405 len
= STRING32_lstrlenW((LPWSTR
)it
);
406 it
+= sizeof(WCHAR
)*(len
+1);
407 if(!wMenuID
&& !*utext
)
408 flags
|= MF_SEPARATOR
;
410 if(len
>=bufsize
) continue; /* hack hack */
411 STRING32_UniToAnsi(entry
,utext
);
412 AppendMenu(hMenu
,flags
,wMenuID
,MAKE_SEGPTR(entry
));
413 }while(!(flags
& MF_END
));
417 /*****************************************************************
418 * LoadMenuIndirectW (USER32.371)
420 HMENU
WIN32_LoadMenuIndirectW(void *menu
)
423 HMENU hMenu
= CreateMenu();
426 fprintf(stderr
,"Unknown menu header\n");
428 WIN32_ParseMenu(hMenu
,it
);
432 /*****************************************************************
433 * LoadMenuW (USER32.372)
435 HMENU
WIN32_LoadMenuW(HANDLE instance
, LPCWSTR name
)
438 hrsrc
=FindResource32(instance
,name
,(LPWSTR
)RT_MENU
);
440 return WIN32_LoadMenuIndirectW(LoadResource32(instance
, hrsrc
));
443 /*****************************************************************
444 * LoadMenuIndirectA (USER32.370)
446 HMENU
WIN32_LoadMenuIndirectA(void *menu
)
448 fprintf(stderr
,"WIN32_LoadMenuIndirectA not implemented\n");
452 /*****************************************************************
453 * LoadMenuA (USER32.370)
455 HMENU
WIN32_LoadMenuA(HANDLE instance
,LPCSTR name
)
459 res
= WIN32_LoadMenuW(instance
,(LPWSTR
)name
);
461 LPWSTR uni
=STRING32_DupAnsiToUni(name
);
462 res
=WIN32_LoadMenuW(instance
,uni
);