From 424202bd9addff13f3045b7b4cf7241468da4972 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 30 Apr 2003 00:53:23 +0000 Subject: [PATCH] Moved most of the kernel resource APIs to dlls/kernel. --- dlls/kernel/Makefile.in | 2 + dlls/kernel/resource.c | 248 +++++++++ dlls/kernel/resource16.c | 1125 ++++++++++++++++++++++++++++++++++++++ dlls/ntdll/Makefile.in | 3 - if1632/builtin.c | 2 +- include/module.h | 13 +- loader/ne/convert.c | 455 --------------- loader/ne/module.c | 25 +- loader/ne/resource.c | 566 ------------------- loader/pe_resource.c | 151 ----- loader/resource.c | 500 ----------------- 11 files changed, 1401 insertions(+), 1689 deletions(-) create mode 100644 dlls/kernel/resource.c create mode 100644 dlls/kernel/resource16.c delete mode 100644 loader/ne/convert.c delete mode 100644 loader/ne/resource.c delete mode 100644 loader/resource.c diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in index dc6569d810b..0537e38a2c3 100644 --- a/dlls/kernel/Makefile.in +++ b/dlls/kernel/Makefile.in @@ -32,6 +32,8 @@ C_SRCS = \ kernel_main.c \ lcformat.c \ locale.c \ + resource.c \ + resource16.c \ stress.c \ string.c \ sync.c \ diff --git a/dlls/kernel/resource.c b/dlls/kernel/resource.c new file mode 100644 index 00000000000..300551f1a8e --- /dev/null +++ b/dlls/kernel/resource.c @@ -0,0 +1,248 @@ +/* + * Resources + * + * Copyright 1993 Robert J. Amstadt + * Copyright 1995, 2003 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include "wine/port.h" + +#include "windef.h" +#include "winternl.h" +#include "winbase.h" +#include "wownt32.h" +#include "wine/winbase16.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(resource); + +/* handle conversions */ +#define HRSRC_32(h16) ((HRSRC)(ULONG_PTR)(h16)) +#define HRSRC_16(h32) (LOWORD(h32)) +#define HGLOBAL_32(h16) ((HGLOBAL)(ULONG_PTR)(h16)) +#define HGLOBAL_16(h32) (LOWORD(h32)) +#define HMODULE_16(h32) (LOWORD(h32)) + + +/* retrieve the resource name to pass to the ntdll functions */ +static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str ) +{ + if (!HIWORD(name)) + { + str->Buffer = (LPWSTR)name; + return STATUS_SUCCESS; + } + if (name[0] == '#') + { + ULONG value; + if (RtlCharToInteger( name, 10, &value ) != STATUS_SUCCESS || HIWORD(value)) + return STATUS_INVALID_PARAMETER; + str->Buffer = (LPWSTR)value; + return STATUS_SUCCESS; + } + RtlCreateUnicodeStringFromAsciiz( str, name ); + RtlUpcaseUnicodeString( str, str, FALSE ); + return STATUS_SUCCESS; +} + +/* retrieve the resource name to pass to the ntdll functions */ +static NTSTATUS get_res_nameW( LPCWSTR name, UNICODE_STRING *str ) +{ + if (!HIWORD(name)) + { + str->Buffer = (LPWSTR)name; + return STATUS_SUCCESS; + } + if (name[0] == '#') + { + ULONG value; + RtlInitUnicodeString( str, name ); + if (RtlUnicodeStringToInteger( str, 10, &value ) != STATUS_SUCCESS || HIWORD(value)) + return STATUS_INVALID_PARAMETER; + str->Buffer = (LPWSTR)value; + return STATUS_SUCCESS; + } + RtlCreateUnicodeString( str, name ); + RtlUpcaseUnicodeString( str, str, FALSE ); + return STATUS_SUCCESS; +} + +/********************************************************************** + * FindResourceExA (KERNEL32.@) + */ +HRSRC WINAPI FindResourceExA( HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang ) +{ + NTSTATUS status; + UNICODE_STRING nameW, typeW; + LDR_RESOURCE_INFO info; + const IMAGE_RESOURCE_DATA_ENTRY *entry = NULL; + + TRACE( "%p %s %s %04x\n", hModule, debugstr_a(type), debugstr_a(name), lang ); + + if (!hModule) hModule = GetModuleHandleW(0); + else if (!HIWORD(hModule)) + { + return HRSRC_32( FindResource16( HMODULE_16(hModule), name, type ) ); + } + + nameW.Buffer = typeW.Buffer = NULL; + if ((status = get_res_nameA( name, &nameW )) != STATUS_SUCCESS) goto done; + if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS) goto done; + info.Type = (ULONG)typeW.Buffer; + info.Name = (ULONG)nameW.Buffer; + info.Language = lang; + status = LdrFindResource_U( hModule, &info, 3, &entry ); +done: + if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); + if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return (HRSRC)entry; +} + + +/********************************************************************** + * FindResourceA (KERNEL32.@) + */ +HRSRC WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) +{ + return FindResourceExA( hModule, type, name, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) ); +} + + +/********************************************************************** + * FindResourceExW (KERNEL32.@) + */ +HRSRC WINAPI FindResourceExW( HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang ) +{ + NTSTATUS status; + UNICODE_STRING nameW, typeW; + LDR_RESOURCE_INFO info; + const IMAGE_RESOURCE_DATA_ENTRY *entry = NULL; + + TRACE( "%p %s %s %04x\n", hModule, debugstr_w(type), debugstr_w(name), lang ); + + if (!hModule) hModule = GetModuleHandleW(0); + else if (!HIWORD(hModule)) + { + LPSTR nameA, typeA; + HRSRC16 ret; + + if (HIWORD(name)) + { + DWORD len = WideCharToMultiByte( CP_ACP, 0, name, -1, NULL, 0, NULL, NULL ); + nameA = HeapAlloc( GetProcessHeap(), 0, len ); + if (nameA) WideCharToMultiByte( CP_ACP, 0, name, -1, nameA, len, NULL, NULL ); + } + else nameA = (LPSTR)name; + + if (HIWORD(type)) + { + DWORD len = WideCharToMultiByte( CP_ACP, 0, type, -1, NULL, 0, NULL, NULL ); + typeA = HeapAlloc( GetProcessHeap(), 0, len ); + if (typeA) WideCharToMultiByte( CP_ACP, 0, type, -1, typeA, len, NULL, NULL ); + } + else typeA = (LPSTR)type; + + ret = FindResource16( HMODULE_16(hModule), nameA, typeA ); + if (HIWORD(nameA)) HeapFree( GetProcessHeap(), 0, nameA ); + if (HIWORD(typeA)) HeapFree( GetProcessHeap(), 0, typeA ); + return HRSRC_32(ret); + } + + nameW.Buffer = typeW.Buffer = NULL; + if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS) goto done; + if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS) goto done; + info.Type = (ULONG)typeW.Buffer; + info.Name = (ULONG)nameW.Buffer; + info.Language = lang; + status = LdrFindResource_U( hModule, &info, 3, &entry ); +done: + if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); + if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return (HRSRC)entry; +} + + +/********************************************************************** + * FindResourceW (KERNEL32.@) + */ +HRSRC WINAPI FindResourceW( HINSTANCE hModule, LPCWSTR name, LPCWSTR type ) +{ + return FindResourceExW( hModule, type, name, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) ); +} + + +/********************************************************************** + * LoadResource (KERNEL32.@) + */ +HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc ) +{ + NTSTATUS status; + void *ret = NULL; + + TRACE( "%p %p\n", hModule, hRsrc ); + + if (hModule && !HIWORD(hModule)) + /* FIXME: should convert return to 32-bit resource */ + return HGLOBAL_32( LoadResource16( HMODULE_16(hModule), HRSRC_16(hRsrc) ) ); + + if (!hRsrc) return 0; + if (!hModule) hModule = GetModuleHandleA( NULL ); + status = LdrAccessResource( hModule, (IMAGE_RESOURCE_DATA_ENTRY *)hRsrc, &ret, NULL ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return ret; +} + + +/********************************************************************** + * LockResource (KERNEL32.@) + */ +LPVOID WINAPI LockResource( HGLOBAL handle ) +{ + TRACE("(%p)\n", handle ); + + if (HIWORD( handle )) /* 32-bit memory handle */ + return (LPVOID)handle; + + /* 16-bit memory handle */ + return LockResource16( HGLOBAL_16(handle) ); +} + + +/********************************************************************** + * FreeResource (KERNEL32.@) + */ +BOOL WINAPI FreeResource( HGLOBAL handle ) +{ + if (HIWORD(handle)) return 0; /* 32-bit memory handle: nothing to do */ + return FreeResource16( HGLOBAL_16(handle) ); +} + + +/********************************************************************** + * SizeofResource (KERNEL32.@) + */ +DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc ) +{ + if (hModule && !HIWORD(hModule)) + return SizeofResource16( HMODULE_16(hModule), HRSRC_16(hRsrc) ); + + if (!hRsrc) return 0; + return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size; +} diff --git a/dlls/kernel/resource16.c b/dlls/kernel/resource16.c new file mode 100644 index 00000000000..31af22f95a6 --- /dev/null +++ b/dlls/kernel/resource16.c @@ -0,0 +1,1125 @@ +/* + * 16-bit resource functions + * + * Copyright 1993 Robert J. Amstadt + * Copyright 1997 Alex Korobka + * Copyright 1998 Ulrich Weigand + * Copyright 1995, 2003 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include + +#include "windef.h" +#include "wownt32.h" +#include "wine/winbase16.h" +#include "wine/winuser16.h" +#include "wine/unicode.h" +#include "module.h" +#include "task.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(resource); + +/* handle conversions */ +#define HRSRC_32(h16) ((HRSRC)(ULONG_PTR)(h16)) +#define HGLOBAL_32(h16) ((HGLOBAL)(ULONG_PTR)(h16)) + +static inline NE_MODULE *get_module( HMODULE16 mod ) +{ + if (!mod) mod = TASK_GetCurrent()->hModule; + return NE_GetPtr( mod ); +} + +#define HRSRC_MAP_BLOCKSIZE 16 + +typedef struct _HRSRC_ELEM +{ + HRSRC 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, HRSRC 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 = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HRSRC_MAP) ) ) ) + { + ERR("Cannot allocate HRSRC map\n" ); + return 0; + } + pModule->hRsrcMap = 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("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 HRSRC MapHRsrc16To32( NE_MODULE *pModule, HRSRC16 hRsrc16 ) +{ + HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; + if ( !map || !hRsrc16 || hRsrc16 > map->nUsed ) return 0; + + return map->elem[hRsrc16-1].hRsrc; +} + +/********************************************************************** + * MapHRsrc16ToType + */ +static WORD MapHRsrc16ToType( NE_MODULE *pModule, HRSRC16 hRsrc16 ) +{ + HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; + if ( !map || !hRsrc16 || hRsrc16 > map->nUsed ) return 0; + + return map->elem[hRsrc16-1].type; +} + + +/********************************************************************** + * get_res_name + * + * Convert a resource name from '#xxx' form to numerical id. + */ +static inline LPCSTR get_res_name( LPCSTR name ) +{ + if (HIWORD(name) && name[0] == '#') name = (LPCSTR)atoi( name + 1 ); + return name; +} + + +/********************************************************************** + * next_typeinfo + */ +static inline NE_TYPEINFO *next_typeinfo( NE_TYPEINFO *info ) +{ + return (NE_TYPEINFO *)((char*)(info + 1) + info->count * sizeof(NE_NAMEINFO)); +} + + +/********************************************************************** + * get_default_res_handler + */ +static inline FARPROC16 get_default_res_handler(void) +{ + static FARPROC16 handler; + + if (!handler) handler = GetProcAddress16( GetModuleHandle16("KERNEL"), "DefResourceHandler" ); + return handler; +} + + +/*********************************************************************** + * NE_FindNameTableId + * + * 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, LPCSTR typeId, LPCSTR resId ) +{ + NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2); + NE_NAMEINFO *pNameInfo; + HGLOBAL16 handle; + WORD *p; + DWORD ret = 0; + int count; + + for (; pTypeInfo->type_id != 0; + pTypeInfo = (NE_TYPEINFO *)((char*)(pTypeInfo+1) + + pTypeInfo->count * sizeof(NE_NAMEINFO))) + { + if (pTypeInfo->type_id != 0x800f) continue; + pNameInfo = (NE_NAMEINFO *)(pTypeInfo + 1); + for (count = pTypeInfo->count; count > 0; count--, pNameInfo++) + { + TRACE("NameTable entry: type=%04x id=%04x\n", + pTypeInfo->type_id, pNameInfo->id ); + handle = LoadResource16( pModule->self, + (HRSRC16)((int)pNameInfo - (int)pModule) ); + for(p = (WORD*)LockResource16(handle); p && *p; p = (WORD *)((char*)p+*p)) + { + TRACE(" type=%04x '%s' id=%04x '%s'\n", + p[1], (char *)(p+3), p[2], + (char *)(p+3)+strlen((char *)(p+3))+1 ); + /* Check for correct type */ + + if (p[1] & 0x8000) + { + if (!HIWORD(typeId)) continue; + if (strcasecmp( typeId, (char *)(p + 3) )) continue; + } + else if (HIWORD(typeId) || (((DWORD)typeId & ~0x8000)!= p[1])) + continue; + + /* Now check for the id */ + + if (p[2] & 0x8000) + { + if (!HIWORD(resId)) continue; + if (strcasecmp( resId, (char*)(p+3)+strlen((char*)(p+3))+1 )) continue; + + } + else if (HIWORD(resId) || (((DWORD)resId & ~0x8000) != p[2])) + continue; + + /* If we get here, we've found the entry */ + + TRACE(" Found!\n" ); + ret = MAKELONG( p[1], p[2] ); + break; + } + FreeResource16( handle ); + if (ret) return ret; + } + } + return 0; +} + + +/*********************************************************************** + * NE_FindTypeSection + * + * Find header struct for a particular resource type. + */ +static NE_TYPEINFO *NE_FindTypeSection( LPBYTE pResTab, NE_TYPEINFO *pTypeInfo, LPCSTR typeId ) +{ + /* start from pTypeInfo */ + + if (HIWORD(typeId) != 0) /* Named type */ + { + LPCSTR str = typeId; + BYTE len = strlen( str ); + while (pTypeInfo->type_id) + { + if (!(pTypeInfo->type_id & 0x8000)) + { + BYTE *p = pResTab + pTypeInfo->type_id; + if ((*p == len) && !strncasecmp( p+1, str, len )) + { + TRACE(" Found type '%s'\n", str ); + return pTypeInfo; + } + } + TRACE(" Skipping type %04x\n", pTypeInfo->type_id ); + pTypeInfo = next_typeinfo(pTypeInfo); + } + } + else /* Numeric type id */ + { + WORD id = LOWORD(typeId) | 0x8000; + while (pTypeInfo->type_id) + { + if (pTypeInfo->type_id == id) + { + TRACE(" Found type %04x\n", id ); + return pTypeInfo; + } + TRACE(" Skipping type %04x\n", pTypeInfo->type_id ); + pTypeInfo = next_typeinfo(pTypeInfo); + } + } + return NULL; +} + + +/*********************************************************************** + * NE_FindResourceFromType + * + * Find a resource once the type info structure has been found. + */ +static NE_NAMEINFO *NE_FindResourceFromType( LPBYTE pResTab, NE_TYPEINFO *pTypeInfo, LPCSTR resId ) +{ + BYTE *p; + int count; + NE_NAMEINFO *pNameInfo = (NE_NAMEINFO *)(pTypeInfo + 1); + + if (HIWORD(resId) != 0) /* Named resource */ + { + LPCSTR str = resId; + BYTE len = strlen( str ); + for (count = pTypeInfo->count; count > 0; count--, pNameInfo++) + { + if (pNameInfo->id & 0x8000) continue; + p = pResTab + pNameInfo->id; + if ((*p == len) && !strncasecmp( p+1, str, len )) + return pNameInfo; + } + } + else /* Numeric resource id */ + { + WORD id = LOWORD(resId) | 0x8000; + for (count = pTypeInfo->count; count > 0; count--, pNameInfo++) + if (pNameInfo->id == id) return pNameInfo; + } + return NULL; +} + + +/*********************************************************************** + * DefResourceHandler (KERNEL.456) + * + * This is the default LoadProc() function. + */ +HGLOBAL16 WINAPI NE_DefResourceHandler( HGLOBAL16 hMemObj, HMODULE16 hModule, + HRSRC16 hRsrc ) +{ + HANDLE fd; + NE_MODULE* pModule = NE_GetPtr( hModule ); + if (pModule && (pModule->flags & NE_FFLAGS_BUILTIN)) + { + HGLOBAL16 handle; + WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); + NE_NAMEINFO* pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); + + if ( hMemObj ) + handle = GlobalReAlloc16( hMemObj, pNameInfo->length << sizeShift, 0 ); + else + handle = AllocResource16( hModule, hRsrc, 0 ); + + if ( handle ) + { + /* NOTE: hRsrcMap points to start of built-in resource data */ + memcpy( GlobalLock16( handle ), + (char *)pModule->hRsrcMap + (pNameInfo->offset << sizeShift), + pNameInfo->length << sizeShift ); + } + return handle; + } + if (pModule && (fd = NE_OpenFile( pModule )) != INVALID_HANDLE_VALUE) + { + HGLOBAL16 handle; + WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); + NE_NAMEINFO* pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); + + TRACE("loading, pos=%d, len=%d\n", + (int)pNameInfo->offset << sizeShift, + (int)pNameInfo->length << sizeShift ); + if( hMemObj ) + handle = GlobalReAlloc16( hMemObj, pNameInfo->length << sizeShift, 0 ); + else + handle = AllocResource16( hModule, hRsrc, 0 ); + + if( handle ) + { + DWORD res; + SetFilePointer( fd, (int)pNameInfo->offset << sizeShift, NULL, SEEK_SET ); + ReadFile( fd, GlobalLock16( handle ), (int)pNameInfo->length << sizeShift, + &res, NULL ); + } + CloseHandle(fd); + return handle; + } + return (HGLOBAL16)0; +} + + +/********************************************************************** + * SetResourceHandler (KERNEL.67) + */ +FARPROC16 WINAPI SetResourceHandler16( HMODULE16 hModule, LPCSTR typeId, FARPROC16 resourceHandler ) +{ + LPBYTE pResTab; + NE_TYPEINFO *pTypeInfo; + FARPROC16 prevHandler = NULL; + NE_MODULE *pModule = NE_GetPtr( hModule ); + + if (!pModule || !pModule->res_table) return NULL; + + pResTab = (LPBYTE)pModule + pModule->res_table; + pTypeInfo = (NE_TYPEINFO *)(pResTab + 2); + + TRACE("module=%04x type=%s\n", hModule, debugstr_a(typeId) ); + + for (;;) + { + if (!(pTypeInfo = NE_FindTypeSection( pResTab, pTypeInfo, typeId ))) + break; + memcpy_unaligned( &prevHandler, &pTypeInfo->resloader, sizeof(FARPROC16) ); + memcpy_unaligned( &pTypeInfo->resloader, &resourceHandler, sizeof(FARPROC16) ); + pTypeInfo = next_typeinfo(pTypeInfo); + } + if (!prevHandler) prevHandler = get_default_res_handler(); + return prevHandler; +} + + +/********************************************************************** + * ConvertDialog32To16 (KERNEL.615) + */ +VOID WINAPI ConvertDialog32To16( LPVOID dialog32, DWORD size, LPVOID dialog16 ) +{ + LPVOID p = dialog32; + WORD nbItems, data, dialogEx; + DWORD style; + + style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; + dialogEx = (style == 0xffff0001); /* DIALOGEX resource */ + if (dialogEx) + { + *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */ + *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */ + style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */ + } + else + ((DWORD *)p)++; /* exStyle ignored in 16-bit standard dialog */ + + nbItems = *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++; + *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */ + *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */ + *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */ + *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */ + + /* Transfer menu name */ + switch (*((WORD *)p)) + { + case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break; + case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff; + *((WORD *)dialog16)++ = *((WORD *)p)++; break; + default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); + ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; + break; + } + + /* Transfer class name */ + switch (*((WORD *)p)) + { + case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break; + case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff; + *((WORD *)dialog16)++ = *((WORD *)p)++; break; + default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); + ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; + break; + } + + /* Transfer window caption */ + WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); + ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; + + /* Transfer font info */ + if (style & DS_SETFONT) + { + *((WORD *)dialog16)++ = *((WORD *)p)++; /* pointSize */ + if (dialogEx) + { + *((WORD *)dialog16)++ = *((WORD *)p)++; /* weight */ + *((WORD *)dialog16)++ = *((WORD *)p)++; /* italic */ + } + WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); /* faceName */ + ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; + } + + /* Transfer dialog items */ + while (nbItems) + { + /* align on DWORD boundary (32-bit only) */ + p = (LPVOID)((((int)p) + 3) & ~3); + + if (dialogEx) + { + *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */ + *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */ + *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */ + } + else + { + style = *((DWORD *)p)++; /* save style */ + ((DWORD *)p)++; /* ignore exStyle */ + } + + *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */ + *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */ + *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */ + *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */ + + if (dialogEx) + *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* ID */ + else + { + *((WORD *)dialog16)++ = *((WORD *)p)++; /* ID */ + *((DWORD *)dialog16)++ = style; /* style from above */ + } + + /* Transfer class name */ + switch (*((WORD *)p)) + { + case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break; + case 0xffff: ((WORD *)p)++; + *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++; break; + default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); + ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; + break; + } + + /* Transfer window name */ + switch (*((WORD *)p)) + { + case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break; + case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff; + *((WORD *)dialog16)++ = *((WORD *)p)++; break; + default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); + ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; + break; + } + + /* Transfer data */ + data = *((WORD *)p)++; + if (dialogEx) + *((WORD *)dialog16)++ = data; + else + *((BYTE *)dialog16)++ = (BYTE)data; + + if (data) + { + memcpy( dialog16, p, data ); + (LPSTR)dialog16 += data; + (LPSTR)p += data; + } + + /* Next item */ + nbItems--; + } +} + + +/********************************************************************** + * GetDialog32Size (KERNEL.618) + */ +WORD WINAPI GetDialog32Size16( LPVOID dialog32 ) +{ + LPVOID p = dialog32; + WORD nbItems, data, dialogEx; + DWORD style; + + style = *((DWORD *)p)++; + dialogEx = (style == 0xffff0001); /* DIALOGEX resource */ + if (dialogEx) + { + ((DWORD *)p)++; /* helpID */ + ((DWORD *)p)++; /* exStyle */ + style = *((DWORD *)p)++; /* style */ + } + else + ((DWORD *)p)++; /* exStyle */ + + nbItems = *((WORD *)p)++; + ((WORD *)p)++; /* x */ + ((WORD *)p)++; /* y */ + ((WORD *)p)++; /* cx */ + ((WORD *)p)++; /* cy */ + + /* Skip menu name */ + switch (*((WORD *)p)) + { + case 0x0000: ((WORD *)p)++; break; + case 0xffff: ((WORD *)p) += 2; break; + default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break; + } + + /* Skip class name */ + switch (*((WORD *)p)) + { + case 0x0000: ((WORD *)p)++; break; + case 0xffff: ((WORD *)p) += 2; break; + default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break; + } + + /* Skip window caption */ + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; + + /* Skip font info */ + if (style & DS_SETFONT) + { + ((WORD *)p)++; /* pointSize */ + if (dialogEx) + { + ((WORD *)p)++; /* weight */ + ((WORD *)p)++; /* italic */ + } + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; /* faceName */ + } + + /* Skip dialog items */ + while (nbItems) + { + /* align on DWORD boundary */ + p = (LPVOID)((((int)p) + 3) & ~3); + + if (dialogEx) + { + ((DWORD *)p)++; /* helpID */ + ((DWORD *)p)++; /* exStyle */ + ((DWORD *)p)++; /* style */ + } + else + { + ((DWORD *)p)++; /* style */ + ((DWORD *)p)++; /* exStyle */ + } + + ((WORD *)p)++; /* x */ + ((WORD *)p)++; /* y */ + ((WORD *)p)++; /* cx */ + ((WORD *)p)++; /* cy */ + + if (dialogEx) + ((DWORD *)p)++; /* ID */ + else + ((WORD *)p)++; /* ID */ + + /* Skip class name */ + switch (*((WORD *)p)) + { + case 0x0000: ((WORD *)p)++; break; + case 0xffff: ((WORD *)p) += 2; break; + default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break; + } + + /* Skip window name */ + switch (*((WORD *)p)) + { + case 0x0000: ((WORD *)p)++; break; + case 0xffff: ((WORD *)p) += 2; break; + default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break; + } + + /* Skip data */ + data = *((WORD *)p)++; + (LPSTR)p += data; + + /* Next item */ + nbItems--; + } + + return (WORD)((LPSTR)p - (LPSTR)dialog32); +} + + +/********************************************************************** + * ConvertMenu32To16 (KERNEL.616) + */ +VOID WINAPI ConvertMenu32To16( LPVOID menu32, DWORD size, LPVOID menu16 ) +{ + LPVOID p = menu32; + WORD version, headersize, flags, level = 1; + + version = *((WORD *)menu16)++ = *((WORD *)p)++; + headersize = *((WORD *)menu16)++ = *((WORD *)p)++; + if ( headersize ) + { + memcpy( menu16, p, headersize ); + ((LPSTR)menu16) += headersize; + ((LPSTR)p) += headersize; + } + + while ( level ) + if ( version == 0 ) /* standard */ + { + flags = *((WORD *)menu16)++ = *((WORD *)p)++; + if ( !(flags & MF_POPUP) ) + *((WORD *)menu16)++ = *((WORD *)p)++; /* ID */ + else + level++; + + WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)menu16, 0x7fffffff, NULL,NULL ); + ((LPSTR)menu16) += strlen( (LPSTR)menu16 ) + 1; + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; + + if ( flags & MF_END ) + level--; + } + else /* extended */ + { + *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fType */ + *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fState */ + *((WORD *)menu16)++ = (WORD)*((DWORD *)p)++; /* ID */ + flags = *((BYTE *)menu16)++ = (BYTE)*((WORD *)p)++; + + WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)menu16, 0x7fffffff, NULL,NULL ); + ((LPSTR)menu16) += strlen( (LPSTR)menu16 ) + 1; + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; + + /* align on DWORD boundary (32-bit only) */ + p = (LPVOID)((((int)p) + 3) & ~3); + + /* If popup, transfer helpid */ + if ( flags & 1) + { + *((DWORD *)menu16)++ = *((DWORD *)p)++; + level++; + } + + if ( flags & MF_END ) + level--; + } +} + + +/********************************************************************** + * GetMenu32Size (KERNEL.617) + */ +WORD WINAPI GetMenu32Size16( LPVOID menu32 ) +{ + LPVOID p = menu32; + WORD version, headersize, flags, level = 1; + + version = *((WORD *)p)++; + headersize = *((WORD *)p)++; + ((LPSTR)p) += headersize; + + while ( level ) + if ( version == 0 ) /* standard */ + { + flags = *((WORD *)p)++; + if ( !(flags & MF_POPUP) ) + ((WORD *)p)++; /* ID */ + else + level++; + + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; + + if ( flags & MF_END ) + level--; + } + else /* extended */ + { + ((DWORD *)p)++; /* fType */ + ((DWORD *)p)++; /* fState */ + ((DWORD *)p)++; /* ID */ + flags = *((WORD *)p)++; + + ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; + + /* align on DWORD boundary (32-bit only) */ + p = (LPVOID)((((int)p) + 3) & ~3); + + /* If popup, skip helpid */ + if ( flags & 1) + { + ((DWORD *)p)++; + level++; + } + + if ( flags & MF_END ) + level--; + } + + return (WORD)((LPSTR)p - (LPSTR)menu32); +} + + +/********************************************************************** + * ConvertAccelerator32To16 + */ +static void ConvertAccelerator32To16( LPVOID acc32, DWORD size, LPVOID acc16 ) +{ + int type; + + do + { + /* Copy type */ + type = *((BYTE *)acc16)++ = *((BYTE *)acc32)++; + /* Skip padding */ + ((BYTE *)acc32)++; + /* Copy event and IDval */ + *((WORD *)acc16)++ = *((WORD *)acc32)++; + *((WORD *)acc16)++ = *((WORD *)acc32)++; + /* Skip padding */ + ((WORD *)acc32)++; + + } while ( !( type & 0x80 ) ); +} + + +/********************************************************************** + * NE_LoadPEResource + */ +static HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size ) +{ + HGLOBAL16 handle; + + TRACE("module=%04x type=%04x\n", pModule->self, type ); + + handle = GlobalAlloc16( 0, size ); + + switch (type) + { + case RT_MENU16: + ConvertMenu32To16( bits, size, GlobalLock16( handle ) ); + break; + case RT_DIALOG16: + ConvertDialog32To16( bits, size, GlobalLock16( handle ) ); + break; + case RT_ACCELERATOR16: + ConvertAccelerator32To16( bits, size, GlobalLock16( handle ) ); + break; + case RT_STRING16: + FIXME("not yet implemented!\n" ); + /* fall through */ + default: + memcpy( GlobalLock16( handle ), bits, size ); + break; + } + return handle; +} + + +/********************************************************************** + * AllocResource (KERNEL.66) + */ +HGLOBAL16 WINAPI AllocResource16( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size) +{ + NE_NAMEINFO *pNameInfo=NULL; + WORD sizeShift; + HGLOBAL16 ret; + + NE_MODULE *pModule = NE_GetPtr( hModule ); + if (!pModule || !pModule->res_table || !hRsrc) return 0; + + TRACE("module=%04x res=%04x size=%ld\n", hModule, hRsrc, size ); + + sizeShift = *(WORD *)((char *)pModule + pModule->res_table); + pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); + if (size < (DWORD)pNameInfo->length << sizeShift) + size = (DWORD)pNameInfo->length << sizeShift; + ret = GlobalAlloc16( GMEM_FIXED, size ); + if (ret) FarSetOwner16( ret, hModule ); + return ret; +} + + +/********************************************************************** + * DirectResAlloc (KERNEL.168) + * + * Check Schulman, p. 232 for details + */ +HGLOBAL16 WINAPI DirectResAlloc16( HINSTANCE16 hInstance, WORD wType, + UINT16 wSize ) +{ + HGLOBAL16 ret; + TRACE("(%04x,%04x,%04x)\n", hInstance, wType, wSize ); + if (!(hInstance = GetExePtr( hInstance ))) return 0; + if(wType != 0x10) /* 0x10 is the only observed value, passed from + CreateCursorIndirect. */ + TRACE("(wType=%x)\n", wType); + ret = GlobalAlloc16( GMEM_MOVEABLE, wSize ); + if (ret) FarSetOwner16( ret, hInstance ); + return ret; +} + + +/********************************************************************** + * AccessResource (KERNEL.64) + */ +INT16 WINAPI AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc ) +{ + HFILE16 fd; + NE_MODULE *pModule = NE_GetPtr( hModule ); + + if (!pModule || !pModule->res_table || !hRsrc) return -1; + + TRACE("module=%04x res=%04x\n", pModule->self, hRsrc ); + + if ((fd = _lopen16( NE_MODULE_NAME(pModule), OF_READ )) != HFILE_ERROR16) + { + WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); + NE_NAMEINFO *pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); + _llseek16( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET ); + } + return fd; +} + + +/********************************************************************** + * FindResource (KERNEL.60) + */ +HRSRC16 WINAPI FindResource16( HMODULE16 hModule, LPCSTR name, LPCSTR type ) +{ + NE_TYPEINFO *pTypeInfo; + NE_NAMEINFO *pNameInfo; + LPBYTE pResTab; + NE_MODULE *pModule = get_module( hModule ); + + if (!pModule) return 0; + + if (pModule->module32) + { + /* 32-bit PE module */ + HRSRC hRsrc32 = FindResourceA( pModule->module32, name, type ); + return MapHRsrc32To16( pModule, hRsrc32, HIWORD(type) ? 0 : LOWORD(type) ); + } + + TRACE("module=%04x name=%s type=%s\n", pModule->self, debugstr_a(name), debugstr_a(type) ); + + if (!pModule->res_table) return 0; + + type = get_res_name( type ); + name = get_res_name( name ); + + if (HIWORD(type) || HIWORD(name)) + { + DWORD id = NE_FindNameTableId( pModule, type, name ); + if (id) /* found */ + { + type = (LPCSTR)(ULONG_PTR)LOWORD(id); + name = (LPCSTR)(ULONG_PTR)HIWORD(id); + } + } + pResTab = (LPBYTE)pModule + pModule->res_table; + pTypeInfo = (NE_TYPEINFO *)( pResTab + 2 ); + + for (;;) + { + if (!(pTypeInfo = NE_FindTypeSection( pResTab, pTypeInfo, type ))) break; + if ((pNameInfo = NE_FindResourceFromType( pResTab, pTypeInfo, name ))) + { + TRACE(" Found id %08lx\n", (DWORD)name ); + return (HRSRC16)( (char *)pNameInfo - (char *)pModule ); + } + pTypeInfo = next_typeinfo(pTypeInfo); + } + return 0; +} + + +/********************************************************************** + * LoadResource (KERNEL.61) + */ +HGLOBAL16 WINAPI LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc ) +{ + NE_TYPEINFO *pTypeInfo; + NE_NAMEINFO *pNameInfo = NULL; + NE_MODULE *pModule = get_module( hModule ); + int d; + + if (!hRsrc || !pModule) return 0; + + if (pModule->module32) + { + /* load 32-bit resource and convert it */ + HRSRC hRsrc32 = MapHRsrc16To32( pModule, hRsrc ); + WORD type = MapHRsrc16ToType( pModule, hRsrc ); + HGLOBAL hMem = LoadResource( pModule->module32, hRsrc32 ); + DWORD size = SizeofResource( pModule->module32, hRsrc32 ); + if (!hMem) return 0; + return NE_LoadPEResource( pModule, type, LockResource( hMem ), size ); + } + + /* first, verify hRsrc (just an offset from pModule to the needed pNameInfo) */ + + d = pModule->res_table + 2; + pTypeInfo = (NE_TYPEINFO *)((char *)pModule + d); + while( hRsrc > d ) + { + if (pTypeInfo->type_id == 0) break; /* terminal entry */ + d += sizeof(NE_TYPEINFO) + pTypeInfo->count * sizeof(NE_NAMEINFO); + if (hRsrc < d) + { + if( ((d - hRsrc)%sizeof(NE_NAMEINFO)) == 0 ) + { + pNameInfo = (NE_NAMEINFO *)((char *)pModule + hRsrc); + break; + } + else break; /* NE_NAMEINFO boundary mismatch */ + } + pTypeInfo = (NE_TYPEINFO *)((char *)pModule + d); + } + + if (pNameInfo) + { + if (pNameInfo->handle && !(GlobalFlags16(pNameInfo->handle) & GMEM_DISCARDED)) + { + pNameInfo->usage++; + TRACE(" Already loaded, new count=%d\n", pNameInfo->usage ); + } + else + { + FARPROC16 resloader; + memcpy_unaligned( &resloader, &pTypeInfo->resloader, sizeof(FARPROC16) ); + if (resloader && resloader != get_default_res_handler()) + { + WORD args[3]; + DWORD ret; + + args[2] = pNameInfo->handle; + args[1] = pModule->self; + args[0] = hRsrc; + WOWCallback16Ex( (DWORD)resloader, WCB16_PASCAL, sizeof(args), args, &ret ); + pNameInfo->handle = LOWORD(ret); + } + else + pNameInfo->handle = NE_DefResourceHandler( pNameInfo->handle, pModule->self, hRsrc ); + + if (pNameInfo->handle) + { + pNameInfo->usage++; + pNameInfo->flags |= NE_SEGFLAGS_LOADED; + } + } + return pNameInfo->handle; + } + return 0; +} + + +/********************************************************************** + * LockResource (KERNEL.62) + */ +SEGPTR WINAPI WIN16_LockResource16( HGLOBAL16 handle ) +{ + TRACE("(%04x)\n", handle ); + /* May need to reload the resource if discarded */ + return K32WOWGlobalLock16( handle ); +} + + +/********************************************************************** + * LockResource16 (KERNEL32.@) + */ +LPVOID WINAPI LockResource16( HGLOBAL16 handle ) +{ + return MapSL( WIN16_LockResource16(handle) ); +} + + +/********************************************************************** + * SizeofResource (KERNEL.65) + */ +DWORD WINAPI SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc ) +{ + NE_MODULE *pModule = NE_GetPtr( hModule ); + + TRACE("(%x, %x)\n", hModule, hRsrc ); + + if (!hRsrc) return 0; + if (!(pModule = get_module( hModule ))) return 0; + if (pModule->res_table) + { + WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); + NE_NAMEINFO *pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); + return (DWORD)pNameInfo->length << sizeShift; + } + if (pModule->module32) + { + /* 32-bit PE module */ + return SizeofResource( pModule->module32, MapHRsrc16To32( pModule, hRsrc ) ); + } + return 0; +} + + +typedef WORD (WINAPI *pDestroyIcon32Proc)( HGLOBAL16 handle, UINT16 flags ); + +/********************************************************************** + * FreeResource (KERNEL.63) + */ +BOOL16 WINAPI FreeResource16( HGLOBAL16 handle ) +{ + pDestroyIcon32Proc proc; + HMODULE user; + NE_MODULE *pModule = NE_GetPtr( FarGetOwner16( handle ) ); + + TRACE("(%04x)\n", handle ); + + /* Try NE resource first */ + + if (pModule && pModule->res_table) + { + NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2); + while (pTypeInfo->type_id) + { + WORD count; + NE_NAMEINFO *pNameInfo = (NE_NAMEINFO *)(pTypeInfo + 1); + for (count = pTypeInfo->count; count > 0; count--) + { + if (pNameInfo->handle == handle) + { + if (pNameInfo->usage > 0) pNameInfo->usage--; + if (pNameInfo->usage == 0) + { + GlobalFree16( pNameInfo->handle ); + pNameInfo->handle = 0; + pNameInfo->flags &= ~NE_SEGFLAGS_LOADED; + } + return 0; + } + pNameInfo++; + } + pTypeInfo = (NE_TYPEINFO *)pNameInfo; + } + } + + /* If this failed, call USER.DestroyIcon32; this will check + whether it is a shared cursor/icon; if not it will call + GlobalFree16() */ + user = GetModuleHandleA( "user32.dll" ); + if (user && (proc = (pDestroyIcon32Proc)GetProcAddress( user, "DestroyIcon32" ))) + return proc( handle, 1 /*CID_RESOURCE*/ ); + else + return GlobalFree16( handle ); +} diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in index 6b3fe1a8625..a6a97fa0c73 100644 --- a/dlls/ntdll/Makefile.in +++ b/dlls/ntdll/Makefile.in @@ -22,11 +22,8 @@ C_SRCS = \ $(TOPOBJDIR)/loader/module.c \ $(TOPOBJDIR)/loader/pe_image.c \ $(TOPOBJDIR)/loader/pe_resource.c \ - $(TOPOBJDIR)/loader/resource.c \ $(TOPOBJDIR)/loader/task.c \ - $(TOPOBJDIR)/loader/ne/convert.c \ $(TOPOBJDIR)/loader/ne/module.c \ - $(TOPOBJDIR)/loader/ne/resource.c \ $(TOPOBJDIR)/loader/ne/segment.c \ $(TOPOBJDIR)/memory/atom.c \ $(TOPOBJDIR)/memory/codepage.c \ diff --git a/if1632/builtin.c b/if1632/builtin.c index cd50297d2a9..a746791f990 100644 --- a/if1632/builtin.c +++ b/if1632/builtin.c @@ -117,7 +117,7 @@ static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr ) LocalInit16( GlobalHandleToSel16(pSegTable->hSeg), pSegTable->minsize, minsize ); - if (descr->rsrc) NE_InitResourceHandler(hModule); + if (descr->rsrc) NE_InitResourceHandler(pModule); NE_RegisterModule( pModule ); diff --git a/include/module.h b/include/module.h index 1b5df210d10..86438fc20ca 100644 --- a/include/module.h +++ b/include/module.h @@ -195,6 +195,7 @@ extern void MODULE_WalkModref( DWORD id ); extern NE_MODULE *NE_GetPtr( HMODULE16 hModule ); extern void NE_DumpModule( HMODULE16 hModule ); extern void NE_WalkModules(void); +extern void NE_InitResourceHandler( NE_MODULE *pModule ); extern void NE_RegisterModule( NE_MODULE *pModule ); extern WORD NE_GetOrdinal( HMODULE16 hModule, const char *name ); extern FARPROC16 WINAPI NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal ); @@ -205,13 +206,6 @@ extern DWORD NE_StartTask(void); /* loader/ne/resource.c */ extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16); -extern BOOL NE_InitResourceHandler( HMODULE16 hModule ); -extern HRSRC NE_FindResource( NE_MODULE *pModule, LPCSTR name, LPCSTR type ); -extern DWORD NE_SizeofResource( NE_MODULE *pModule, HRSRC hRsrc ); -extern HGLOBAL16 NE_LoadResource( NE_MODULE *pModule, HRSRC16 hRsrc ); -extern BOOL16 NE_FreeResource( NE_MODULE *pModule, HGLOBAL16 handle ); -extern NE_TYPEINFO *NE_FindTypeSection( LPBYTE pResTab, NE_TYPEINFO *pTypeInfo, LPCSTR typeId ); -extern NE_NAMEINFO *NE_FindResourceFromType( LPBYTE pResTab, NE_TYPEINFO *pTypeInfo, LPCSTR resId ); /* loader/ne/segment.c */ extern BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ); @@ -222,14 +216,9 @@ extern HINSTANCE16 NE_GetInstance( NE_MODULE *pModule ); extern void NE_InitializeDLLs( HMODULE16 hModule ); extern void NE_DllProcessAttach( HMODULE16 hModule ); -/* loader/ne/convert.c */ -HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size ); - /* loader/pe_resource.c */ extern HRSRC PE_FindResourceW(HMODULE,LPCWSTR,LPCWSTR); extern HRSRC PE_FindResourceExW(HMODULE,LPCWSTR,LPCWSTR,WORD); -extern DWORD PE_SizeofResource(HRSRC); -extern HGLOBAL PE_LoadResource(HMODULE,HRSRC); /* loader/pe_image.c */ extern NTSTATUS PE_LoadLibraryExA(LPCSTR, DWORD, WINE_MODREF**); diff --git a/loader/ne/convert.c b/loader/ne/convert.c deleted file mode 100644 index fbe9fe57dc6..00000000000 --- a/loader/ne/convert.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * PE->NE resource conversion functions - * - * Copyright 1998 Ulrich Weigand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include "windef.h" -#include "wingdi.h" -#include "wine/winuser16.h" -#include "wine/unicode.h" -#include "module.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(resource); - -/********************************************************************** - * ConvertDialog32To16 (KERNEL.615) - */ -VOID WINAPI ConvertDialog32To16( LPVOID dialog32, DWORD size, LPVOID dialog16 ) -{ - LPVOID p = dialog32; - WORD nbItems, data, dialogEx; - DWORD style; - - style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; - dialogEx = (style == 0xffff0001); /* DIALOGEX resource */ - if (dialogEx) - { - *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */ - *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */ - style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */ - } - else - ((DWORD *)p)++; /* exStyle ignored in 16-bit standard dialog */ - - nbItems = *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++; - *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */ - *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */ - *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */ - *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */ - - /* Transfer menu name */ - switch (*((WORD *)p)) - { - case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break; - case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff; - *((WORD *)dialog16)++ = *((WORD *)p)++; break; - default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); - ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; - break; - } - - /* Transfer class name */ - switch (*((WORD *)p)) - { - case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break; - case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff; - *((WORD *)dialog16)++ = *((WORD *)p)++; break; - default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); - ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; - break; - } - - /* Transfer window caption */ - WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); - ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; - - /* Transfer font info */ - if (style & DS_SETFONT) - { - *((WORD *)dialog16)++ = *((WORD *)p)++; /* pointSize */ - if (dialogEx) - { - *((WORD *)dialog16)++ = *((WORD *)p)++; /* weight */ - *((WORD *)dialog16)++ = *((WORD *)p)++; /* italic */ - } - WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); /* faceName */ - ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; - } - - /* Transfer dialog items */ - while (nbItems) - { - /* align on DWORD boundary (32-bit only) */ - p = (LPVOID)((((int)p) + 3) & ~3); - - if (dialogEx) - { - *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */ - *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */ - *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */ - } - else - { - style = *((DWORD *)p)++; /* save style */ - ((DWORD *)p)++; /* ignore exStyle */ - } - - *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */ - *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */ - *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */ - *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */ - - if (dialogEx) - *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* ID */ - else - { - *((WORD *)dialog16)++ = *((WORD *)p)++; /* ID */ - *((DWORD *)dialog16)++ = style; /* style from above */ - } - - /* Transfer class name */ - switch (*((WORD *)p)) - { - case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break; - case 0xffff: ((WORD *)p)++; - *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++; break; - default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); - ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; - break; - } - - /* Transfer window name */ - switch (*((WORD *)p)) - { - case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break; - case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff; - *((WORD *)dialog16)++ = *((WORD *)p)++; break; - default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); - ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1; - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; - break; - } - - /* Transfer data */ - data = *((WORD *)p)++; - if (dialogEx) - *((WORD *)dialog16)++ = data; - else - *((BYTE *)dialog16)++ = (BYTE)data; - - if (data) - { - memcpy( dialog16, p, data ); - (LPSTR)dialog16 += data; - (LPSTR)p += data; - } - - /* Next item */ - nbItems--; - } -} - -/********************************************************************** - * GetDialog32Size (KERNEL.618) - */ -WORD WINAPI GetDialog32Size16( LPVOID dialog32 ) -{ - LPVOID p = dialog32; - WORD nbItems, data, dialogEx; - DWORD style; - - style = *((DWORD *)p)++; - dialogEx = (style == 0xffff0001); /* DIALOGEX resource */ - if (dialogEx) - { - ((DWORD *)p)++; /* helpID */ - ((DWORD *)p)++; /* exStyle */ - style = *((DWORD *)p)++; /* style */ - } - else - ((DWORD *)p)++; /* exStyle */ - - nbItems = *((WORD *)p)++; - ((WORD *)p)++; /* x */ - ((WORD *)p)++; /* y */ - ((WORD *)p)++; /* cx */ - ((WORD *)p)++; /* cy */ - - /* Skip menu name */ - switch (*((WORD *)p)) - { - case 0x0000: ((WORD *)p)++; break; - case 0xffff: ((WORD *)p) += 2; break; - default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break; - } - - /* Skip class name */ - switch (*((WORD *)p)) - { - case 0x0000: ((WORD *)p)++; break; - case 0xffff: ((WORD *)p) += 2; break; - default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break; - } - - /* Skip window caption */ - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; - - /* Skip font info */ - if (style & DS_SETFONT) - { - ((WORD *)p)++; /* pointSize */ - if (dialogEx) - { - ((WORD *)p)++; /* weight */ - ((WORD *)p)++; /* italic */ - } - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; /* faceName */ - } - - /* Skip dialog items */ - while (nbItems) - { - /* align on DWORD boundary */ - p = (LPVOID)((((int)p) + 3) & ~3); - - if (dialogEx) - { - ((DWORD *)p)++; /* helpID */ - ((DWORD *)p)++; /* exStyle */ - ((DWORD *)p)++; /* style */ - } - else - { - ((DWORD *)p)++; /* style */ - ((DWORD *)p)++; /* exStyle */ - } - - ((WORD *)p)++; /* x */ - ((WORD *)p)++; /* y */ - ((WORD *)p)++; /* cx */ - ((WORD *)p)++; /* cy */ - - if (dialogEx) - ((DWORD *)p)++; /* ID */ - else - ((WORD *)p)++; /* ID */ - - /* Skip class name */ - switch (*((WORD *)p)) - { - case 0x0000: ((WORD *)p)++; break; - case 0xffff: ((WORD *)p) += 2; break; - default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break; - } - - /* Skip window name */ - switch (*((WORD *)p)) - { - case 0x0000: ((WORD *)p)++; break; - case 0xffff: ((WORD *)p) += 2; break; - default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break; - } - - /* Skip data */ - data = *((WORD *)p)++; - (LPSTR)p += data; - - /* Next item */ - nbItems--; - } - - return (WORD)((LPSTR)p - (LPSTR)dialog32); -} - -/********************************************************************** - * ConvertMenu32To16 (KERNEL.616) - */ -VOID WINAPI ConvertMenu32To16( LPVOID menu32, DWORD size, LPVOID menu16 ) -{ - LPVOID p = menu32; - WORD version, headersize, flags, level = 1; - - version = *((WORD *)menu16)++ = *((WORD *)p)++; - headersize = *((WORD *)menu16)++ = *((WORD *)p)++; - if ( headersize ) - { - memcpy( menu16, p, headersize ); - ((LPSTR)menu16) += headersize; - ((LPSTR)p) += headersize; - } - - while ( level ) - if ( version == 0 ) /* standard */ - { - flags = *((WORD *)menu16)++ = *((WORD *)p)++; - if ( !(flags & MF_POPUP) ) - *((WORD *)menu16)++ = *((WORD *)p)++; /* ID */ - else - level++; - - WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)menu16, 0x7fffffff, NULL,NULL ); - ((LPSTR)menu16) += strlen( (LPSTR)menu16 ) + 1; - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; - - if ( flags & MF_END ) - level--; - } - else /* extended */ - { - *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fType */ - *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fState */ - *((WORD *)menu16)++ = (WORD)*((DWORD *)p)++; /* ID */ - flags = *((BYTE *)menu16)++ = (BYTE)*((WORD *)p)++; - - WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)menu16, 0x7fffffff, NULL,NULL ); - ((LPSTR)menu16) += strlen( (LPSTR)menu16 ) + 1; - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; - - /* align on DWORD boundary (32-bit only) */ - p = (LPVOID)((((int)p) + 3) & ~3); - - /* If popup, transfer helpid */ - if ( flags & 1) - { - *((DWORD *)menu16)++ = *((DWORD *)p)++; - level++; - } - - if ( flags & MF_END ) - level--; - } -} - -/********************************************************************** - * GetMenu32Size (KERNEL.617) - */ -WORD WINAPI GetMenu32Size16( LPVOID menu32 ) -{ - LPVOID p = menu32; - WORD version, headersize, flags, level = 1; - - version = *((WORD *)p)++; - headersize = *((WORD *)p)++; - ((LPSTR)p) += headersize; - - while ( level ) - if ( version == 0 ) /* standard */ - { - flags = *((WORD *)p)++; - if ( !(flags & MF_POPUP) ) - ((WORD *)p)++; /* ID */ - else - level++; - - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; - - if ( flags & MF_END ) - level--; - } - else /* extended */ - { - ((DWORD *)p)++; /* fType */ - ((DWORD *)p)++; /* fState */ - ((DWORD *)p)++; /* ID */ - flags = *((WORD *)p)++; - - ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; - - /* align on DWORD boundary (32-bit only) */ - p = (LPVOID)((((int)p) + 3) & ~3); - - /* If popup, skip helpid */ - if ( flags & 1) - { - ((DWORD *)p)++; - level++; - } - - if ( flags & MF_END ) - level--; - } - - return (WORD)((LPSTR)p - (LPSTR)menu32); -} - -/********************************************************************** - * ConvertAccelerator32To16 - */ -VOID ConvertAccelerator32To16( LPVOID acc32, DWORD size, LPVOID acc16 ) -{ - int type; - - do - { - /* Copy type */ - type = *((BYTE *)acc16)++ = *((BYTE *)acc32)++; - /* Skip padding */ - ((BYTE *)acc32)++; - /* Copy event and IDval */ - *((WORD *)acc16)++ = *((WORD *)acc32)++; - *((WORD *)acc16)++ = *((WORD *)acc32)++; - /* Skip padding */ - ((WORD *)acc32)++; - - } while ( !( type & 0x80 ) ); -} - -/********************************************************************** - * NE_LoadPEResource - */ -HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size ) -{ - HGLOBAL16 handle; - - TRACE("module=%04x type=%04x\n", pModule->self, type ); - if (!pModule || !bits || !size) return 0; - - handle = GlobalAlloc16( 0, size ); - - switch (type) - { - case RT_MENU16: - ConvertMenu32To16( bits, size, GlobalLock16( handle ) ); - break; - - case RT_DIALOG16: - ConvertDialog32To16( bits, size, GlobalLock16( handle ) ); - break; - - case RT_ACCELERATOR16: - ConvertAccelerator32To16( bits, size, GlobalLock16( handle ) ); - break; - - case RT_STRING16: - FIXME("not yet implemented!\n" ); - /* fall through */ - - default: - memcpy( GlobalLock16( handle ), bits, size ); - break; - } - - return handle; -} diff --git a/loader/ne/module.c b/loader/ne/module.c index b549e9fbb63..f6469b202f5 100644 --- a/loader/ne/module.c +++ b/loader/ne/module.c @@ -258,6 +258,29 @@ void NE_RegisterModule( NE_MODULE *pModule ) } +/*********************************************************************** + * NE_InitResourceHandler + * + * Fill in 'resloader' fields in the resource table. + */ +void NE_InitResourceHandler( NE_MODULE *pModule ) +{ + static FARPROC16 proc; + + NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2); + + TRACE("InitResourceHandler[%04x]\n", pModule->self ); + + if (!proc) proc = GetProcAddress16( GetModuleHandle16("KERNEL"), "DefResourceHandler" ); + + while(pTypeInfo->type_id) + { + memcpy_unaligned( &pTypeInfo->resloader, &proc, sizeof(FARPROC16) ); + pTypeInfo = (NE_TYPEINFO *)((char*)(pTypeInfo + 1) + pTypeInfo->count * sizeof(NE_NAMEINFO)); + } +} + + /*********************************************************************** * NE_GetOrdinal * @@ -591,7 +614,7 @@ static HMODULE16 NE_LoadExeHeader( HANDLE handle, LPCSTR path ) pData )) return (HMODULE16)11; /* invalid exe */ pData += ne_header.ne_restab - ne_header.ne_rsrctab; - NE_InitResourceHandler( hModule ); + NE_InitResourceHandler( pModule ); } else pModule->res_table = 0; /* No resource table */ diff --git a/loader/ne/resource.c b/loader/ne/resource.c deleted file mode 100644 index e562a4ec847..00000000000 --- a/loader/ne/resource.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * NE resource functions - * - * Copyright 1993 Robert J. Amstadt - * Copyright 1995 Alexandre Julliard - * Copyright 1997 Alex Korobka - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif - -#include "windef.h" -#include "wine/winbase16.h" -#include "wine/library.h" -#include "module.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(resource); - -#define NEXT_TYPEINFO(pTypeInfo) ((NE_TYPEINFO *)((char*)((pTypeInfo) + 1) + \ - (pTypeInfo)->count * sizeof(NE_NAMEINFO))) - -static FARPROC16 DefResourceHandlerProc = (FARPROC16)0xffffffff; - -/* already defined in segment.c glue code */ -extern WORD CALLBACK NE_CallTo16_word_www(FARPROC16,WORD,WORD,WORD); - -/*********************************************************************** - * NE_FindNameTableId - * - * 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, LPCSTR typeId, LPCSTR resId ) -{ - NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2); - NE_NAMEINFO *pNameInfo; - HGLOBAL16 handle; - WORD *p; - DWORD ret = 0; - int count; - - for (; pTypeInfo->type_id != 0; - pTypeInfo = (NE_TYPEINFO *)((char*)(pTypeInfo+1) + - pTypeInfo->count * sizeof(NE_NAMEINFO))) - { - if (pTypeInfo->type_id != 0x800f) continue; - pNameInfo = (NE_NAMEINFO *)(pTypeInfo + 1); - for (count = pTypeInfo->count; count > 0; count--, pNameInfo++) - { - TRACE("NameTable entry: type=%04x id=%04x\n", - pTypeInfo->type_id, pNameInfo->id ); - handle = LoadResource16( pModule->self, - (HRSRC16)((int)pNameInfo - (int)pModule) ); - for(p = (WORD*)LockResource16(handle); p && *p; p = (WORD *)((char*)p+*p)) - { - TRACE(" type=%04x '%s' id=%04x '%s'\n", - p[1], (char *)(p+3), p[2], - (char *)(p+3)+strlen((char *)(p+3))+1 ); - /* Check for correct type */ - - if (p[1] & 0x8000) - { - if (!HIWORD(typeId)) continue; - if (strcasecmp( typeId, (char *)(p + 3) )) continue; - } - else if (HIWORD(typeId) || (((DWORD)typeId & ~0x8000)!= p[1])) - continue; - - /* Now check for the id */ - - if (p[2] & 0x8000) - { - if (!HIWORD(resId)) continue; - if (strcasecmp( resId, (char*)(p+3)+strlen((char*)(p+3))+1 )) continue; - - } - else if (HIWORD(resId) || (((DWORD)resId & ~0x8000) != p[2])) - continue; - - /* If we get here, we've found the entry */ - - TRACE(" Found!\n" ); - ret = MAKELONG( p[1], p[2] ); - break; - } - FreeResource16( handle ); - if (ret) return ret; - } - } - return 0; -} - -/*********************************************************************** - * NE_FindTypeSection - * - * Find header struct for a particular resource type. - */ -NE_TYPEINFO *NE_FindTypeSection( LPBYTE pResTab, - NE_TYPEINFO *pTypeInfo, LPCSTR typeId ) -{ - /* start from pTypeInfo */ - - if (HIWORD(typeId) != 0) /* Named type */ - { - LPCSTR str = typeId; - BYTE len = strlen( str ); - while (pTypeInfo->type_id) - { - if (!(pTypeInfo->type_id & 0x8000)) - { - BYTE *p = pResTab + pTypeInfo->type_id; - if ((*p == len) && !strncasecmp( p+1, str, len )) - { - TRACE(" Found type '%s'\n", str ); - return pTypeInfo; - } - } - TRACE(" Skipping type %04x\n", pTypeInfo->type_id ); - pTypeInfo = NEXT_TYPEINFO(pTypeInfo); - } - } - else /* Numeric type id */ - { - WORD id = LOWORD(typeId) | 0x8000; - while (pTypeInfo->type_id) - { - if (pTypeInfo->type_id == id) - { - TRACE(" Found type %04x\n", id ); - return pTypeInfo; - } - TRACE(" Skipping type %04x\n", pTypeInfo->type_id ); - pTypeInfo = NEXT_TYPEINFO(pTypeInfo); - } - } - return NULL; -} - -/*********************************************************************** - * NE_FindResourceFromType - * - * Find a resource once the type info structure has been found. - */ -NE_NAMEINFO *NE_FindResourceFromType( LPBYTE pResTab, - NE_TYPEINFO *pTypeInfo, LPCSTR resId ) -{ - BYTE *p; - int count; - NE_NAMEINFO *pNameInfo = (NE_NAMEINFO *)(pTypeInfo + 1); - - if (HIWORD(resId) != 0) /* Named resource */ - { - LPCSTR str = resId; - BYTE len = strlen( str ); - for (count = pTypeInfo->count; count > 0; count--, pNameInfo++) - { - if (pNameInfo->id & 0x8000) continue; - p = pResTab + pNameInfo->id; - if ((*p == len) && !strncasecmp( p+1, str, len )) - return pNameInfo; - } - } - else /* Numeric resource id */ - { - WORD id = LOWORD(resId) | 0x8000; - for (count = pTypeInfo->count; count > 0; count--, pNameInfo++) - if (pNameInfo->id == id) - return pNameInfo; - } - return NULL; -} - - -/*********************************************************************** - * DefResourceHandler (KERNEL.456) - * - * This is the default LoadProc() function. - */ -HGLOBAL16 WINAPI NE_DefResourceHandler( HGLOBAL16 hMemObj, HMODULE16 hModule, - HRSRC16 hRsrc ) -{ - HANDLE fd; - NE_MODULE* pModule = NE_GetPtr( hModule ); - if (pModule && (pModule->flags & NE_FFLAGS_BUILTIN)) - { - HGLOBAL16 handle; - WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); - NE_NAMEINFO* pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); - - if ( hMemObj ) - handle = GlobalReAlloc16( hMemObj, pNameInfo->length << sizeShift, 0 ); - else - handle = AllocResource16( hModule, hRsrc, 0 ); - - if ( handle ) - { - /* NOTE: hRsrcMap points to start of built-in resource data */ - memcpy( GlobalLock16( handle ), - (char *)pModule->hRsrcMap + (pNameInfo->offset << sizeShift), - pNameInfo->length << sizeShift ); - } - return handle; - } - if (pModule && (fd = NE_OpenFile( pModule )) != INVALID_HANDLE_VALUE) - { - HGLOBAL16 handle; - WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); - NE_NAMEINFO* pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); - - TRACE("loading, pos=%d, len=%d\n", - (int)pNameInfo->offset << sizeShift, - (int)pNameInfo->length << sizeShift ); - if( hMemObj ) - handle = GlobalReAlloc16( hMemObj, pNameInfo->length << sizeShift, 0 ); - else - handle = AllocResource16( hModule, hRsrc, 0 ); - - if( handle ) - { - DWORD res; - SetFilePointer( fd, (int)pNameInfo->offset << sizeShift, NULL, SEEK_SET ); - ReadFile( fd, GlobalLock16( handle ), (int)pNameInfo->length << sizeShift, - &res, NULL ); - } - CloseHandle(fd); - return handle; - } - return (HGLOBAL16)0; -} - -/*********************************************************************** - * NE_InitResourceHandler - * - * Fill in 'resloader' fields in the resource table. - */ -BOOL NE_InitResourceHandler( HMODULE16 hModule ) -{ - NE_MODULE *pModule = NE_GetPtr( hModule ); - NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2); - - if ( DefResourceHandlerProc == (FARPROC16)0xffffffff ) - { - HMODULE16 hModule = GetModuleHandle16( "KERNEL" ); - int ordinal = hModule? NE_GetOrdinal( hModule, "DefResourceHandler" ) : 0; - - if ( ordinal ) - DefResourceHandlerProc = NE_GetEntryPointEx( hModule, ordinal, FALSE ); - else - DefResourceHandlerProc = NULL; - } - - TRACE("InitResourceHandler[%04x]\n", hModule ); - - while(pTypeInfo->type_id) - { - memcpy_unaligned( &pTypeInfo->resloader, &DefResourceHandlerProc, sizeof(FARPROC16) ); - pTypeInfo = NEXT_TYPEINFO(pTypeInfo); - } - return TRUE; -} - - -/********************************************************************** - * SetResourceHandler (KERNEL.67) - */ -FARPROC16 WINAPI SetResourceHandler16( HMODULE16 hModule, LPCSTR typeId, - FARPROC16 resourceHandler ) -{ - FARPROC16 prevHandler = NULL; - NE_MODULE *pModule = NE_GetPtr( hModule ); - LPBYTE pResTab = (LPBYTE)pModule + pModule->res_table; - NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)(pResTab + 2); - - if (!pModule || !pModule->res_table) return NULL; - - TRACE("module=%04x type=%s\n", hModule, debugstr_a(typeId) ); - - for (;;) - { - if (!(pTypeInfo = NE_FindTypeSection( pResTab, pTypeInfo, typeId ))) - break; - memcpy_unaligned( &prevHandler, &pTypeInfo->resloader, sizeof(FARPROC16) ); - memcpy_unaligned( &pTypeInfo->resloader, &resourceHandler, sizeof(FARPROC16) ); - pTypeInfo = NEXT_TYPEINFO(pTypeInfo); - } - return prevHandler; -} - - -/********************************************************************** - * NE_FindResource - */ -HRSRC NE_FindResource( NE_MODULE *pModule, LPCSTR name, LPCSTR type ) -{ - NE_TYPEINFO *pTypeInfo; - NE_NAMEINFO *pNameInfo; - LPBYTE pResTab; - - if (!pModule || !pModule->res_table) return 0; - - TRACE("module=%04x name=%s type=%s\n", pModule->self, debugstr_a(name), debugstr_a(type) ); - - if (HIWORD(name)) /* Check for '#xxx' name */ - { - LPCSTR ptr = name; - if (ptr[0] == '#') - if (!(name = (LPCSTR)atoi( ptr + 1 ))) - { - WARN("Incorrect resource name: %s\n", ptr); - return 0; - } - } - - if (HIWORD(type)) /* Check for '#xxx' type */ - { - LPCSTR ptr = type; - if (ptr[0] == '#') - if (!(type = (LPCSTR)atoi( ptr + 1 ))) - { - WARN("Incorrect resource type: %s\n", ptr); - return 0; - } - } - - if (HIWORD(type) || HIWORD(name)) - { - DWORD id = NE_FindNameTableId( pModule, type, name ); - if (id) /* found */ - { - type = (LPCSTR)(int)LOWORD(id); - name = (LPCSTR)(int)HIWORD(id); - } - } - - pResTab = (LPBYTE)pModule + pModule->res_table; - pTypeInfo = (NE_TYPEINFO *)( pResTab + 2 ); - - for (;;) - { - if (!(pTypeInfo = NE_FindTypeSection( pResTab, pTypeInfo, type ))) - break; - if ((pNameInfo = NE_FindResourceFromType( pResTab, pTypeInfo, name ))) - { - TRACE(" Found id %08lx\n", (DWORD)name ); - return (HRSRC)( (char *)pNameInfo - (char *)pModule ); - } - TRACE(" Not found, going on\n" ); - pTypeInfo = NEXT_TYPEINFO(pTypeInfo); - } - - WARN("failed!\n"); - return 0; -} - - -/********************************************************************** - * AllocResource (KERNEL.66) - */ -HGLOBAL16 WINAPI AllocResource16( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size) -{ - NE_NAMEINFO *pNameInfo=NULL; - WORD sizeShift; - HGLOBAL16 ret; - - NE_MODULE *pModule = NE_GetPtr( hModule ); - if (!pModule || !pModule->res_table || !hRsrc) return 0; - - TRACE("module=%04x res=%04x size=%ld\n", hModule, hRsrc, size ); - - sizeShift = *(WORD *)((char *)pModule + pModule->res_table); - pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); - if (size < (DWORD)pNameInfo->length << sizeShift) - size = (DWORD)pNameInfo->length << sizeShift; - ret = GlobalAlloc16( GMEM_FIXED, size ); - if (ret) FarSetOwner16( ret, hModule ); - return ret; -} - - -/********************************************************************** - * DirectResAlloc (KERNEL.168) - * - * Check Schulman, p. 232 for details - */ -HGLOBAL16 WINAPI DirectResAlloc16( HINSTANCE16 hInstance, WORD wType, - UINT16 wSize ) -{ - HGLOBAL16 ret; - TRACE("(%04x,%04x,%04x)\n", hInstance, wType, wSize ); - if (!(hInstance = GetExePtr( hInstance ))) return 0; - if(wType != 0x10) /* 0x10 is the only observed value, passed from - CreateCursorIndirect. */ - TRACE("(wType=%x)\n", wType); - ret = GlobalAlloc16( GMEM_MOVEABLE, wSize ); - if (ret) FarSetOwner16( ret, hInstance ); - return ret; -} - - -/********************************************************************** - * AccessResource (KERNEL.64) - */ -INT16 WINAPI AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc ) -{ - HFILE16 fd; - NE_MODULE *pModule = NE_GetPtr( hModule ); - - if (!pModule || !pModule->res_table || !hRsrc) return -1; - - TRACE("module=%04x res=%04x\n", pModule->self, hRsrc ); - - if ((fd = _lopen16( NE_MODULE_NAME(pModule), OF_READ )) != HFILE_ERROR16) - { - WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); - NE_NAMEINFO *pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); - _llseek16( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET ); - } - return fd; -} - - -/********************************************************************** - * NE_SizeofResource - */ -DWORD NE_SizeofResource( NE_MODULE *pModule, HRSRC hRsrc ) -{ - NE_NAMEINFO *pNameInfo=NULL; - WORD sizeShift; - - if (!pModule || !pModule->res_table) return 0; - - TRACE("module=%04x res=%p\n", pModule->self, hRsrc ); - - sizeShift = *(WORD *)((char *)pModule + pModule->res_table); - pNameInfo = (NE_NAMEINFO*)((char*)pModule + LOWORD(hRsrc)); - return (DWORD)pNameInfo->length << sizeShift; -} - - -/********************************************************************** - * NE_LoadResource - */ -HGLOBAL16 NE_LoadResource( NE_MODULE *pModule, HRSRC16 hRsrc ) -{ - NE_TYPEINFO *pTypeInfo; - NE_NAMEINFO *pNameInfo = NULL; - int d; - - TRACE("module=%04x res=%04x\n", pModule->self, hRsrc ); - if (!hRsrc || !pModule || !pModule->res_table) return 0; - - /* First, verify hRsrc (just an offset from pModule to the needed pNameInfo) */ - - d = pModule->res_table + 2; - pTypeInfo = (NE_TYPEINFO *)((char *)pModule + d); - while( hRsrc > d ) - { - if (pTypeInfo->type_id == 0) - break; /* terminal entry */ - d += sizeof(NE_TYPEINFO) + pTypeInfo->count * sizeof(NE_NAMEINFO); - if (hRsrc < d) - { - if( ((d - hRsrc)%sizeof(NE_NAMEINFO)) == 0 ) - { - pNameInfo = (NE_NAMEINFO *)(((char *)pModule) + hRsrc); - break; - } - else - break; /* NE_NAMEINFO boundary mismatch */ - } - pTypeInfo = (NE_TYPEINFO *)(((char *)pModule) + d); - } - - if (pNameInfo) - { - if (pNameInfo->handle - && !(GlobalFlags16(pNameInfo->handle) & GMEM_DISCARDED)) - { - pNameInfo->usage++; - TRACE(" Already loaded, new count=%d\n", - pNameInfo->usage ); - } - else - { - FARPROC16 resloader; - memcpy_unaligned( &resloader, &pTypeInfo->resloader, sizeof(FARPROC16) ); - if ( resloader && resloader != DefResourceHandlerProc ) - pNameInfo->handle = NE_CallTo16_word_www( - resloader, pNameInfo->handle, pModule->self, hRsrc ); - else - pNameInfo->handle = NE_DefResourceHandler( - pNameInfo->handle, pModule->self, hRsrc ); - - if (pNameInfo->handle) - { - pNameInfo->usage++; - pNameInfo->flags |= NE_SEGFLAGS_LOADED; - } - } - return pNameInfo->handle; - } - return 0; -} - - -/********************************************************************** - * NE_FreeResource - */ -BOOL16 NE_FreeResource( NE_MODULE *pModule, HGLOBAL16 handle ) -{ - NE_TYPEINFO *pTypeInfo; - NE_NAMEINFO *pNameInfo; - WORD count; - - if (!handle || !pModule || !pModule->res_table) return handle; - - TRACE("handle=%04x\n", handle ); - - pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2); - while (pTypeInfo->type_id) - { - pNameInfo = (NE_NAMEINFO *)(pTypeInfo + 1); - for (count = pTypeInfo->count; count > 0; count--) - { - if (pNameInfo->handle == handle) - { - if (pNameInfo->usage > 0) pNameInfo->usage--; - if (pNameInfo->usage == 0) - { - GlobalFree16( pNameInfo->handle ); - pNameInfo->handle = 0; - pNameInfo->flags &= ~NE_SEGFLAGS_LOADED; - } - return 0; - } - pNameInfo++; - } - pTypeInfo = (NE_TYPEINFO *)pNameInfo; - } - - return handle; -} diff --git a/loader/pe_resource.c b/loader/pe_resource.c index aec210817ed..e530d9a3f66 100644 --- a/loader/pe_resource.c +++ b/loader/pe_resource.c @@ -41,17 +41,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(resource); -/********************************************************************** - * is_data_file_module - * - * Check if a module handle is for a LOAD_LIBRARY_AS_DATAFILE module. - */ -inline static int is_data_file_module( HMODULE hmod ) -{ - return (ULONG_PTR)hmod & 1; -} - - /********************************************************************** * get_resdir * @@ -166,146 +155,6 @@ static const IMAGE_RESOURCE_DIRECTORY *find_entry_by_nameA( const IMAGE_RESOURCE } -/********************************************************************** - * find_entry_default - * - * Find a default entry in a resource directory - */ -static const IMAGE_RESOURCE_DIRECTORY *find_entry_default( const IMAGE_RESOURCE_DIRECTORY *dir, - const void *root ) -{ - const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry; - - entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); - return (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry->u2.s3.OffsetToDirectory); -} - - -/********************************************************************** - * PE_FindResourceExW - * - * FindResourceExA/W does search in the following order: - * 1. Exact specified language - * 2. Language with neutral sublanguage - * 3. Neutral language with neutral sublanguage - * 4. Neutral language with default sublanguage - */ -HRSRC PE_FindResourceExW( HMODULE hmod, LPCWSTR name, LPCWSTR type, WORD lang ) -{ - const IMAGE_RESOURCE_DIRECTORY *resdirptr = get_resdir(hmod); - const void *root; - HRSRC result; - - if (!resdirptr) return 0; - - root = resdirptr; - if (!(resdirptr = find_entry_by_nameW(resdirptr, type, root))) return 0; - if (!(resdirptr = find_entry_by_nameW(resdirptr, name, root))) return 0; - - /* 1. Exact specified language */ - if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found; - - /* 2. Language with neutral sublanguage */ - lang = MAKELANGID(PRIMARYLANGID(lang), SUBLANG_NEUTRAL); - if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found; - - /* 3. Neutral language with neutral sublanguage */ - lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); - if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found; - - /* 4. Neutral language with default sublanguage */ - lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); - result = (HRSRC)find_entry_by_id( resdirptr, lang, root ); - - found: - return result; -} - -/********************************************************************** - * PE_FindResourceW - * - * Load[String]/[Icon]/[Menu]/[etc.] does use FindResourceA/W. - * FindResourceA/W does search in the following order: - * 1. Neutral language with neutral sublanguage - * 2. Neutral language with default sublanguage - * 3. Current locale lang id - * 4. Current locale lang id with neutral sublanguage - * 5. (!) LANG_ENGLISH, SUBLANG_DEFAULT - * 6. Return first in the list - */ -HRSRC PE_FindResourceW( HMODULE hmod, LPCWSTR name, LPCWSTR type ) -{ - const IMAGE_RESOURCE_DIRECTORY *resdirptr = get_resdir(hmod); - const void *root; - HRSRC result; - WORD lang; - - if (!resdirptr) return 0; - - root = resdirptr; - if (!(resdirptr = find_entry_by_nameW(resdirptr, type, root))) return 0; - if (!(resdirptr = find_entry_by_nameW(resdirptr, name, root))) return 0; - - /* 1. Neutral language with neutral sublanguage */ - lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); - if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found; - - /* 2. Neutral language with default sublanguage */ - lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); - if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found; - - /* 3. Current locale lang id */ - lang = LANGIDFROMLCID(GetUserDefaultLCID()); - if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found; - - /* 4. Current locale lang id with neutral sublanguage */ - lang = MAKELANGID(PRIMARYLANGID(lang), SUBLANG_NEUTRAL); - if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found; - - /* 5. (!) LANG_ENGLISH, SUBLANG_DEFAULT */ - lang = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); - if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found; - - /* 6. Return first in the list */ - result = (HRSRC)find_entry_default( resdirptr, root ); - - found: - return result; -} - - -/********************************************************************** - * PE_LoadResource - */ -HGLOBAL PE_LoadResource( HMODULE hmod, HRSRC hRsrc ) -{ - DWORD offset; - - if (!hRsrc) return 0; - if (!hmod) hmod = GetModuleHandleA( NULL ); - - offset = ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData; - - if (is_data_file_module(hmod)) - { - hmod = (HMODULE)((ULONG_PTR)hmod & ~1); - return (HGLOBAL)RtlImageRvaToVa( RtlImageNtHeader(hmod), hmod, offset, NULL ); - } - else - return (HGLOBAL)((char *)hmod + offset); -} - - -/********************************************************************** - * PE_SizeofResource - */ -DWORD PE_SizeofResource( HRSRC hRsrc ) -{ - if (!hRsrc) return 0; - return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size; -} - - /********************************************************************** * EnumResourceTypesA (KERNEL32.@) */ diff --git a/loader/resource.c b/loader/resource.c deleted file mode 100644 index 5b8f9a1d3a0..00000000000 --- a/loader/resource.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Resources - * - * Copyright 1993 Robert J. Amstadt - * Copyright 1995 Alexandre Julliard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include "windef.h" -#include "winbase.h" -#include "wine/winbase16.h" -#include "wine/exception.h" -#include "heap.h" -#include "cursoricon.h" -#include "module.h" -#include "file.h" -#include "wine/debug.h" -#include "winerror.h" -#include "winnls.h" -#include "excpt.h" -#include "winternl.h" - -WINE_DEFAULT_DEBUG_CHANNEL(resource); - -#define HRSRC_MAP_BLOCKSIZE 16 - -/* handle conversions */ -#define HRSRC_32(h16) ((HRSRC)(ULONG_PTR)(h16)) -#define HGLOBAL_32(h16) ((HGLOBAL)(ULONG_PTR)(h16)) -#define HGLOBAL_16(h32) (LOWORD(h32)) -#define HMODULE_32(h16) ((HMODULE)(ULONG_PTR)(h16)) - -typedef struct _HRSRC_ELEM -{ - HRSRC hRsrc; - WORD type; -} HRSRC_ELEM; - -typedef struct _HRSRC_MAP -{ - int nAlloc; - int nUsed; - HRSRC_ELEM *elem; -} HRSRC_MAP; - -/********************************************************************** - * MapHRsrc32To16 - */ -static HRSRC MapHRsrc32To16( NE_MODULE *pModule, HRSRC 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("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 (HRSRC)(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("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 (HRSRC)map->nUsed; -} - -/********************************************************************** - * MapHRsrc16To32 - */ -static HRSRC MapHRsrc16To32( NE_MODULE *pModule, HRSRC 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, HRSRC hRsrc16 ) -{ - HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; - if ( !map || !hRsrc16 || (int)hRsrc16 > map->nUsed ) return 0; - - return map->elem[(int)hRsrc16-1].type; -} - - -/* filter for page-fault exceptions */ -static WINE_EXCEPTION_FILTER(page_fault) -{ - if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) - return EXCEPTION_EXECUTE_HANDLER; - return EXCEPTION_CONTINUE_SEARCH; -} - -static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type, - LPCSTR name, WORD lang, - BOOL bUnicode, BOOL bRet16 ) -{ - HRSRC hRsrc = 0; - - TRACE("(%p, %08x%s, %08x%s, %04x, %s, %s)\n", - hModule, - (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 (!HIWORD(hModule)) - { - HMODULE16 hMod16 = MapHModuleLS( hModule ); - NE_MODULE *pModule = NE_GetPtr( hMod16 ); - if (!pModule) return 0; - if (!pModule->module32) - { - /* 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 */ - } - else - { - /* 32-bit PE module */ - hRsrc = RES_FindResource2( pModule->module32, type, name, lang, bUnicode, FALSE ); - /* If we need to return 16-bit HRSRC, perform conversion */ - if ( bRet16 ) - hRsrc = MapHRsrc32To16( pModule, hRsrc, - HIWORD( type )? 0 : LOWORD( type ) ); - } - } - else - { - /* 32-bit PE module */ - LPWSTR typeStr, nameStr; - - if ( HIWORD( type ) && !bUnicode ) - { - UNICODE_STRING usBuffer; - RtlCreateUnicodeStringFromAsciiz(&usBuffer,type); - typeStr = usBuffer.Buffer; - } - else - typeStr = (LPWSTR)type; - if ( HIWORD( name ) && !bUnicode ) - { - UNICODE_STRING usBuffer; - RtlCreateUnicodeStringFromAsciiz(&usBuffer,name); - nameStr = usBuffer.Buffer; - } - else - nameStr = (LPWSTR)name; - - /* Here is the real difference between FindResouce and FindResourceEx */ - if(lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) || - lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) || - lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT) || - lang == MAKELANGID(LANG_NEUTRAL, 3)) /* FIXME: real name? */ - hRsrc = PE_FindResourceW( hModule, nameStr, typeStr ); - else - hRsrc = PE_FindResourceExW( hModule, nameStr, typeStr, lang ); - - if ( HIWORD( type ) && !bUnicode ) - HeapFree( GetProcessHeap(), 0, typeStr ); - if ( HIWORD( name ) && !bUnicode ) - HeapFree( GetProcessHeap(), 0, nameStr ); - } - return hRsrc; -} - -/********************************************************************** - * RES_FindResource - */ - -static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type, - LPCSTR name, WORD lang, - BOOL bUnicode, BOOL bRet16 ) -{ - HRSRC hRsrc; - __TRY - { - hRsrc = RES_FindResource2(hModule, type, name, lang, bUnicode, bRet16); - } - __EXCEPT(page_fault) - { - WARN("page fault\n"); - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - __ENDTRY - return hRsrc; -} - -/********************************************************************** - * RES_SizeofResource - */ -static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 ) -{ - if (!hRsrc) return 0; - - TRACE("(%p, %p, %s)\n", hModule, hRsrc, bRet16? "NE" : "PE" ); - - if (!HIWORD(hModule)) - { - HMODULE16 hMod16 = MapHModuleLS( hModule ); - NE_MODULE *pModule = NE_GetPtr( hMod16 ); - if (!pModule) return 0; - - if (!pModule->module32) /* 16-bit NE module */ - { - /* If we got a 32-bit hRsrc, we don't need to convert it */ - return NE_SizeofResource( pModule, hRsrc ); - } - - /* If we got a 16-bit hRsrc, convert it */ - if (!HIWORD(hRsrc)) hRsrc = MapHRsrc16To32( pModule, hRsrc ); - } - - /* 32-bit PE module */ - return PE_SizeofResource( hRsrc ); -} - -/********************************************************************** - * RES_LoadResource - */ -static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 ) -{ - HGLOBAL hMem = 0; - - TRACE("(%p, %p, %s)\n", hModule, hRsrc, bRet16? "NE" : "PE" ); - - if (!hRsrc) return 0; - - if (!HIWORD(hModule)) - { - HMODULE16 hMod16 = MapHModuleLS( hModule ); - NE_MODULE *pModule = NE_GetPtr( hMod16 ); - if (!pModule) return 0; - if (!pModule->module32) - { - /* 16-bit NE module */ - - /* If we got a 32-bit hRsrc, we don't need to convert it */ - hMem = HGLOBAL_32(NE_LoadResource( pModule, LOWORD(hRsrc) )); - - /* If we are to return a 32-bit resource, we should probably - convert it but we don't for now. FIXME !!! */ - return hMem; - } - else - { - /* If we got a 16-bit hRsrc, convert it */ - HRSRC hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); - - hMem = PE_LoadResource( pModule->module32, hRsrc32 ); - - /* 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 = HGLOBAL_32(NE_LoadPEResource( pModule, type, bits, size )); - } - } - } - else - { - /* 32-bit PE module */ - hMem = PE_LoadResource( hModule, hRsrc ); - } - - return hMem; -} - -/********************************************************************** - * FindResource (KERNEL.60) - */ -HRSRC16 WINAPI FindResource16( HMODULE16 hModule, LPCSTR name, LPCSTR type ) -{ - return LOWORD( RES_FindResource( HMODULE_32(hModule), type, name, - MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, TRUE ) ); -} - -/********************************************************************** - * FindResourceA (KERNEL32.@) - */ -HRSRC WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) -{ - return RES_FindResource( hModule, type, name, - MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, FALSE ); -} - -/********************************************************************** - * FindResourceExA (KERNEL32.@) - */ -HRSRC WINAPI FindResourceExA( HMODULE hModule, - LPCSTR type, LPCSTR name, WORD lang ) -{ - return RES_FindResource( hModule, type, name, - lang, FALSE, FALSE ); -} - -/********************************************************************** - * FindResourceExW (KERNEL32.@) - */ -HRSRC WINAPI FindResourceExW( HMODULE hModule, - LPCWSTR type, LPCWSTR name, WORD lang ) -{ - return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, - lang, TRUE, FALSE ); -} - -/********************************************************************** - * FindResourceW (KERNEL32.@) - */ -HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type) -{ - return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, - MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), TRUE, FALSE ); -} - -/********************************************************************** - * LoadResource (KERNEL.61) - */ -HGLOBAL16 WINAPI LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc ) -{ - return HGLOBAL_16(RES_LoadResource( HMODULE_32(hModule), HRSRC_32(hRsrc), TRUE )); -} - -/********************************************************************** - * LoadResource (KERNEL32.@) - */ -HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc ) -{ - return RES_LoadResource( hModule, hRsrc, FALSE ); -} - -/********************************************************************** - * LockResource (KERNEL.62) - */ -SEGPTR WINAPI WIN16_LockResource16( HGLOBAL16 handle ) -{ - TRACE("(%04x)\n", handle ); - /* May need to reload the resource if discarded */ - return K32WOWGlobalLock16( handle ); -} - -/********************************************************************** - * LockResource16 (KERNEL32.@) - */ -LPVOID WINAPI LockResource16( HGLOBAL16 handle ) -{ - return MapSL( WIN16_LockResource16(handle) ); -} - -/********************************************************************** - * LockResource (KERNEL32.@) - */ -LPVOID WINAPI LockResource( HGLOBAL handle ) -{ - TRACE("(%p)\n", handle ); - - if (HIWORD( handle )) /* 32-bit memory handle */ - return (LPVOID)handle; - - /* 16-bit memory handle */ - return LockResource16( LOWORD(handle) ); -} - -typedef WORD (WINAPI *pDestroyIcon32Proc)( HGLOBAL16 handle, UINT16 flags ); - - -/********************************************************************** - * FreeResource (KERNEL.63) - */ -BOOL16 WINAPI FreeResource16( HGLOBAL16 handle ) -{ - HGLOBAL16 retv = handle; - NE_MODULE *pModule = NE_GetPtr( FarGetOwner16( handle ) ); - - TRACE("(%04x)\n", 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 ) - { - pDestroyIcon32Proc proc; - HMODULE user = GetModuleHandleA( "user32.dll" ); - - if (user && (proc = (pDestroyIcon32Proc)GetProcAddress( user, "DestroyIcon32" ))) - retv = proc( handle, CID_RESOURCE ); - else - retv = GlobalFree16( handle ); - } - return (BOOL)retv; -} - -/********************************************************************** - * FreeResource (KERNEL32.@) - */ -BOOL WINAPI FreeResource( HGLOBAL handle ) -{ - if (HIWORD(handle)) return 0; /* 32-bit memory handle: nothing to do */ - - return FreeResource16( LOWORD(handle) ); -} - -/********************************************************************** - * SizeofResource (KERNEL.65) - */ -DWORD WINAPI SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc ) -{ - return RES_SizeofResource( HMODULE_32(hModule), HRSRC_32(hRsrc), TRUE ); -} - -/********************************************************************** - * SizeofResource (KERNEL32.@) - */ -DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc ) -{ - return RES_SizeofResource( hModule, hRsrc, FALSE ); -}