From 8543a5db9a5893b70509fe473ea59f26870ae566 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 13 Dec 2003 01:36:14 +0000 Subject: [PATCH] Added exception handlers in FindResourceExA/W (based on a patch by Richard Cohen). --- dlls/kernel/resource.c | 157 ++++++++++++++++++++++++++++------------- 1 file changed, 108 insertions(+), 49 deletions(-) diff --git a/dlls/kernel/resource.c b/dlls/kernel/resource.c index 695c8ed61d6..0baf3c4fedd 100644 --- a/dlls/kernel/resource.c +++ b/dlls/kernel/resource.c @@ -34,6 +34,8 @@ #include "wownt32.h" #include "wine/winbase16.h" #include "wine/debug.h" +#include "excpt.h" +#include "wine/exception.h" WINE_DEFAULT_DEBUG_CHANNEL(resource); @@ -44,6 +46,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(resource); #define HGLOBAL_16(h32) (LOWORD(h32)) #define HMODULE_16(h32) (LOWORD(h32)) +static WINE_EXCEPTION_FILTER(page_fault) +{ + if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION || + GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION) + return EXCEPTION_EXECUTE_HANDLER; + return EXCEPTION_CONTINUE_SEARCH; +} /* retrieve the resource name to pass to the ntdll functions */ static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str ) @@ -88,16 +97,108 @@ static NTSTATUS get_res_nameW( LPCWSTR name, UNICODE_STRING *str ) return STATUS_SUCCESS; } -/********************************************************************** - * FindResourceExA (KERNEL32.@) - */ -HRSRC WINAPI FindResourceExA( HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang ) +/* retrieve the resource names for the 16-bit FindResource function */ +static BOOL get_res_name_type_WtoA( LPCWSTR name, LPCWSTR type, LPSTR *nameA, LPSTR *typeA ) +{ + *nameA = *typeA = NULL; + + __TRY + { + 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; + } + __EXCEPT(page_fault) + { + if (HIWORD(*nameA)) HeapFree( GetProcessHeap(), 0, *nameA ); + if (HIWORD(*typeA)) HeapFree( GetProcessHeap(), 0, *typeA ); + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + __ENDTRY + return TRUE; +} + +/* implementation of FindResourceExA */ +static HRSRC find_resourceA( 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; + __TRY + { + 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 (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + } + __EXCEPT(page_fault) + { + SetLastError( ERROR_INVALID_PARAMETER ); + } + __ENDTRY + + if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); + if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + return (HRSRC)entry; +} + + +/* implementation of FindResourceExW */ +static HRSRC find_resourceW( 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; + + nameW.Buffer = typeW.Buffer = NULL; + + __TRY + { + 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 (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + } + __EXCEPT(page_fault) + { + SetLastError( ERROR_INVALID_PARAMETER ); + } + __ENDTRY + + if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); + if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + return (HRSRC)entry; +} + +/********************************************************************** + * FindResourceExA (KERNEL32.@) + */ +HRSRC WINAPI FindResourceExA( HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang ) +{ TRACE( "%p %s %s %04x\n", hModule, debugstr_a(type), debugstr_a(name), lang ); if (!hModule) hModule = GetModuleHandleW(0); @@ -105,19 +206,7 @@ HRSRC WINAPI FindResourceExA( HMODULE hModule, LPCSTR type, LPCSTR name, WORD la { 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; + return find_resourceA( hModule, type, name, lang ); } @@ -135,11 +224,6 @@ HRSRC WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) */ 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); @@ -148,21 +232,7 @@ HRSRC WINAPI FindResourceExW( HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD 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; + if (!get_res_name_type_WtoA( name, type, &nameA, &typeA )) return NULL; ret = FindResource16( HMODULE_16(hModule), nameA, typeA ); if (HIWORD(nameA)) HeapFree( GetProcessHeap(), 0, nameA ); @@ -170,18 +240,7 @@ HRSRC WINAPI FindResourceExW( HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD 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; + return find_resourceW( hModule, type, name, lang ); }