From 80a69b6bdfcb9621e6447da0f4a6a1c3aa71a949 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Wed, 25 Nov 1998 17:58:51 +0000 Subject: [PATCH] Moved ...Resource16 routines to loader/resource.c. Implemented accessing PE-file resources with 16-bit resource routines. --- include/module.h | 10 +++ loader/ne/resource.c | 109 ++++++++---------------- loader/resource.c | 193 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 235 insertions(+), 77 deletions(-) diff --git a/include/module.h b/include/module.h index ea75aba239a..d5758c5f0e8 100644 --- a/include/module.h +++ b/include/module.h @@ -52,6 +52,7 @@ typedef struct _NE_MODULE WORD self_loading_sel; /* 46 Selector used for self-loading apps. */ LPDOSTASK lpDosTask; LPVOID dos_image; /* pointer to DOS memory (for DOS apps) */ + LPVOID hRsrcMap; /* HRSRC 16->32 map (for 32-bit modules) */ } NE_MODULE; @@ -168,6 +169,11 @@ extern HINSTANCE16 NE_LoadModule( LPCSTR name, HINSTANCE16 *hPrevInstance, /* loader/ne/resource.c */ extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16); extern BOOL32 NE_InitResourceHandler( HMODULE16 hModule ); +extern HRSRC16 NE_FindResource( NE_MODULE *pModule, LPCSTR name, LPCSTR type ); +extern INT16 NE_AccessResource( NE_MODULE *pModule, HRSRC16 hRsrc ); +extern DWORD NE_SizeofResource( NE_MODULE *pModule, HRSRC16 hRsrc ); +extern HGLOBAL16 NE_LoadResource( NE_MODULE *pModule, HRSRC16 hRsrc ); +extern BOOL16 NE_FreeResource( NE_MODULE *pModule, HGLOBAL16 handle ); /* loader/ne/segment.c */ extern BOOL32 NE_LoadSegment( NE_MODULE *pModule, WORD segnum ); @@ -178,6 +184,10 @@ extern BOOL32 NE_CreateSegments( NE_MODULE *pModule ); extern HINSTANCE16 NE_CreateInstance( NE_MODULE *pModule, HINSTANCE16 *prev, BOOL32 lib_only ); +/* loader/ne/convert.c */ +HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size ); +BOOL16 NE_FreePEResource( NE_MODULE *pModule, HGLOBAL16 handle ); + /* if1632/builtin.c */ extern BOOL32 BUILTIN_Init(void); extern HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL32 force ); diff --git a/loader/ne/resource.c b/loader/ne/resource.c index da379441a62..83f8c602b3e 100644 --- a/loader/ne/resource.c +++ b/loader/ne/resource.c @@ -6,7 +6,6 @@ * Copyright 1997 Alex Korobka */ -#include #include #include #include @@ -32,7 +31,7 @@ * Find the type and resource id from their names. * Return value is MAKELONG( typeId, resId ), or 0 if not found. */ -static DWORD NE_FindNameTableId( NE_MODULE *pModule, SEGPTR typeId, SEGPTR resId ) +static DWORD NE_FindNameTableId( NE_MODULE *pModule, LPCSTR typeId, LPCSTR resId ) { NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2); NE_NAMEINFO *pNameInfo; @@ -63,10 +62,10 @@ static DWORD NE_FindNameTableId( NE_MODULE *pModule, SEGPTR typeId, SEGPTR resId if (p[1] & 0x8000) { if (!HIWORD(typeId)) continue; - if (lstrcmpi32A( (char *)PTR_SEG_TO_LIN(typeId), + if (lstrcmpi32A( typeId, (char *)(p + 3) )) continue; } - else if (HIWORD(typeId) || ((typeId & ~0x8000)!= p[1])) + else if (HIWORD(typeId) || (((DWORD)typeId & ~0x8000)!= p[1])) continue; /* Now check for the id */ @@ -74,11 +73,11 @@ static DWORD NE_FindNameTableId( NE_MODULE *pModule, SEGPTR typeId, SEGPTR resId if (p[2] & 0x8000) { if (!HIWORD(resId)) continue; - if (lstrcmpi32A( (char *)PTR_SEG_TO_LIN(resId), + if (lstrcmpi32A( resId, (char*)(p+3)+strlen((char*)(p+3))+1 )) continue; } - else if (HIWORD(resId) || ((resId & ~0x8000) != p[2])) + else if (HIWORD(resId) || (((DWORD)resId & ~0x8000) != p[2])) continue; /* If we get here, we've found the entry */ @@ -100,13 +99,13 @@ static DWORD NE_FindNameTableId( NE_MODULE *pModule, SEGPTR typeId, SEGPTR resId * Find header struct for a particular resource type. */ static NE_TYPEINFO* NE_FindTypeSection( NE_MODULE *pModule, - NE_TYPEINFO *pTypeInfo, SEGPTR typeId ) + NE_TYPEINFO *pTypeInfo, LPCSTR typeId ) { /* start from pTypeInfo */ if (HIWORD(typeId) != 0) /* Named type */ { - char *str = (char *)PTR_SEG_TO_LIN( typeId ); + LPCSTR str = typeId; BYTE len = strlen( str ); while (pTypeInfo->type_id) { @@ -146,7 +145,7 @@ static NE_TYPEINFO* NE_FindTypeSection( NE_MODULE *pModule, * Find a resource once the type info structure has been found. */ static HRSRC16 NE_FindResourceFromType( NE_MODULE *pModule, - NE_TYPEINFO *pTypeInfo, SEGPTR resId ) + NE_TYPEINFO *pTypeInfo, LPCSTR resId ) { BYTE *p; int count; @@ -154,7 +153,7 @@ static HRSRC16 NE_FindResourceFromType( NE_MODULE *pModule, if (HIWORD(resId) != 0) /* Named resource */ { - char *str = (char *)PTR_SEG_TO_LIN( resId ); + LPCSTR str = resId; BYTE len = strlen( str ); for (count = pTypeInfo->count; count > 0; count--, pNameInfo++) { @@ -249,7 +248,7 @@ FARPROC16 WINAPI SetResourceHandler( HMODULE16 hModule, SEGPTR typeId, for (;;) { - if (!(pTypeInfo = NE_FindTypeSection( pModule, pTypeInfo, typeId ))) + if (!(pTypeInfo = NE_FindTypeSection( pModule, pTypeInfo, PTR_SEG_TO_LIN(typeId) ))) break; prevHandler = pTypeInfo->resloader; pTypeInfo->resloader = resourceHandler; @@ -260,27 +259,24 @@ FARPROC16 WINAPI SetResourceHandler( HMODULE16 hModule, SEGPTR typeId, /********************************************************************** - * FindResource16 (KERNEL.60) + * NE_FindResource */ -HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type ) +HRSRC16 NE_FindResource( NE_MODULE *pModule, LPCSTR name, LPCSTR type ) { NE_TYPEINFO *pTypeInfo; HRSRC16 hRsrc; - NE_MODULE *pModule = NE_GetPtr( hModule ); if (!pModule || !pModule->res_table) return 0; - assert( !__winelib ); /* Can't use Win16 resource functions in Winelib */ - TRACE( resource, "module=%04x name=%s type=%s\n", - hModule, debugres_a(PTR_SEG_TO_LIN(name)), + pModule->self, debugres_a(PTR_SEG_TO_LIN(name)), debugres_a(PTR_SEG_TO_LIN(type)) ); if (HIWORD(name)) /* Check for '#xxx' name */ { - char *ptr = PTR_SEG_TO_LIN( name ); + LPCSTR ptr = name; if (ptr[0] == '#') - if (!(name = (SEGPTR)atoi( ptr + 1 ))) + if (!(name = (LPCSTR)atoi( ptr + 1 ))) { WARN(resource, "Incorrect resource name: %s\n", ptr); return 0; @@ -289,9 +285,9 @@ HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type ) if (HIWORD(type)) /* Check for '#xxx' type */ { - char *ptr = PTR_SEG_TO_LIN( type ); + LPCSTR ptr = type; if (ptr[0] == '#') - if (!(type = (SEGPTR)atoi( ptr + 1 ))) + if (!(type = (LPCSTR)atoi( ptr + 1 ))) { WARN(resource, "Incorrect resource type: %s\n", ptr); return 0; @@ -303,8 +299,8 @@ HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type ) DWORD id = NE_FindNameTableId( pModule, type, name ); if (id) /* found */ { - type = LOWORD(id); - name = HIWORD(id); + type = (LPCSTR)(int)LOWORD(id); + name = (LPCSTR)(int)HIWORD(id); } } @@ -316,7 +312,7 @@ HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type ) break; if ((hRsrc = NE_FindResourceFromType(pModule, pTypeInfo, name))) { - TRACE(resource, " Found id %08lx\n", name ); + TRACE(resource, " Found id %08lx\n", (DWORD)name ); return hRsrc; } TRACE(resource, " Not found, going on\n" ); @@ -341,8 +337,6 @@ HGLOBAL16 WINAPI AllocResource( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size) TRACE( resource, "module=%04x res=%04x size=%ld\n", hModule, hRsrc, size ); - assert( !__winelib ); /* Can't use Win16 resource functions in Winelib */ - sizeShift = *(WORD *)((char *)pModule + pModule->res_table); pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); if (size < (DWORD)pNameInfo->length << sizeShift) @@ -370,18 +364,15 @@ HGLOBAL16 WINAPI DirectResAlloc( HINSTANCE16 hInstance, WORD wType, /********************************************************************** - * AccessResource16 (KERNEL.64) + * NE_AccessResource */ -INT16 WINAPI AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc ) +INT16 NE_AccessResource( NE_MODULE *pModule, HRSRC16 hRsrc ) { HFILE16 fd; - NE_MODULE *pModule = NE_GetPtr( hModule ); if (!pModule || !pModule->res_table || !hRsrc) return -1; - TRACE(resource, "module=%04x res=%04x\n", hModule, hRsrc ); - - assert( !__winelib ); /* Can't use Win16 resource functions in Winelib */ + TRACE(resource, "module=%04x res=%04x\n", pModule->self, hRsrc ); if ((fd = _lopen16( NE_MODULE_NAME(pModule), OF_READ )) != HFILE_ERROR16) { @@ -394,19 +385,16 @@ INT16 WINAPI AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc ) /********************************************************************** - * SizeofResource16 (KERNEL.65) + * NE_SizeofResource */ -DWORD WINAPI SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc ) +DWORD NE_SizeofResource( NE_MODULE *pModule, HRSRC16 hRsrc ) { NE_NAMEINFO *pNameInfo=NULL; WORD sizeShift; - NE_MODULE *pModule = NE_GetPtr( hModule ); if (!pModule || !pModule->res_table) return 0; - TRACE(resource, "module=%04x res=%04x\n", hModule, hRsrc ); - - assert( !__winelib ); /* Can't use Win16 resource functions in Winelib */ + TRACE(resource, "module=%04x res=%04x\n", pModule->self, hRsrc ); sizeShift = *(WORD *)((char *)pModule + pModule->res_table); pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); @@ -415,20 +403,17 @@ DWORD WINAPI SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc ) /********************************************************************** - * LoadResource16 (KERNEL.61) + * NE_LoadResource */ -HGLOBAL16 WINAPI LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc ) +HGLOBAL16 NE_LoadResource( NE_MODULE *pModule, HRSRC16 hRsrc ) { NE_TYPEINFO *pTypeInfo; NE_NAMEINFO *pNameInfo = NULL; - NE_MODULE *pModule = NE_GetPtr( hModule ); int d; - TRACE( resource, "module=%04x res=%04x\n", hModule, hRsrc ); + TRACE( resource, "module=%04x res=%04x\n", pModule->self, hRsrc ); if (!hRsrc || !pModule || !pModule->res_table) return 0; - assert( !__winelib ); /* Can't use Win16 resource functions in Winelib */ - /* First, verify hRsrc (just an offset from pModule to the needed pNameInfo) */ d = pModule->res_table + 2; @@ -464,12 +449,12 @@ HGLOBAL16 WINAPI LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc ) { if (pTypeInfo->resloader) pNameInfo->handle = Callbacks->CallResourceHandlerProc( - pTypeInfo->resloader, pNameInfo->handle, hModule, hRsrc ); + pTypeInfo->resloader, pNameInfo->handle, pModule->self, hRsrc ); else /* this is really bad */ { - ERR(resource, "[%04x]: Missing resource handler!\n", hModule); + ERR(resource, "[%04x]: Missing resource handler!\n", pModule->self); pNameInfo->handle = NE_DefResourceHandler( - pNameInfo->handle, hModule, hRsrc ); + pNameInfo->handle, pModule->self, hRsrc ); } if (pNameInfo->handle) @@ -485,44 +470,18 @@ HGLOBAL16 WINAPI LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc ) /********************************************************************** - * LockResource16 (KERNEL.62) + * NE_FreeResource */ -/* 16-bit version */ -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 ); -} - -/* Winelib 16-bit version */ -LPVOID WINAPI LockResource16( HGLOBAL16 handle ) -{ - assert( !__winelib ); /* Can't use Win16 resource functions in Winelib */ - - return (LPVOID)PTR_SEG_TO_LIN( WIN16_LockResource16( handle ) ); -} - - -/********************************************************************** - * FreeResource16 (KERNEL.63) - */ -BOOL16 WINAPI FreeResource16( HGLOBAL16 handle ) +BOOL16 NE_FreeResource( NE_MODULE *pModule, HGLOBAL16 handle ) { NE_TYPEINFO *pTypeInfo; NE_NAMEINFO *pNameInfo; WORD count; - NE_MODULE *pModule = NE_GetPtr( FarGetOwner(handle) ); if (!handle || !pModule || !pModule->res_table) return handle; TRACE(resource, "handle=%04x\n", handle ); - assert( !__winelib ); /* Can't use Win16 resource functions in Winelib */ - pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2); while (pTypeInfo->type_id) { diff --git a/loader/resource.c b/loader/resource.c index d482549b2f1..fe281b1f838 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -20,6 +20,7 @@ #include "task.h" #include "process.h" #include "module.h" +#include "file.h" #include "resource.h" #include "debug.h" #include "libres.h" @@ -28,6 +29,111 @@ extern WORD WINE_LanguageId; +#define HRSRC_MAP_BLOCKSIZE 16 + +typedef struct _HRSRC_ELEM +{ + HANDLE32 hRsrc; + WORD type; +} HRSRC_ELEM; + +typedef struct _HRSRC_MAP +{ + int nAlloc; + int nUsed; + HRSRC_ELEM *elem; +} HRSRC_MAP; + +/********************************************************************** + * MapHRsrc32To16 + */ +static HRSRC16 MapHRsrc32To16( NE_MODULE *pModule, HANDLE32 hRsrc32, WORD type ) +{ + HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; + HRSRC_ELEM *newElem; + int i; + + /* On first call, initialize HRSRC map */ + if ( !map ) + { + if ( !(map = (HRSRC_MAP *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(HRSRC_MAP) ) ) ) + { + ERR( resource, "Cannot allocate HRSRC map\n" ); + return 0; + } + pModule->hRsrcMap = (LPVOID)map; + } + + /* Check whether HRSRC32 already in map */ + for ( i = 0; i < map->nUsed; i++ ) + if ( map->elem[i].hRsrc == hRsrc32 ) + return (HRSRC16)(i + 1); + + /* If no space left, grow table */ + if ( map->nUsed == map->nAlloc ) + { + if ( !(newElem = (HRSRC_ELEM *)HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, + map->elem, + (map->nAlloc + HRSRC_MAP_BLOCKSIZE) + * sizeof(HRSRC_ELEM) ) )) + { + ERR( resource, "Cannot grow HRSRC map\n" ); + return 0; + } + map->elem = newElem; + map->nAlloc += HRSRC_MAP_BLOCKSIZE; + } + + /* Add HRSRC32 to table */ + map->elem[map->nUsed].hRsrc = hRsrc32; + map->elem[map->nUsed].type = type; + map->nUsed++; + + return (HRSRC16)map->nUsed; +} + +/********************************************************************** + * MapHRsrc16To32 + */ +static HANDLE32 MapHRsrc16To32( NE_MODULE *pModule, HRSRC16 hRsrc16 ) +{ + HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; + if ( !map || !hRsrc16 || (int)hRsrc16 > map->nUsed ) return 0; + + return map->elem[(int)hRsrc16-1].hRsrc; +} + +/********************************************************************** + * MapHRsrc16ToType + */ +static WORD MapHRsrc16ToType( NE_MODULE *pModule, HRSRC16 hRsrc16 ) +{ + HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; + if ( !map || !hRsrc16 || (int)hRsrc16 > map->nUsed ) return 0; + + return map->elem[(int)hRsrc16-1].type; +} + +/********************************************************************** + * 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 ) + { + HANDLE32 hRsrc32 = FindResource32A( pModule->module32, nameStr, typeStr ); + return MapHRsrc32To16( pModule, hRsrc32, HIWORD(type)? 0 : type ); + } + + return NE_FindResource( pModule, nameStr, typeStr ); +} /********************************************************************** * FindResource32A (KERNEL32.128) @@ -107,6 +213,27 @@ HRSRC32 WINAPI FindResource32W(HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type) return FindResourceEx32W(hModule,type,name,WINE_LanguageId); } +/********************************************************************** + * LoadResource16 (KERNEL.61) + */ +HGLOBAL16 WINAPI LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc ) +{ + NE_MODULE *pModule = NE_GetPtr( hModule ); + if ( !pModule ) return 0; + + if ( pModule->module32 ) + { + HANDLE32 hRsrc32 = MapHRsrc16To32( pModule, hRsrc ); + WORD type = MapHRsrc16ToType( pModule, hRsrc ); + HGLOBAL32 image = LoadResource32( pModule->module32, hRsrc32 ); + DWORD size = SizeofResource32( pModule->module32, hRsrc32 ); + LPVOID bits = LockResource32( image ); + + return NE_LoadPEResource( pModule, type, bits, size ); + } + + return NE_LoadResource( pModule, hRsrc ); +} /********************************************************************** * LoadResource32 (KERNEL32.370) @@ -144,6 +271,21 @@ HGLOBAL32 WINAPI LoadResource32( return 0; } +/********************************************************************** + * 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 ); +} +LPVOID WINAPI LockResource16( HGLOBAL16 handle ) +{ + return (LPVOID)PTR_SEG_TO_LIN( WIN16_LockResource16( handle ) ); +} /********************************************************************** * LockResource32 (KERNEL32.384) @@ -154,6 +296,20 @@ LPVOID WINAPI LockResource32( HGLOBAL32 handle ) } +/********************************************************************** + * FreeResource16 (KERNEL.63) + */ +BOOL16 WINAPI FreeResource16( HGLOBAL16 handle ) +{ + NE_MODULE *pModule = NE_GetPtr( FarGetOwner(handle) ); + if ( !pModule ) return handle; + + if ( pModule->module32 ) + return NE_FreePEResource( pModule, handle ); + + return NE_FreeResource( pModule, handle ); +} + /********************************************************************** * FreeResource32 (KERNEL32.145) */ @@ -163,6 +319,23 @@ BOOL32 WINAPI FreeResource32( HGLOBAL32 handle ) return TRUE; } +/********************************************************************** + * AccessResource16 (KERNEL.64) + */ +INT16 WINAPI AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc ) +{ + NE_MODULE *pModule = NE_GetPtr( hModule ); + if ( !pModule ) return 0; + + if ( pModule->module32 ) + { + HANDLE32 hRsrc32 = MapHRsrc16To32( pModule, hRsrc ); + HFILE32 hFile32 = AccessResource32( pModule->module32, hRsrc32 ); + return HFILE32_TO_HFILE16( hFile32 ); + } + + return NE_AccessResource( pModule, hRsrc ); +} /********************************************************************** * AccessResource32 (KERNEL32.64) @@ -174,6 +347,23 @@ INT32 WINAPI AccessResource32( HMODULE32 hModule, HRSRC32 hRsrc ) } +/********************************************************************** + * SizeofResource16 (KERNEL.65) + */ +DWORD WINAPI SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc ) +{ + NE_MODULE *pModule = NE_GetPtr( hModule ); + if ( !pModule ) return 0; + + if ( pModule->module32 ) + { + HANDLE32 hRsrc32 = MapHRsrc16To32( pModule, hRsrc ); + return SizeofResource32( hModule, hRsrc32 ); + } + + return NE_SizeofResource( pModule, hRsrc ); +} + /********************************************************************** * SizeofResource32 (KERNEL32.522) */ @@ -190,8 +380,7 @@ DWORD WINAPI SizeofResource32( HINSTANCE32 hModule, HRSRC32 hRsrc ) return PE_SizeofResource32(hModule,hRsrc); case MODULE32_ELF: - FIXME(module,"Not implemented for ELF modules\n"); - break; + return LIBRES_SizeofResource( hModule, hRsrc ); default: ERR(module,"unknown module type %d\n",wm->type);