4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
11 #include <sys/types.h>
17 #include "wine/winbase16.h"
18 #include "wine/exception.h"
23 #include "cursoricon.h"
29 #include "debugtools.h"
33 DEFAULT_DEBUG_CHANNEL(resource
);
35 #define HRSRC_MAP_BLOCKSIZE 16
37 typedef struct _HRSRC_ELEM
43 typedef struct _HRSRC_MAP
50 /**********************************************************************
53 static HRSRC16
MapHRsrc32To16( NE_MODULE
*pModule
, HANDLE hRsrc32
, WORD type
)
55 HRSRC_MAP
*map
= (HRSRC_MAP
*)pModule
->hRsrcMap
;
59 /* On first call, initialize HRSRC map */
62 if ( !(map
= (HRSRC_MAP
*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
63 sizeof(HRSRC_MAP
) ) ) )
65 ERR("Cannot allocate HRSRC map\n" );
68 pModule
->hRsrcMap
= (LPVOID
)map
;
71 /* Check whether HRSRC32 already in map */
72 for ( i
= 0; i
< map
->nUsed
; i
++ )
73 if ( map
->elem
[i
].hRsrc
== hRsrc32
)
74 return (HRSRC16
)(i
+ 1);
76 /* If no space left, grow table */
77 if ( map
->nUsed
== map
->nAlloc
)
79 if ( !(newElem
= (HRSRC_ELEM
*)HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
81 (map
->nAlloc
+ HRSRC_MAP_BLOCKSIZE
)
82 * sizeof(HRSRC_ELEM
) ) ))
84 ERR("Cannot grow HRSRC map\n" );
88 map
->nAlloc
+= HRSRC_MAP_BLOCKSIZE
;
91 /* Add HRSRC32 to table */
92 map
->elem
[map
->nUsed
].hRsrc
= hRsrc32
;
93 map
->elem
[map
->nUsed
].type
= type
;
96 return (HRSRC16
)map
->nUsed
;
99 /**********************************************************************
102 static HANDLE
MapHRsrc16To32( NE_MODULE
*pModule
, HRSRC16 hRsrc16
)
104 HRSRC_MAP
*map
= (HRSRC_MAP
*)pModule
->hRsrcMap
;
105 if ( !map
|| !hRsrc16
|| (int)hRsrc16
> map
->nUsed
) return 0;
107 return map
->elem
[(int)hRsrc16
-1].hRsrc
;
110 /**********************************************************************
113 static WORD
MapHRsrc16ToType( NE_MODULE
*pModule
, HRSRC16 hRsrc16
)
115 HRSRC_MAP
*map
= (HRSRC_MAP
*)pModule
->hRsrcMap
;
116 if ( !map
|| !hRsrc16
|| (int)hRsrc16
> map
->nUsed
) return 0;
118 return map
->elem
[(int)hRsrc16
-1].type
;
122 /* filter for page-fault exceptions */
123 static WINE_EXCEPTION_FILTER(page_fault
)
125 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
)
126 return EXCEPTION_EXECUTE_HANDLER
;
127 return EXCEPTION_CONTINUE_SEARCH
;
130 static HRSRC
RES_FindResource2( HMODULE hModule
, LPCSTR type
,
131 LPCSTR name
, WORD lang
,
132 BOOL bUnicode
, BOOL bRet16
)
135 HMODULE16 hMod16
= MapHModuleLS( hModule
);
136 NE_MODULE
*pModule
= NE_GetPtr( hMod16
);
137 WINE_MODREF
*wm
= pModule
&& pModule
->module32
?
138 MODULE32_LookupHMODULE( pModule
->module32
) : NULL
;
140 TRACE("(%08x %s, %08x%s, %08x%s, %04x, %s, %s)\n",
142 pModule
? (char *)NE_MODULE_NAME(pModule
) : "NULL dereference",
143 (UINT
)type
, HIWORD(type
)? (bUnicode
? debugstr_w((LPWSTR
)type
) : debugstr_a(type
)) : "",
144 (UINT
)name
, HIWORD(name
)? (bUnicode
? debugstr_w((LPWSTR
)name
) : debugstr_a(name
)) : "",
147 bRet16
? "NE" : "PE" );
153 /* 32-bit PE module */
154 LPWSTR typeStr
, nameStr
;
156 if ( HIWORD( type
) && !bUnicode
)
157 typeStr
= HEAP_strdupAtoW( GetProcessHeap(), 0, type
);
159 typeStr
= (LPWSTR
)type
;
160 if ( HIWORD( name
) && !bUnicode
)
161 nameStr
= HEAP_strdupAtoW( GetProcessHeap(), 0, name
);
163 nameStr
= (LPWSTR
)name
;
165 hRsrc
= PE_FindResourceExW( wm
, nameStr
, typeStr
, lang
);
167 if ( HIWORD( type
) && !bUnicode
)
168 HeapFree( GetProcessHeap(), 0, typeStr
);
169 if ( HIWORD( name
) && !bUnicode
)
170 HeapFree( GetProcessHeap(), 0, nameStr
);
173 /* If we need to return 16-bit HRSRC, perform conversion */
175 hRsrc
= MapHRsrc32To16( pModule
, hRsrc
,
176 HIWORD( type
)? 0 : LOWORD( type
) );
180 /* 16-bit NE module */
181 LPSTR typeStr
, nameStr
;
183 if ( HIWORD( type
) && bUnicode
)
184 typeStr
= HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)type
);
186 typeStr
= (LPSTR
)type
;
187 if ( HIWORD( name
) && bUnicode
)
188 nameStr
= HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)name
);
190 nameStr
= (LPSTR
)name
;
192 hRsrc
= NE_FindResource( pModule
, nameStr
, typeStr
);
194 if ( HIWORD( type
) && bUnicode
)
195 HeapFree( GetProcessHeap(), 0, typeStr
);
196 if ( HIWORD( name
) && bUnicode
)
197 HeapFree( GetProcessHeap(), 0, nameStr
);
200 /* If we need to return 32-bit HRSRC, no conversion is necessary,
201 we simply use the 16-bit HRSRC as 32-bit HRSRC */
207 /**********************************************************************
211 static HRSRC
RES_FindResource( HMODULE hModule
, LPCSTR type
,
212 LPCSTR name
, WORD lang
,
213 BOOL bUnicode
, BOOL bRet16
)
218 hRsrc
= RES_FindResource2(hModule
, type
, name
, lang
, bUnicode
, bRet16
);
222 WARN("page fault\n");
223 SetLastError(ERROR_INVALID_PARAMETER
);
230 /**********************************************************************
233 static DWORD
RES_SizeofResource( HMODULE hModule
, HRSRC hRsrc
, BOOL bRet16
)
237 HMODULE16 hMod16
= MapHModuleLS( hModule
);
238 NE_MODULE
*pModule
= NE_GetPtr( hMod16
);
239 WINE_MODREF
*wm
= pModule
&& pModule
->module32
?
240 MODULE32_LookupHMODULE( pModule
->module32
) : NULL
;
242 TRACE("(%08x %s, %08x, %s)\n",
243 hModule
, NE_MODULE_NAME(pModule
), hRsrc
, bRet16
? "NE" : "PE" );
245 if ( !pModule
|| !hRsrc
) return 0;
249 /* 32-bit PE module */
251 /* If we got a 16-bit hRsrc, convert it */
252 HRSRC hRsrc32
= HIWORD(hRsrc
)? hRsrc
: MapHRsrc16To32( pModule
, hRsrc
);
254 size
= PE_SizeofResource( hModule
, hRsrc32
);
258 /* 16-bit NE module */
260 /* If we got a 32-bit hRsrc, we don't need to convert it */
262 size
= NE_SizeofResource( pModule
, hRsrc
);
268 /**********************************************************************
271 static HFILE
RES_AccessResource( HMODULE hModule
, HRSRC hRsrc
, BOOL bRet16
)
273 HFILE hFile
= HFILE_ERROR
;
275 HMODULE16 hMod16
= MapHModuleLS( hModule
);
276 NE_MODULE
*pModule
= NE_GetPtr( hMod16
);
277 WINE_MODREF
*wm
= pModule
&& pModule
->module32
?
278 MODULE32_LookupHMODULE( pModule
->module32
) : NULL
;
280 TRACE("(%08x %s, %08x, %s)\n",
281 hModule
, NE_MODULE_NAME(pModule
), hRsrc
, bRet16
? "NE" : "PE" );
283 if ( !pModule
|| !hRsrc
) return HFILE_ERROR
;
287 /* 32-bit PE module */
289 /* If we got a 16-bit hRsrc, convert it */
290 HRSRC hRsrc32
= HIWORD(hRsrc
)? hRsrc
: MapHRsrc16To32( pModule
, hRsrc
);
293 FIXME("32-bit modules not yet supported.\n" );
296 /* If we need to return a 16-bit file handle, convert it */
298 hFile
= FILE_AllocDosHandle( hFile
);
302 /* 16-bit NE module */
304 /* If we got a 32-bit hRsrc, we don't need to convert it */
306 hFile
= NE_AccessResource( pModule
, hRsrc
);
308 /* If we are to return a 32-bit file handle, convert it */
310 hFile
= FILE_GetHandle( hFile
);
316 /**********************************************************************
319 static HGLOBAL
RES_LoadResource( HMODULE hModule
, HRSRC hRsrc
, BOOL bRet16
)
323 HMODULE16 hMod16
= MapHModuleLS( hModule
);
324 NE_MODULE
*pModule
= NE_GetPtr( hMod16
);
325 WINE_MODREF
*wm
= pModule
&& pModule
->module32
?
326 MODULE32_LookupHMODULE( pModule
->module32
) : NULL
;
328 TRACE("(%08x %s, %08x, %s)\n",
329 hModule
, NE_MODULE_NAME(pModule
), hRsrc
, bRet16
? "NE" : "PE" );
331 if ( !pModule
|| !hRsrc
) return 0;
335 /* 32-bit PE module */
337 /* If we got a 16-bit hRsrc, convert it */
338 HRSRC hRsrc32
= HIWORD(hRsrc
)? hRsrc
: MapHRsrc16To32( pModule
, hRsrc
);
340 hMem
= PE_LoadResource( wm
, hRsrc32
);
342 /* If we need to return a 16-bit resource, convert it */
345 WORD type
= MapHRsrc16ToType( pModule
, hRsrc
);
346 DWORD size
= SizeofResource( hModule
, hRsrc
);
347 LPVOID bits
= LockResource( hMem
);
349 hMem
= NE_LoadPEResource( pModule
, type
, bits
, size
);
354 /* 16-bit NE module */
356 /* If we got a 32-bit hRsrc, we don't need to convert it */
358 hMem
= NE_LoadResource( pModule
, hRsrc
);
360 /* If we are to return a 32-bit resource, we should probably
361 convert it but we don't for now. FIXME !!! */
367 /**********************************************************************
370 static LPVOID
RES_LockResource( HGLOBAL handle
, BOOL bRet16
)
374 TRACE("(%08x, %s)\n", handle
, bRet16
? "NE" : "PE" );
376 if ( HIWORD( handle
) )
378 /* 32-bit memory handle */
381 FIXME("can't return SEGPTR to 32-bit resource %08x.\n", handle
);
383 bits
= (LPVOID
)handle
;
387 /* 16-bit memory handle */
389 /* May need to reload the resource if discarded */
390 SEGPTR segPtr
= WIN16_GlobalLock16( handle
);
393 bits
= (LPVOID
)segPtr
;
395 bits
= PTR_SEG_TO_LIN( segPtr
);
401 /**********************************************************************
404 static BOOL
RES_FreeResource( HGLOBAL handle
)
406 HGLOBAL retv
= handle
;
408 TRACE("(%08x)\n", handle
);
410 if ( HIWORD( handle
) )
412 /* 32-bit memory handle: nothing to do */
416 /* 16-bit memory handle */
417 NE_MODULE
*pModule
= NE_GetPtr( FarGetOwner16( handle
) );
419 /* Try NE resource first */
420 retv
= NE_FreeResource( pModule
, handle
);
422 /* If this failed, call USER.DestroyIcon32; this will check
423 whether it is a shared cursor/icon; if not it will call
426 if ( Callout
.DestroyIcon32
)
427 retv
= Callout
.DestroyIcon32( handle
, CID_RESOURCE
);
429 retv
= GlobalFree16( handle
);
437 /**********************************************************************
438 * FindResource16 (KERNEL.60)
440 HRSRC16 WINAPI
FindResource16( HMODULE16 hModule
, SEGPTR name
, SEGPTR type
)
442 LPCSTR nameStr
= HIWORD(name
)? PTR_SEG_TO_LIN(name
) : (LPCSTR
)name
;
443 LPCSTR typeStr
= HIWORD(type
)? PTR_SEG_TO_LIN(type
) : (LPCSTR
)type
;
445 return RES_FindResource( hModule
, typeStr
, nameStr
,
446 GetSystemDefaultLangID(), FALSE
, TRUE
);
449 /**********************************************************************
450 * FindResourceA (KERNEL32.128)
452 HANDLE WINAPI
FindResourceA( HMODULE hModule
, LPCSTR name
, LPCSTR type
)
454 return RES_FindResource( hModule
, type
, name
,
455 GetSystemDefaultLangID(), FALSE
, FALSE
);
458 /**********************************************************************
459 * FindResourceExA (KERNEL32.129)
461 HANDLE WINAPI
FindResourceExA( HMODULE hModule
,
462 LPCSTR type
, LPCSTR name
, WORD lang
)
464 return RES_FindResource( hModule
, type
, name
,
465 lang
, FALSE
, FALSE
);
468 /**********************************************************************
469 * FindResourceExW (KERNEL32.130)
471 HRSRC WINAPI
FindResourceExW( HMODULE hModule
,
472 LPCWSTR type
, LPCWSTR name
, WORD lang
)
474 return RES_FindResource( hModule
, (LPCSTR
)type
, (LPCSTR
)name
,
478 /**********************************************************************
479 * FindResourceW (KERNEL32.131)
481 HRSRC WINAPI
FindResourceW(HINSTANCE hModule
, LPCWSTR name
, LPCWSTR type
)
483 return RES_FindResource( hModule
, (LPCSTR
)type
, (LPCSTR
)name
,
484 GetSystemDefaultLangID(), TRUE
, FALSE
);
487 /**********************************************************************
488 * LoadResource16 (KERNEL.61)
490 HGLOBAL16 WINAPI
LoadResource16( HMODULE16 hModule
, HRSRC16 hRsrc
)
492 return RES_LoadResource( hModule
, hRsrc
, TRUE
);
495 /**********************************************************************
496 * LoadResource (KERNEL32.370)
498 HGLOBAL WINAPI
LoadResource( HINSTANCE hModule
, HRSRC hRsrc
)
500 return RES_LoadResource( hModule
, hRsrc
, FALSE
);
503 /**********************************************************************
504 * LockResource16 (KERNEL.62)
506 SEGPTR WINAPI
WIN16_LockResource16( HGLOBAL16 handle
)
508 return (SEGPTR
)RES_LockResource( handle
, TRUE
);
510 LPVOID WINAPI
LockResource16( HGLOBAL16 handle
)
512 return RES_LockResource( handle
, FALSE
);
515 /**********************************************************************
516 * LockResource (KERNEL32.384)
518 LPVOID WINAPI
LockResource( HGLOBAL handle
)
520 return RES_LockResource( handle
, FALSE
);
523 /**********************************************************************
524 * FreeResource16 (KERNEL.63)
526 BOOL16 WINAPI
FreeResource16( HGLOBAL16 handle
)
528 return RES_FreeResource( handle
);
531 /**********************************************************************
532 * FreeResource (KERNEL32.145)
534 BOOL WINAPI
FreeResource( HGLOBAL handle
)
536 return RES_FreeResource( handle
);
539 /**********************************************************************
540 * AccessResource16 (KERNEL.64)
542 INT16 WINAPI
AccessResource16( HINSTANCE16 hModule
, HRSRC16 hRsrc
)
544 return RES_AccessResource( hModule
, hRsrc
, TRUE
);
547 /**********************************************************************
548 * AccessResource (KERNEL32.64)
550 INT WINAPI
AccessResource( HMODULE hModule
, HRSRC hRsrc
)
552 return RES_AccessResource( hModule
, hRsrc
, FALSE
);
555 /**********************************************************************
556 * SizeofResource16 (KERNEL.65)
558 DWORD WINAPI
SizeofResource16( HMODULE16 hModule
, HRSRC16 hRsrc
)
560 return RES_SizeofResource( hModule
, hRsrc
, TRUE
);
563 /**********************************************************************
564 * SizeofResource (KERNEL32.522)
566 DWORD WINAPI
SizeofResource( HINSTANCE hModule
, HRSRC hRsrc
)
568 return RES_SizeofResource( hModule
, hRsrc
, FALSE
);
573 /**********************************************************************
574 * EnumResourceTypesA (KERNEL32.90)
576 BOOL WINAPI
EnumResourceTypesA( HMODULE hmodule
,ENUMRESTYPEPROCA lpfun
,
579 /* FIXME: move WINE_MODREF stuff here */
580 return PE_EnumResourceTypesA(hmodule
,lpfun
,lParam
);
583 /**********************************************************************
584 * EnumResourceTypesW (KERNEL32.91)
586 BOOL WINAPI
EnumResourceTypesW( HMODULE hmodule
,ENUMRESTYPEPROCW lpfun
,
589 /* FIXME: move WINE_MODREF stuff here */
590 return PE_EnumResourceTypesW(hmodule
,lpfun
,lParam
);
593 /**********************************************************************
594 * EnumResourceNamesA (KERNEL32.88)
596 BOOL WINAPI
EnumResourceNamesA( HMODULE hmodule
, LPCSTR type
,
597 ENUMRESNAMEPROCA lpfun
, LONG lParam
)
599 /* FIXME: move WINE_MODREF stuff here */
600 return PE_EnumResourceNamesA(hmodule
,type
,lpfun
,lParam
);
602 /**********************************************************************
603 * EnumResourceNamesW (KERNEL32.89)
605 BOOL WINAPI
EnumResourceNamesW( HMODULE hmodule
, LPCWSTR type
,
606 ENUMRESNAMEPROCW lpfun
, LONG lParam
)
608 /* FIXME: move WINE_MODREF stuff here */
609 return PE_EnumResourceNamesW(hmodule
,type
,lpfun
,lParam
);
612 /**********************************************************************
613 * EnumResourceLanguagesA (KERNEL32.86)
615 BOOL WINAPI
EnumResourceLanguagesA( HMODULE hmodule
, LPCSTR type
,
616 LPCSTR name
, ENUMRESLANGPROCA lpfun
,
619 /* FIXME: move WINE_MODREF stuff here */
620 return PE_EnumResourceLanguagesA(hmodule
,type
,name
,lpfun
,lParam
);
622 /**********************************************************************
623 * EnumResourceLanguagesW (KERNEL32.87)
625 BOOL WINAPI
EnumResourceLanguagesW( HMODULE hmodule
, LPCWSTR type
,
626 LPCWSTR name
, ENUMRESLANGPROCW lpfun
,
629 /* FIXME: move WINE_MODREF stuff here */
630 return PE_EnumResourceLanguagesW(hmodule
,type
,name
,lpfun
,lParam
);