diff --git a/loader/ne/resource.c b/loader/ne/resource.c index 359f6c9caf1..b38fad05b66 100644 --- a/loader/ne/resource.c +++ b/loader/ne/resource.c @@ -510,8 +510,5 @@ BOOL16 NE_FreeResource( NE_MODULE *pModule, HGLOBAL16 handle ) pTypeInfo = (NE_TYPEINFO *)pNameInfo; } - TRACE(resource, "[%04x]: no intrinsic resource for %04x, assuming DirectResAlloc()!\n", - pModule->self, handle ); - GlobalFree16( handle ); return handle; } diff --git a/loader/resource.c b/loader/resource.c index a24ec98c49a..54588a3f948 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -13,12 +13,15 @@ #include #include #include "winbase.h" +#include "windef.h" #include "winuser.h" #include "wine/winbase16.h" #include "wine/winuser16.h" #include "gdi.h" #include "global.h" #include "heap.h" +#include "callback.h" +#include "cursoricon.h" #include "neexe.h" #include "task.h" #include "process.h" @@ -117,282 +120,468 @@ static WORD MapHRsrc16ToType( NE_MODULE *pModule, HRSRC16 hRsrc16 ) return map->elem[(int)hRsrc16-1].type; } + /********************************************************************** - * FindResource16 (KERNEL.60) + * RES_FindResource + */ +static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type, + LPCSTR name, WORD lang, + BOOL bUnicode, BOOL bRet16 ) +{ + HRSRC hRsrc = 0; + + HMODULE16 hMod16 = MapHModuleLS( hModule ); + NE_MODULE *pModule = NE_GetPtr( hMod16 ); + WINE_MODREF *wm = pModule && pModule->module32? + MODULE32_LookupHMODULE( pModule->module32 ) : NULL; + + TRACE( resource, "(%08x %s, %08x%s, %08x%s, %04x, %s, %s)\n", + hModule, NE_MODULE_NAME(pModule), + (UINT)type, HIWORD(type)? (bUnicode? debugstr_w((LPWSTR)type) : debugstr_a(type)) : "", + (UINT)name, HIWORD(name)? (bUnicode? debugstr_w((LPWSTR)name) : debugstr_a(name)) : "", + lang, + bUnicode? "W" : "A", + bRet16? "NE" : "PE" ); + + if ( !pModule ) return 0; + + if ( wm ) + { + /* 32-bit PE/ELF module */ + LPWSTR typeStr, nameStr; + + if ( HIWORD( type ) && !bUnicode ) + typeStr = HEAP_strdupAtoW( GetProcessHeap(), 0, type ); + else + typeStr = (LPWSTR)type; + if ( HIWORD( name ) && !bUnicode ) + nameStr = HEAP_strdupAtoW( GetProcessHeap(), 0, name ); + else + nameStr = (LPWSTR)name; + + switch ( wm->type ) + { + case MODULE32_PE: + hRsrc = PE_FindResourceExW( wm, nameStr, typeStr, lang ); + break; + + case MODULE32_ELF: + hRsrc = LIBRES_FindResource( hModule, nameStr, typeStr ); + break; + + default: + ERR( resource, "unknown module type %d\n", wm->type ); + break; + } + + if ( HIWORD( type ) && !bUnicode ) + HeapFree( GetProcessHeap(), 0, typeStr ); + if ( HIWORD( name ) && !bUnicode ) + HeapFree( GetProcessHeap(), 0, nameStr ); + + + /* If we need to return 16-bit HRSRC, perform conversion */ + if ( bRet16 ) + hRsrc = MapHRsrc32To16( pModule, hRsrc, + HIWORD( type )? 0 : LOWORD( type ) ); + } + else + { + /* 16-bit NE module */ + LPSTR typeStr, nameStr; + + if ( HIWORD( type ) && bUnicode ) + typeStr = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)type ); + else + typeStr = (LPSTR)type; + if ( HIWORD( name ) && bUnicode ) + nameStr = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)name ); + else + nameStr = (LPSTR)name; + + hRsrc = NE_FindResource( pModule, nameStr, typeStr ); + + if ( HIWORD( type ) && bUnicode ) + HeapFree( GetProcessHeap(), 0, typeStr ); + if ( HIWORD( name ) && bUnicode ) + HeapFree( GetProcessHeap(), 0, nameStr ); + + + /* If we need to return 32-bit HRSRC, no conversion is necessary, + we simply use the 16-bit HRSRC as 32-bit HRSRC */ + } + + return hRsrc; +} + +/********************************************************************** + * RES_SizeofResource + */ +static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 ) +{ + DWORD size = 0; + + HMODULE16 hMod16 = MapHModuleLS( hModule ); + NE_MODULE *pModule = NE_GetPtr( hMod16 ); + WINE_MODREF *wm = pModule && pModule->module32? + MODULE32_LookupHMODULE( pModule->module32 ) : NULL; + + TRACE( resource, "(%08x %s, %08x, %s)\n", + hModule, NE_MODULE_NAME(pModule), hRsrc, bRet16? "NE" : "PE" ); + + if ( !pModule || !hRsrc ) return 0; + + if ( wm ) + { + /* 32-bit PE/ELF module */ + + /* If we got a 16-bit hRsrc, convert it */ + HRSRC hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); + + switch ( wm->type ) + { + case MODULE32_PE: + size = PE_SizeofResource( hModule, hRsrc32 ); + break; + + case MODULE32_ELF: + size = LIBRES_SizeofResource( hModule, hRsrc32 ); + break; + + default: + ERR( resource, "unknown module type %d\n", wm->type ); + break; + } + } + else + { + /* 16-bit NE module */ + + /* If we got a 32-bit hRsrc, we don't need to convert it */ + + size = NE_AccessResource( pModule, hRsrc ); + } + + return size; +} + +/********************************************************************** + * RES_AccessResource + */ +static HFILE RES_AccessResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 ) +{ + HFILE hFile = HFILE_ERROR; + + HMODULE16 hMod16 = MapHModuleLS( hModule ); + NE_MODULE *pModule = NE_GetPtr( hMod16 ); + WINE_MODREF *wm = pModule && pModule->module32? + MODULE32_LookupHMODULE( pModule->module32 ) : NULL; + + TRACE( resource, "(%08x %s, %08x, %s)\n", + hModule, NE_MODULE_NAME(pModule), hRsrc, bRet16? "NE" : "PE" ); + + if ( !pModule || !hRsrc ) return HFILE_ERROR; + + if ( wm ) + { + /* 32-bit PE/ELF module */ +#if 0 + /* If we got a 16-bit hRsrc, convert it */ + HRSRC hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); +#endif + + FIXME( resource, "32-bit modules not yet supported.\n" ); + hFile = HFILE_ERROR; + + /* If we need to return a 16-bit file handle, convert it */ + if ( bRet16 ) + hFile = FILE_AllocDosHandle( hFile ); + } + else + { + /* 16-bit NE module */ + + /* If we got a 32-bit hRsrc, we don't need to convert it */ + + hFile = NE_AccessResource( pModule, hRsrc ); + + /* If we are to return a 32-bit file handle, convert it */ + if ( !bRet16 ) + hFile = FILE_GetHandle( hFile ); + } + + return hFile; +} + +/********************************************************************** + * RES_LoadResource + */ +static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 ) +{ + HGLOBAL hMem = 0; + + HMODULE16 hMod16 = MapHModuleLS( hModule ); + NE_MODULE *pModule = NE_GetPtr( hMod16 ); + WINE_MODREF *wm = pModule && pModule->module32? + MODULE32_LookupHMODULE( pModule->module32 ) : NULL; + + TRACE( resource, "(%08x %s, %08x, %s)\n", + hModule, NE_MODULE_NAME(pModule), hRsrc, bRet16? "NE" : "PE" ); + + if ( !pModule || !hRsrc ) return 0; + + if ( wm ) + { + /* 32-bit PE/ELF module */ + + /* If we got a 16-bit hRsrc, convert it */ + HRSRC hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); + + switch ( wm->type ) + { + case MODULE32_PE: + hMem = PE_LoadResource( wm, hRsrc32 ); + break; + + case MODULE32_ELF: + hMem = LIBRES_LoadResource( hModule, hRsrc32 ); + break; + + default: + ERR( resource, "unknown module type %d\n", wm->type ); + break; + } + + /* If we need to return a 16-bit resource, convert it */ + if ( bRet16 ) + { + WORD type = MapHRsrc16ToType( pModule, hRsrc ); + DWORD size = SizeofResource( hModule, hRsrc ); + LPVOID bits = LockResource( hMem ); + + hMem = NE_LoadPEResource( pModule, type, bits, size ); + } + } + else + { + /* 16-bit NE module */ + + /* If we got a 32-bit hRsrc, we don't need to convert it */ + + hMem = NE_LoadResource( pModule, hRsrc ); + + /* If we are to return a 32-bit resource, we should probably + convert it but we don't for now. FIXME !!! */ + } + + return hMem; +} + +/********************************************************************** + * RES_LockResource + */ +static LPVOID RES_LockResource( HGLOBAL handle, BOOL bRet16 ) +{ + LPVOID bits = NULL; + + TRACE( resource, "(%08x, %s)\n", handle, bRet16? "NE" : "PE" ); + + if ( HIWORD( handle ) ) + { + /* 32-bit memory handle */ + + if ( bRet16 ) + FIXME( resource, "can't return SEGPTR to 32-bit resource %08x.\n", handle ); + else + bits = (LPVOID)handle; + } + else + { + /* 16-bit memory handle */ + + /* May need to reload the resource if discarded */ + SEGPTR segPtr = WIN16_GlobalLock16( handle ); + + if ( bRet16 ) + bits = (LPVOID)segPtr; + else + bits = PTR_SEG_TO_LIN( segPtr ); + } + + return bits; +} + +/********************************************************************** + * RES_FreeResource + */ +static BOOL RES_FreeResource( HGLOBAL handle ) +{ + HGLOBAL retv = handle; + + TRACE( resource, "(%08x)\n", handle ); + + if ( HIWORD( handle ) ) + { + /* 32-bit memory handle: nothing to do */ + } + else + { + /* 16-bit memory handle */ + NE_MODULE *pModule = NE_GetPtr( FarGetOwner16( handle ) ); + + /* Try NE resource first */ + retv = NE_FreeResource( pModule, handle ); + + /* If this failed, call USER.DestroyIcon32; this will check + whether it is a shared cursor/icon; if not it will call + GlobalFree16() */ + if ( retv ) + if ( Callout.DestroyIcon32 ) + retv = Callout.DestroyIcon32( handle, CID_RESOURCE ); + else + retv = GlobalFree16( handle ); + } + + return (BOOL)retv; +} + + +/********************************************************************** + * FindResource16 (KERNEL.60) */ HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type ) { LPCSTR nameStr = HIWORD(name)? PTR_SEG_TO_LIN(name) : (LPCSTR)name; LPCSTR typeStr = HIWORD(type)? PTR_SEG_TO_LIN(type) : (LPCSTR)type; - NE_MODULE *pModule = NE_GetPtr( hModule ); - if ( !pModule ) return 0; - - if ( pModule->module32 ) - { - HANDLE hRsrc32 = FindResourceA( pModule->module32, nameStr, typeStr ); - return MapHRsrc32To16( pModule, hRsrc32, HIWORD(type)? 0 : type ); - } - - return NE_FindResource( pModule, nameStr, typeStr ); + return RES_FindResource( hModule, typeStr, nameStr, + WINE_LanguageId, FALSE, TRUE ); } /********************************************************************** - * FindResource32A (KERNEL32.128) + * FindResourceA (KERNEL32.128) */ -HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type) +HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) { - return FindResourceExA(hModule,type,name,WINE_LanguageId); + return RES_FindResource( hModule, type, name, + WINE_LanguageId, FALSE, FALSE ); } /********************************************************************** - * FindResourceEx32A (KERNEL32.129) + * FindResourceExA (KERNEL32.129) */ -HANDLE WINAPI FindResourceExA( HMODULE hModule, LPCSTR type, LPCSTR name, - WORD lang -) { - LPWSTR xname,xtype; - HANDLE ret; - - if (HIWORD((DWORD)name)) - xname = HEAP_strdupAtoW( GetProcessHeap(), 0, name ); - else - xname = (LPWSTR)name; - if (HIWORD((DWORD)type)) - xtype = HEAP_strdupAtoW( GetProcessHeap(), 0, type); - else - xtype = (LPWSTR)type; - ret = FindResourceExW( hModule, xtype, xname, lang ); - if (HIWORD((DWORD)name)) HeapFree( GetProcessHeap(), 0, xname ); - if (HIWORD((DWORD)type)) HeapFree( GetProcessHeap(), 0, xtype ); - return ret; -} - - -/********************************************************************** - * FindResourceEx32W (KERNEL32.130) - */ -HRSRC WINAPI FindResourceExW( HMODULE hModule, LPCWSTR type, - LPCWSTR name, WORD lang ) +HANDLE WINAPI FindResourceExA( HMODULE hModule, + LPCSTR type, LPCSTR name, WORD lang ) { - WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); - HRSRC hrsrc; - - TRACE(resource, "module=%08x(%s) type=%s name=%s\n", - hModule, wm->modname, - debugres_w (type), - debugres_w (name)); - - if (!wm) return (HRSRC)0; - - switch (wm->type) - { - case MODULE32_PE: - hrsrc = PE_FindResourceExW(wm,name,type,lang); - break; - - case MODULE32_ELF: - hrsrc = LIBRES_FindResource( hModule, name, type ); - break; - - default: - ERR(module,"unknown module type %d\n",wm->type); - return (HRSRC)0; - } - - if ( !hrsrc ) - WARN(resource,"0x%08x(%s) %s(%s) not found!\n", - hModule,wm->modname, debugres_w (name), debugres_w (type)); - - return hrsrc; + return RES_FindResource( hModule, type, name, + lang, FALSE, FALSE ); } +/********************************************************************** + * FindResourceExW (KERNEL32.130) + */ +HRSRC WINAPI FindResourceExW( HMODULE hModule, + LPCWSTR type, LPCWSTR name, WORD lang ) +{ + return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, + lang, TRUE, FALSE ); +} /********************************************************************** - * FindResource32W (KERNEL32.131) + * FindResourceW (KERNEL32.131) */ HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type) { - return FindResourceExW(hModule,type,name,WINE_LanguageId); + return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, + WINE_LanguageId, TRUE, FALSE ); } /********************************************************************** - * LoadResource16 (KERNEL.61) + * LoadResource16 (KERNEL.61) */ HGLOBAL16 WINAPI LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc ) { - NE_MODULE *pModule = NE_GetPtr( hModule ); - if ( !pModule ) return 0; - - if ( pModule->module32 ) - { - HANDLE hRsrc32 = MapHRsrc16To32( pModule, hRsrc ); - WORD type = MapHRsrc16ToType( pModule, hRsrc ); - HGLOBAL image = LoadResource( pModule->module32, hRsrc32 ); - DWORD size = SizeofResource( pModule->module32, hRsrc32 ); - LPVOID bits = LockResource( image ); - - return NE_LoadPEResource( pModule, type, bits, size ); - } - - return NE_LoadResource( pModule, hRsrc ); + return RES_LoadResource( hModule, hRsrc, TRUE ); } /********************************************************************** - * LoadResource32 (KERNEL32.370) - * 'loads' a resource. The current implementation just returns a pointer - * into the already mapped image. - * RETURNS - * pointer into the mapped resource of the passed module + * LoadResource (KERNEL32.370) */ -HGLOBAL WINAPI LoadResource( - HINSTANCE hModule, /* [in] module handle */ - HRSRC hRsrc ) /* [in] resource handle */ +HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc ) { - WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); - - TRACE(resource, "module=%04x res=%04x\n", - hModule, hRsrc ); - if (!hRsrc) { - ERR(resource,"hRsrc is 0, return 0.\n"); - return 0; - } - if (!wm) return 0; - - switch (wm->type) - { - case MODULE32_PE: - return PE_LoadResource(wm,hRsrc); - - case MODULE32_ELF: - return LIBRES_LoadResource( hModule, hRsrc ); - - default: - ERR(resource,"unknown module type %d\n",wm->type); - break; - } - return 0; + return RES_LoadResource( hModule, hRsrc, FALSE ); } /********************************************************************** - * LockResource16 (KERNEL.62) + * LockResource16 (KERNEL.62) */ SEGPTR WINAPI WIN16_LockResource16( HGLOBAL16 handle ) { - TRACE( resource, "handle=%04x\n", handle ); - if (!handle) return (SEGPTR)0; - - /* May need to reload the resource if discarded */ - return (SEGPTR)WIN16_GlobalLock16( handle ); + return (SEGPTR)RES_LockResource( handle, TRUE ); } LPVOID WINAPI LockResource16( HGLOBAL16 handle ) { - return (LPVOID)PTR_SEG_TO_LIN( WIN16_LockResource16( handle ) ); + return RES_LockResource( handle, FALSE ); } /********************************************************************** - * LockResource32 (KERNEL32.384) + * LockResource (KERNEL32.384) */ LPVOID WINAPI LockResource( HGLOBAL handle ) { - return (LPVOID)handle; + return RES_LockResource( handle, FALSE ); } - /********************************************************************** - * FreeResource16 (KERNEL.63) + * FreeResource16 (KERNEL.63) */ BOOL16 WINAPI FreeResource16( HGLOBAL16 handle ) { - NE_MODULE *pModule = NE_GetPtr( FarGetOwner16(handle) ); - if ( !pModule ) return handle; - - if ( pModule->module32 ) - return NE_FreePEResource( pModule, handle ); - - return NE_FreeResource( pModule, handle ); + return RES_FreeResource( handle ); } /********************************************************************** - * FreeResource32 (KERNEL32.145) + * FreeResource (KERNEL32.145) */ BOOL WINAPI FreeResource( HGLOBAL handle ) { - /* no longer used in Win32 */ - return TRUE; + return RES_FreeResource( handle ); } /********************************************************************** - * AccessResource16 (KERNEL.64) + * AccessResource16 (KERNEL.64) */ INT16 WINAPI AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc ) { - NE_MODULE *pModule = NE_GetPtr( hModule ); - if ( !pModule ) return 0; - - if ( pModule->module32 ) - { - HANDLE hRsrc32 = MapHRsrc16To32( pModule, hRsrc ); - HFILE hFile32 = AccessResource( pModule->module32, hRsrc32 ); - return FILE_AllocDosHandle( hFile32 ); - } - - return NE_AccessResource( pModule, hRsrc ); + return RES_AccessResource( hModule, hRsrc, TRUE ); } /********************************************************************** - * AccessResource32 (KERNEL32.64) + * AccessResource (KERNEL32.64) */ INT WINAPI AccessResource( HMODULE hModule, HRSRC hRsrc ) { - FIXME(resource,"(module=%08x res=%08x),not implemented\n", hModule, hRsrc); - return 0; + return RES_AccessResource( hModule, hRsrc, FALSE ); } - /********************************************************************** - * SizeofResource16 (KERNEL.65) + * SizeofResource16 (KERNEL.65) */ DWORD WINAPI SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc ) { - NE_MODULE *pModule = NE_GetPtr( hModule ); - if ( !pModule ) return 0; - - if ( pModule->module32 ) - { - HANDLE hRsrc32 = MapHRsrc16To32( pModule, hRsrc ); - return SizeofResource( hModule, hRsrc32 ); - } - - return NE_SizeofResource( pModule, hRsrc ); + return RES_SizeofResource( hModule, hRsrc, TRUE ); } /********************************************************************** - * SizeofResource32 (KERNEL32.522) + * SizeofResource (KERNEL32.522) */ DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc ) { - WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); - - TRACE(resource, "module=%08x res=%08x\n", hModule, hRsrc ); - if (!wm) return 0; - - switch (wm->type) - { - case MODULE32_PE: - return PE_SizeofResource(hModule,hRsrc); - - case MODULE32_ELF: - return LIBRES_SizeofResource( hModule, hRsrc ); - - default: - ERR(module,"unknown module type %d\n",wm->type); - break; - } - return 0; + return RES_SizeofResource( hModule, hRsrc, FALSE ); } + /********************************************************************** * LoadAccelerators16 [USER.177] */