From ce4d111cd87b15e83e8ad8b1e561cce88f4f27a5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 7 May 2003 03:21:26 +0000 Subject: [PATCH] Moved the EnumResource* functions to the kernel dll, and fixed their prototypes. --- dlls/kernel/resource.c | 312 +++++++++++++++++++++++++++++++++ dlls/ntdll/Makefile.in | 1 - dlls/ntdll/resource.c | 16 +- include/winbase.h | 24 +-- include/winternl.h | 2 +- loader/pe_resource.c | 379 ----------------------------------------- 6 files changed, 333 insertions(+), 401 deletions(-) delete mode 100644 loader/pe_resource.c diff --git a/dlls/kernel/resource.c b/dlls/kernel/resource.c index 300551f1a8e..8be32ca65d1 100644 --- a/dlls/kernel/resource.c +++ b/dlls/kernel/resource.c @@ -188,6 +188,318 @@ HRSRC WINAPI FindResourceW( HINSTANCE hModule, LPCWSTR name, LPCWSTR type ) } +/********************************************************************** + * EnumResourceTypesA (KERNEL32.@) + */ +BOOL WINAPI EnumResourceTypesA( HMODULE hmod, ENUMRESTYPEPROCA lpfun, LONG_PTR lparam ) +{ + int i; + BOOL ret = FALSE; + LPSTR type = NULL; + DWORD len = 0, newlen; + NTSTATUS status; + const IMAGE_RESOURCE_DIRECTORY *resdir; + const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; + const IMAGE_RESOURCE_DIR_STRING_U *str; + + TRACE( "%p %p %lx\n", hmod, lpfun, lparam ); + + if (!hmod) hmod = GetModuleHandleA( NULL ); + + if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &resdir )) != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1); + for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++) + { + if (et[i].u1.s1.NameIsString) + { + str = (PIMAGE_RESOURCE_DIR_STRING_U) ((LPBYTE) resdir + et[i].u1.s1.NameOffset); + newlen = WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL); + if (newlen + 1 > len) + { + len = newlen + 1; + if (type) HeapFree( GetProcessHeap(), 0, type ); + if (!(type = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE; + } + WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, type, len, NULL, NULL); + type[newlen] = 0; + ret = lpfun(hmod,type,lparam); + } + else + { + ret = lpfun( hmod, (LPSTR)(int)et[i].u1.s2.Id, lparam ); + } + if (!ret) break; + } + if (type) HeapFree( GetProcessHeap(), 0, type ); + return ret; +} + + +/********************************************************************** + * EnumResourceTypesW (KERNEL32.@) + */ +BOOL WINAPI EnumResourceTypesW( HMODULE hmod, ENUMRESTYPEPROCW lpfun, LONG_PTR lparam ) +{ + int i; + BOOL ret = FALSE; + DWORD len = 0; + LPWSTR type = NULL; + NTSTATUS status; + const IMAGE_RESOURCE_DIRECTORY *resdir; + const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; + const IMAGE_RESOURCE_DIR_STRING_U *str; + + TRACE( "%p %p %lx\n", hmod, lpfun, lparam ); + + if (!hmod) hmod = GetModuleHandleW( NULL ); + + if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &resdir )) != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1); + for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++) + { + if (et[i].u1.s1.NameIsString) + { + str = (PIMAGE_RESOURCE_DIR_STRING_U) ((LPBYTE) resdir + et[i].u1.s1.NameOffset); + if (str->Length + 1 > len) + { + len = str->Length + 1; + if (type) HeapFree( GetProcessHeap(), 0, type ); + if (!(type = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE; + } + memcpy(type, str->NameString, str->Length * sizeof (WCHAR)); + type[str->Length] = 0; + ret = lpfun(hmod,type,lparam); + } + else + { + ret = lpfun( hmod, (LPWSTR)(int)et[i].u1.s2.Id, lparam ); + } + if (!ret) break; + } + if (type) HeapFree( GetProcessHeap(), 0, type ); + return ret; +} + + +/********************************************************************** + * EnumResourceNamesA (KERNEL32.@) + */ +BOOL WINAPI EnumResourceNamesA( HMODULE hmod, LPCSTR type, ENUMRESNAMEPROCA lpfun, LONG_PTR lparam ) +{ + int i; + BOOL ret = FALSE; + DWORD len = 0, newlen; + LPSTR name = NULL; + NTSTATUS status; + UNICODE_STRING typeW; + LDR_RESOURCE_INFO info; + const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir; + const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; + const IMAGE_RESOURCE_DIR_STRING_U *str; + + TRACE( "%p %s %p %lx\n", hmod, debugstr_a(type), lpfun, lparam ); + + if (!hmod) hmod = GetModuleHandleA( NULL ); + typeW.Buffer = NULL; + if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS) + goto done; + if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS) + goto done; + info.Type = (ULONG)typeW.Buffer; + if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS) + goto done; + + et = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); + for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++) + { + if (et[i].u1.s1.NameIsString) + { + str = (IMAGE_RESOURCE_DIR_STRING_U *) ((LPBYTE) basedir + et[i].u1.s1.NameOffset); + newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL); + if (newlen + 1 > len) + { + len = newlen + 1; + if (name) HeapFree( GetProcessHeap(), 0, name ); + if (!(name = HeapAlloc(GetProcessHeap(), 0, len + 1 ))) + { + ret = FALSE; + break; + } + } + WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, name, len, NULL, NULL ); + name[newlen] = 0; + ret = lpfun(hmod,type,name,lparam); + } + else + { + ret = lpfun( hmod, type, (LPSTR)(int)et[i].u1.s2.Id, lparam ); + } + if (!ret) break; + } +done: + if (name) HeapFree( GetProcessHeap(), 0, name ); + if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return ret; +} + + +/********************************************************************** + * EnumResourceNamesW (KERNEL32.@) + */ +BOOL WINAPI EnumResourceNamesW( HMODULE hmod, LPCWSTR type, ENUMRESNAMEPROCW lpfun, LONG_PTR lparam ) +{ + int i; + BOOL ret = FALSE; + LPWSTR name = NULL; + DWORD len = 0; + NTSTATUS status; + UNICODE_STRING typeW; + LDR_RESOURCE_INFO info; + const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir; + const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; + const IMAGE_RESOURCE_DIR_STRING_U *str; + + TRACE( "%p %s %p %lx\n", hmod, debugstr_w(type), lpfun, lparam ); + + if (!hmod) hmod = GetModuleHandleW( NULL ); + typeW.Buffer = NULL; + if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS) + goto done; + if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS) + goto done; + info.Type = (ULONG)typeW.Buffer; + if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS) + goto done; + + et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1); + for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++) + { + if (et[i].u1.s1.NameIsString) + { + str = (IMAGE_RESOURCE_DIR_STRING_U *) ((LPBYTE) basedir + et[i].u1.s1.NameOffset); + if (str->Length + 1 > len) + { + len = str->Length + 1; + if (name) HeapFree( GetProcessHeap(), 0, name ); + if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) + { + ret = FALSE; + break; + } + } + memcpy(name, str->NameString, str->Length * sizeof (WCHAR)); + name[str->Length] = 0; + ret = lpfun(hmod,type,name,lparam); + } + else + { + ret = lpfun( hmod, type, (LPWSTR)(int)et[i].u1.s2.Id, lparam ); + } + if (!ret) break; + } +done: + if (name) HeapFree( GetProcessHeap(), 0, name ); + if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return ret; +} + + +/********************************************************************** + * EnumResourceLanguagesA (KERNEL32.@) + */ +BOOL WINAPI EnumResourceLanguagesA( HMODULE hmod, LPCSTR type, LPCSTR name, + ENUMRESLANGPROCA lpfun, LONG_PTR lparam ) +{ + int i; + BOOL ret = FALSE; + NTSTATUS status; + UNICODE_STRING typeW, nameW; + LDR_RESOURCE_INFO info; + const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir; + const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; + + TRACE( "%p %s %s %p %lx\n", hmod, debugstr_a(type), debugstr_a(name), lpfun, lparam ); + + if (!hmod) hmod = GetModuleHandleA( NULL ); + typeW.Buffer = nameW.Buffer = NULL; + if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS) + goto done; + if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS) + goto done; + if ((status = get_res_nameA( name, &nameW )) != STATUS_SUCCESS) + goto done; + info.Type = (ULONG)typeW.Buffer; + info.Name = (ULONG)nameW.Buffer; + if ((status = LdrFindResourceDirectory_U( hmod, &info, 2, &resdir )) != STATUS_SUCCESS) + goto done; + + et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1); + for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++) + { + ret = lpfun( hmod, type, name, et[i].u1.s2.Id, lparam ); + if (!ret) break; + } +done: + if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return ret; +} + + +/********************************************************************** + * EnumResourceLanguagesW (KERNEL32.@) + */ +BOOL WINAPI EnumResourceLanguagesW( HMODULE hmod, LPCWSTR type, LPCWSTR name, + ENUMRESLANGPROCW lpfun, LONG_PTR lparam ) +{ + int i; + BOOL ret = FALSE; + NTSTATUS status; + UNICODE_STRING typeW, nameW; + LDR_RESOURCE_INFO info; + const IMAGE_RESOURCE_DIRECTORY *basedir, *resdir; + const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; + + TRACE( "%p %s %s %p %lx\n", hmod, debugstr_w(type), debugstr_w(name), lpfun, lparam ); + + if (!hmod) hmod = GetModuleHandleW( NULL ); + typeW.Buffer = nameW.Buffer = NULL; + if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS) + goto done; + if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS) + goto done; + if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS) + goto done; + info.Type = (ULONG)typeW.Buffer; + info.Name = (ULONG)nameW.Buffer; + if ((status = LdrFindResourceDirectory_U( hmod, &info, 2, &resdir )) != STATUS_SUCCESS) + goto done; + + et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1); + for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++) + { + ret = lpfun( hmod, type, name, et[i].u1.s2.Id, lparam ); + if (!ret) break; + } +done: + if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return ret; +} + + /********************************************************************** * LoadResource (KERNEL32.@) */ diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in index a6a97fa0c73..80a9c08aff3 100644 --- a/dlls/ntdll/Makefile.in +++ b/dlls/ntdll/Makefile.in @@ -21,7 +21,6 @@ C_SRCS = \ $(TOPOBJDIR)/loader/main.c \ $(TOPOBJDIR)/loader/module.c \ $(TOPOBJDIR)/loader/pe_image.c \ - $(TOPOBJDIR)/loader/pe_resource.c \ $(TOPOBJDIR)/loader/task.c \ $(TOPOBJDIR)/loader/ne/module.c \ $(TOPOBJDIR)/loader/ne/segment.c \ diff --git a/dlls/ntdll/resource.c b/dlls/ntdll/resource.c index daf32325c31..8c0abafbe06 100644 --- a/dlls/ntdll/resource.c +++ b/dlls/ntdll/resource.c @@ -263,19 +263,19 @@ done: * LdrFindResourceDirectory_U (NTDLL.@) */ NTSTATUS WINAPI LdrFindResourceDirectory_U( HMODULE hmod, const LDR_RESOURCE_INFO *info, - ULONG level, const IMAGE_RESOURCE_DIRECTORY_ENTRY **entry ) + ULONG level, const IMAGE_RESOURCE_DIRECTORY **dir ) { const void *res; NTSTATUS status; - TRACE( "module %p type %s name %s lang %04lx level %ld\n", - hmod, debugstr_w((LPCWSTR)info->Type), - debugstr_w((LPCWSTR)info->Name), info->Language, level ); + if (info) TRACE( "module %p type %s name %s lang %04lx level %ld\n", + hmod, debugstr_w((LPCWSTR)info->Type), + debugstr_w((LPCWSTR)info->Name), info->Language, level ); __TRY { status = find_entry( hmod, info, level, &res, TRUE ); - if (status == STATUS_SUCCESS) *entry = res; + if (status == STATUS_SUCCESS) *dir = res; } __EXCEPT(page_fault) { @@ -295,9 +295,9 @@ NTSTATUS WINAPI LdrFindResource_U( HMODULE hmod, const LDR_RESOURCE_INFO *info, const void *res; NTSTATUS status; - TRACE( "module %p type %s name %s lang %04lx level %ld\n", - hmod, debugstr_w((LPCWSTR)info->Type), - debugstr_w((LPCWSTR)info->Name), info->Language, level ); + if (info) TRACE( "module %p type %s name %s lang %04lx level %ld\n", + hmod, debugstr_w((LPCWSTR)info->Type), + debugstr_w((LPCWSTR)info->Name), info->Language, level ); __TRY { diff --git a/include/winbase.h b/include/winbase.h index 121cbe6597c..ef579258569 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -696,12 +696,12 @@ typedef struct tagSYSTEM_INFO WORD wProcessorRevision; } SYSTEM_INFO, *LPSYSTEM_INFO; -typedef BOOL (CALLBACK *ENUMRESTYPEPROCA)(HMODULE,LPSTR,LONG); -typedef BOOL (CALLBACK *ENUMRESTYPEPROCW)(HMODULE,LPWSTR,LONG); -typedef BOOL (CALLBACK *ENUMRESNAMEPROCA)(HMODULE,LPCSTR,LPSTR,LONG); -typedef BOOL (CALLBACK *ENUMRESNAMEPROCW)(HMODULE,LPCWSTR,LPWSTR,LONG); -typedef BOOL (CALLBACK *ENUMRESLANGPROCA)(HMODULE,LPCSTR,LPCSTR,WORD,LONG); -typedef BOOL (CALLBACK *ENUMRESLANGPROCW)(HMODULE,LPCWSTR,LPCWSTR,WORD,LONG); +typedef BOOL (CALLBACK *ENUMRESTYPEPROCA)(HMODULE,LPSTR,LONG_PTR); +typedef BOOL (CALLBACK *ENUMRESTYPEPROCW)(HMODULE,LPWSTR,LONG_PTR); +typedef BOOL (CALLBACK *ENUMRESNAMEPROCA)(HMODULE,LPCSTR,LPSTR,LONG_PTR); +typedef BOOL (CALLBACK *ENUMRESNAMEPROCW)(HMODULE,LPCWSTR,LPWSTR,LONG_PTR); +typedef BOOL (CALLBACK *ENUMRESLANGPROCA)(HMODULE,LPCSTR,LPCSTR,WORD,LONG_PTR); +typedef BOOL (CALLBACK *ENUMRESLANGPROCW)(HMODULE,LPCWSTR,LPCWSTR,WORD,LONG_PTR); DECL_WINELIB_TYPE_AW(ENUMRESTYPEPROC) DECL_WINELIB_TYPE_AW(ENUMRESNAMEPROC) @@ -1250,14 +1250,14 @@ BOOL WINAPI DnsHostnameToComputerNameW(LPCWSTR,LPWSTR,LPDWORD); BOOL WINAPI DosDateTimeToFileTime(WORD,WORD,LPFILETIME); BOOL WINAPI DuplicateHandle(HANDLE,HANDLE,HANDLE,HANDLE*,DWORD,BOOL,DWORD); BOOL WINAPI EscapeCommFunction(HANDLE,UINT); -BOOL WINAPI EnumResourceLanguagesA(HMODULE,LPCSTR,LPCSTR,ENUMRESLANGPROCA,LONG); -BOOL WINAPI EnumResourceLanguagesW(HMODULE,LPCWSTR,LPCWSTR,ENUMRESLANGPROCW,LONG); +BOOL WINAPI EnumResourceLanguagesA(HMODULE,LPCSTR,LPCSTR,ENUMRESLANGPROCA,LONG_PTR); +BOOL WINAPI EnumResourceLanguagesW(HMODULE,LPCWSTR,LPCWSTR,ENUMRESLANGPROCW,LONG_PTR); #define EnumResourceLanguages WINELIB_NAME_AW(EnumResourceLanguages) -BOOL WINAPI EnumResourceNamesA(HMODULE,LPCSTR,ENUMRESNAMEPROCA,LONG); -BOOL WINAPI EnumResourceNamesW(HMODULE,LPCWSTR,ENUMRESNAMEPROCW,LONG); +BOOL WINAPI EnumResourceNamesA(HMODULE,LPCSTR,ENUMRESNAMEPROCA,LONG_PTR); +BOOL WINAPI EnumResourceNamesW(HMODULE,LPCWSTR,ENUMRESNAMEPROCW,LONG_PTR); #define EnumResourceNames WINELIB_NAME_AW(EnumResourceNames) -BOOL WINAPI EnumResourceTypesA(HMODULE,ENUMRESTYPEPROCA,LONG); -BOOL WINAPI EnumResourceTypesW(HMODULE,ENUMRESTYPEPROCW,LONG); +BOOL WINAPI EnumResourceTypesA(HMODULE,ENUMRESTYPEPROCA,LONG_PTR); +BOOL WINAPI EnumResourceTypesW(HMODULE,ENUMRESTYPEPROCW,LONG_PTR); #define EnumResourceTypes WINELIB_NAME_AW(EnumResourceTypes) BOOL WINAPI EqualSid(PSID, PSID); BOOL WINAPI EqualPrefixSid(PSID,PSID); diff --git a/include/winternl.h b/include/winternl.h index 5feb5b2bf64..876ed13faa2 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -842,7 +842,7 @@ void WINAPI DbgUserBreakPoint(void); void WINAPIV DbgPrint(LPCSTR fmt, ...); NTSTATUS WINAPI LdrAccessResource(HMODULE,const IMAGE_RESOURCE_DATA_ENTRY*,void**,PULONG); -NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DIRECTORY_ENTRY**); +NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DIRECTORY**); NTSTATUS WINAPI LdrFindResource_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DATA_ENTRY**); NTSTATUS WINAPI NtAccessCheck(PSECURITY_DESCRIPTOR,HANDLE,ACCESS_MASK,PGENERIC_MAPPING,PPRIVILEGE_SET,PULONG,PULONG,PBOOLEAN); NTSTATUS WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD); diff --git a/loader/pe_resource.c b/loader/pe_resource.c deleted file mode 100644 index e530d9a3f66..00000000000 --- a/loader/pe_resource.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * PE (Portable Execute) File Resources - * - * Copyright 1995 Thomas Sandford - * Copyright 1996 Martin von Loewis - * - * Based on the Win16 resource handling code in loader/resource.c - * Copyright 1993 Robert J. Amstadt - * Copyright 1995 Alexandre Julliard - * Copyright 1997 Marcus Meissner - * - * 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 -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT -#include "wine/unicode.h" -#include "windef.h" -#include "winnls.h" -#include "winternl.h" -#include "winerror.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(resource); - - -/********************************************************************** - * get_resdir - * - * Get the resource directory of a PE module - */ -static const IMAGE_RESOURCE_DIRECTORY* get_resdir( HMODULE hmod ) -{ - DWORD size; - - if (!hmod) hmod = GetModuleHandleA( NULL ); - else if (!HIWORD(hmod)) - { - FIXME("Enumeration of 16-bit resources is not supported\n"); - SetLastError(ERROR_INVALID_HANDLE); - return NULL; - } - return RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size ); -} - - -/********************************************************************** - * find_entry_by_id - * - * Find an entry by id in a resource directory - */ -static const IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( const IMAGE_RESOURCE_DIRECTORY *dir, - WORD id, const void *root ) -{ - const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry; - int min, max, pos; - - entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); - min = dir->NumberOfNamedEntries; - max = min + dir->NumberOfIdEntries - 1; - while (min <= max) - { - pos = (min + max) / 2; - if (entry[pos].u1.s2.Id == id) - return (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry[pos].u2.s3.OffsetToDirectory); - if (entry[pos].u1.s2.Id > id) max = pos - 1; - else min = pos + 1; - } - return NULL; -} - - -/********************************************************************** - * find_entry_by_nameW - * - * Find an entry by name in a resource directory - */ -static const IMAGE_RESOURCE_DIRECTORY *find_entry_by_nameW( const IMAGE_RESOURCE_DIRECTORY *dir, - LPCWSTR name, const void *root ) -{ - const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry; - const IMAGE_RESOURCE_DIR_STRING_U *str; - int min, max, res, pos, namelen; - - if (!HIWORD(name)) return find_entry_by_id( dir, LOWORD(name), root ); - if (name[0] == '#') - { - char buf[16]; - if (!WideCharToMultiByte( CP_ACP, 0, name+1, -1, buf, sizeof(buf), NULL, NULL )) - return NULL; - return find_entry_by_id( dir, atoi(buf), root ); - } - - entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); - namelen = strlenW(name); - min = 0; - max = dir->NumberOfNamedEntries - 1; - while (min <= max) - { - pos = (min + max) / 2; - str = (IMAGE_RESOURCE_DIR_STRING_U *)((char *)root + entry[pos].u1.s1.NameOffset); - res = strncmpiW( name, str->NameString, str->Length ); - if (!res && namelen == str->Length) - return (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry[pos].u2.s3.OffsetToDirectory); - if (res < 0) max = pos - 1; - else min = pos + 1; - } - return NULL; -} - - -/********************************************************************** - * find_entry_by_nameA - * - * Find an entry by name in a resource directory - */ -static const IMAGE_RESOURCE_DIRECTORY *find_entry_by_nameA( const IMAGE_RESOURCE_DIRECTORY *dir, - LPCSTR name, const void *root ) -{ - const IMAGE_RESOURCE_DIRECTORY *ret = NULL; - LPWSTR nameW; - INT len; - - if (!HIWORD(name)) return find_entry_by_id( dir, LOWORD(name), root ); - if (name[0] == '#') - { - return find_entry_by_id( dir, atoi(name+1), root ); - } - - len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 ); - if ((nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) - { - MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len ); - ret = find_entry_by_nameW( dir, nameW, root ); - HeapFree( GetProcessHeap(), 0, nameW ); - } - return ret; -} - - -/********************************************************************** - * EnumResourceTypesA (KERNEL32.@) - */ -BOOL WINAPI EnumResourceTypesA( HMODULE hmod, ENUMRESTYPEPROCA lpfun, LONG lparam) -{ - int i; - const IMAGE_RESOURCE_DIRECTORY *resdir = get_resdir(hmod); - const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; - BOOL ret; - - if (!resdir) return FALSE; - - et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1); - ret = FALSE; - for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { - LPSTR type; - - if (et[i].u1.s1.NameIsString) - { - PIMAGE_RESOURCE_DIR_STRING_U pResString = (PIMAGE_RESOURCE_DIR_STRING_U) ((LPBYTE) resdir + et[i].u1.s1.NameOffset); - DWORD len = WideCharToMultiByte( CP_ACP, 0, pResString->NameString, pResString->Length, - NULL, 0, NULL, NULL); - if (!(type = HeapAlloc(GetProcessHeap(), 0, len + 1))) - return FALSE; - WideCharToMultiByte( CP_ACP, 0, pResString->NameString, pResString->Length, - type, len, NULL, NULL); - type[len] = '\0'; - ret = lpfun(hmod,type,lparam); - HeapFree(GetProcessHeap(), 0, type); - } - else - { - type = (LPSTR)(int)et[i].u1.s2.Id; - ret = lpfun(hmod,type,lparam); - } - if (!ret) - break; - } - return ret; -} - - -/********************************************************************** - * EnumResourceTypesW (KERNEL32.@) - */ -BOOL WINAPI EnumResourceTypesW( HMODULE hmod, ENUMRESTYPEPROCW lpfun, LONG lparam) -{ - int i; - const IMAGE_RESOURCE_DIRECTORY *resdir = get_resdir(hmod); - const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; - BOOL ret; - - if (!resdir) return FALSE; - - et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1); - ret = FALSE; - for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { - LPWSTR type; - - if (et[i].u1.s1.NameIsString) - { - PIMAGE_RESOURCE_DIR_STRING_U pResString = (PIMAGE_RESOURCE_DIR_STRING_U) ((LPBYTE) resdir + et[i].u1.s1.NameOffset); - if (!(type = HeapAlloc(GetProcessHeap(), 0, (pResString->Length+1) * sizeof (WCHAR)))) - return FALSE; - memcpy(type, pResString->NameString, pResString->Length * sizeof (WCHAR)); - type[pResString->Length] = '\0'; - ret = lpfun(hmod,type,lparam); - HeapFree(GetProcessHeap(), 0, type); - } - else - { - type = (LPWSTR)(int)et[i].u1.s2.Id; - ret = lpfun(hmod,type,lparam); - } - if (!ret) - break; - } - return ret; -} - - -/********************************************************************** - * EnumResourceNamesA (KERNEL32.@) - */ -BOOL WINAPI EnumResourceNamesA( HMODULE hmod, LPCSTR type, ENUMRESNAMEPROCA lpfun, LONG lparam ) -{ - int i; - const IMAGE_RESOURCE_DIRECTORY *basedir = get_resdir(hmod); - const IMAGE_RESOURCE_DIRECTORY *resdir; - const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; - BOOL ret; - - if (!basedir) return FALSE; - - if (!(resdir = find_entry_by_nameA( basedir, type, basedir ))) return FALSE; - - et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1); - ret = FALSE; - for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { - LPSTR name; - - if (et[i].u1.s1.NameIsString) - { - PIMAGE_RESOURCE_DIR_STRING_U pResString = (PIMAGE_RESOURCE_DIR_STRING_U) ((LPBYTE) basedir + et[i].u1.s1.NameOffset); - DWORD len = WideCharToMultiByte(CP_ACP, 0, pResString->NameString, pResString->Length, - NULL, 0, NULL, NULL); - if (!(name = HeapAlloc(GetProcessHeap(), 0, len + 1 ))) - return FALSE; - WideCharToMultiByte( CP_ACP, 0, pResString->NameString, pResString->Length, - name, len, NULL, NULL ); - name[len] = '\0'; - ret = lpfun(hmod,type,name,lparam); - HeapFree( GetProcessHeap(), 0, name ); - } - else - { - name = (LPSTR)(int)et[i].u1.s2.Id; - ret = lpfun(hmod,type,name,lparam); - } - if (!ret) - break; - } - return ret; -} - - -/********************************************************************** - * EnumResourceNamesW (KERNEL32.@) - */ -BOOL WINAPI EnumResourceNamesW( HMODULE hmod, LPCWSTR type, ENUMRESNAMEPROCW lpfun, LONG lparam ) -{ - int i; - const IMAGE_RESOURCE_DIRECTORY *basedir = get_resdir(hmod); - const IMAGE_RESOURCE_DIRECTORY *resdir; - const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; - BOOL ret; - - if (!basedir) return FALSE; - - if (!(resdir = find_entry_by_nameW( basedir, type, basedir ))) return FALSE; - - et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1); - ret = FALSE; - for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { - LPWSTR name; - - if (et[i].u1.s1.NameIsString) - { - PIMAGE_RESOURCE_DIR_STRING_U pResString = (PIMAGE_RESOURCE_DIR_STRING_U) ((LPBYTE) basedir + et[i].u1.s1.NameOffset); - if (!(name = HeapAlloc(GetProcessHeap(), 0, (pResString->Length + 1) * sizeof (WCHAR)))) - return FALSE; - memcpy(name, pResString->NameString, pResString->Length * sizeof (WCHAR)); - name[pResString->Length] = '\0'; - ret = lpfun(hmod,type,name,lparam); - HeapFree(GetProcessHeap(), 0, name); - } - else - { - name = (LPWSTR)(int)et[i].u1.s2.Id; - ret = lpfun(hmod,type,name,lparam); - } - if (!ret) - break; - } - return ret; -} - - -/********************************************************************** - * EnumResourceLanguagesA (KERNEL32.@) - */ -BOOL WINAPI EnumResourceLanguagesA( HMODULE hmod, LPCSTR type, LPCSTR name, - ENUMRESLANGPROCA lpfun, LONG lparam ) -{ - int i; - const IMAGE_RESOURCE_DIRECTORY *basedir = get_resdir(hmod); - const IMAGE_RESOURCE_DIRECTORY *resdir; - const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; - BOOL ret; - - if (!basedir) return FALSE; - if (!(resdir = find_entry_by_nameA( basedir, type, basedir ))) return FALSE; - if (!(resdir = find_entry_by_nameA( resdir, name, basedir ))) return FALSE; - - et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1); - ret = FALSE; - for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { - /* languages are just ids... I hope */ - ret = lpfun(hmod,type,name,et[i].u1.s2.Id,lparam); - if (!ret) - break; - } - return ret; -} - - -/********************************************************************** - * EnumResourceLanguagesW (KERNEL32.@) - */ -BOOL WINAPI EnumResourceLanguagesW( HMODULE hmod, LPCWSTR type, LPCWSTR name, - ENUMRESLANGPROCW lpfun, LONG lparam ) -{ - int i; - const IMAGE_RESOURCE_DIRECTORY *basedir = get_resdir(hmod); - const IMAGE_RESOURCE_DIRECTORY *resdir; - const IMAGE_RESOURCE_DIRECTORY_ENTRY *et; - BOOL ret; - - if (!basedir) return FALSE; - - if (!(resdir = find_entry_by_nameW( basedir, type, basedir ))) return FALSE; - if (!(resdir = find_entry_by_nameW( resdir, name, basedir ))) return FALSE; - - et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1); - ret = FALSE; - for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { - ret = lpfun(hmod,type,name,et[i].u1.s2.Id,lparam); - if (!ret) - break; - } - return ret; -}