From 5129c4598227f2d9e24abc8565d24d7874cfb27f Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 2 Jul 2019 15:16:42 +0200 Subject: [PATCH] kernel32: Move resource functions to kernelbase. Signed-off-by: Alexandre Julliard --- .../api-ms-win-core-libraryloader-l1-1-0.spec | 8 +- .../api-ms-win-core-libraryloader-l1-1-1.spec | 8 +- .../api-ms-win-core-libraryloader-l1-2-0.spec | 8 +- .../api-ms-win-core-libraryloader-l1-2-1.spec | 8 +- dlls/kernel32/kernel32.spec | 26 +- dlls/kernel32/resource.c | 502 +-------------- dlls/kernelbase/Makefile.in | 1 + dlls/kernelbase/kernelbase.spec | 26 +- dlls/kernelbase/loader.c | 579 ++++++++++++++++++ include/winbase.h | 6 + 10 files changed, 644 insertions(+), 528 deletions(-) create mode 100644 dlls/kernelbase/loader.c diff --git a/dlls/api-ms-win-core-libraryloader-l1-1-0/api-ms-win-core-libraryloader-l1-1-0.spec b/dlls/api-ms-win-core-libraryloader-l1-1-0/api-ms-win-core-libraryloader-l1-1-0.spec index a011bee54f1..de2dd284685 100644 --- a/dlls/api-ms-win-core-libraryloader-l1-1-0/api-ms-win-core-libraryloader-l1-1-0.spec +++ b/dlls/api-ms-win-core-libraryloader-l1-1-0/api-ms-win-core-libraryloader-l1-1-0.spec @@ -2,10 +2,10 @@ @ stdcall DisableThreadLibraryCalls(long) kernel32.DisableThreadLibraryCalls @ stdcall EnumResourceLanguagesExA(long str str ptr long long long) kernel32.EnumResourceLanguagesExA @ stdcall EnumResourceLanguagesExW(long wstr wstr ptr long long long) kernel32.EnumResourceLanguagesExW -@ stub EnumResourceNamesExA -@ stub EnumResourceNamesExW -@ stub EnumResourceTypesExA -@ stub EnumResourceTypesExW +@ stdcall EnumResourceNamesExA(long str ptr long long long) kernel32.EnumResourceNamesExA +@ stdcall EnumResourceNamesExW(long wstr ptr long long long) kernel32.EnumResourceNamesExW +@ stdcall EnumResourceTypesExA(long ptr long long long) kernel32.EnumResourceTypesExA +@ stdcall EnumResourceTypesExW(long ptr long long long) kernel32.EnumResourceTypesExW @ stdcall FindResourceExW(long wstr wstr long) kernel32.FindResourceExW @ stdcall FindStringOrdinal(long wstr long wstr long long) kernel32.FindStringOrdinal @ stdcall FreeLibrary(long) kernel32.FreeLibrary diff --git a/dlls/api-ms-win-core-libraryloader-l1-1-1/api-ms-win-core-libraryloader-l1-1-1.spec b/dlls/api-ms-win-core-libraryloader-l1-1-1/api-ms-win-core-libraryloader-l1-1-1.spec index eea8f235c86..b0831613440 100644 --- a/dlls/api-ms-win-core-libraryloader-l1-1-1/api-ms-win-core-libraryloader-l1-1-1.spec +++ b/dlls/api-ms-win-core-libraryloader-l1-1-1/api-ms-win-core-libraryloader-l1-1-1.spec @@ -2,10 +2,10 @@ @ stdcall DisableThreadLibraryCalls(long) kernel32.DisableThreadLibraryCalls @ stdcall EnumResourceLanguagesExA(long str str ptr long long long) kernel32.EnumResourceLanguagesExA @ stdcall EnumResourceLanguagesExW(long wstr wstr ptr long long long) kernel32.EnumResourceLanguagesExW -@ stub EnumResourceNamesExA -@ stub EnumResourceNamesExW -@ stub EnumResourceTypesExA -@ stub EnumResourceTypesExW +@ stdcall EnumResourceNamesExA(long str ptr long long long) kernel32.EnumResourceNamesExA +@ stdcall EnumResourceNamesExW(long wstr ptr long long long) kernel32.EnumResourceNamesExW +@ stdcall EnumResourceTypesExA(long ptr long long long) kernel32.EnumResourceTypesExA +@ stdcall EnumResourceTypesExW(long ptr long long long) kernel32.EnumResourceTypesExW @ stdcall FindResourceExW(long wstr wstr long) kernel32.FindResourceExW @ stdcall FindStringOrdinal(long wstr long wstr long long) kernel32.FindStringOrdinal @ stdcall FreeLibrary(long) kernel32.FreeLibrary diff --git a/dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec b/dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec index a011bee54f1..de2dd284685 100644 --- a/dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec +++ b/dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec @@ -2,10 +2,10 @@ @ stdcall DisableThreadLibraryCalls(long) kernel32.DisableThreadLibraryCalls @ stdcall EnumResourceLanguagesExA(long str str ptr long long long) kernel32.EnumResourceLanguagesExA @ stdcall EnumResourceLanguagesExW(long wstr wstr ptr long long long) kernel32.EnumResourceLanguagesExW -@ stub EnumResourceNamesExA -@ stub EnumResourceNamesExW -@ stub EnumResourceTypesExA -@ stub EnumResourceTypesExW +@ stdcall EnumResourceNamesExA(long str ptr long long long) kernel32.EnumResourceNamesExA +@ stdcall EnumResourceNamesExW(long wstr ptr long long long) kernel32.EnumResourceNamesExW +@ stdcall EnumResourceTypesExA(long ptr long long long) kernel32.EnumResourceTypesExA +@ stdcall EnumResourceTypesExW(long ptr long long long) kernel32.EnumResourceTypesExW @ stdcall FindResourceExW(long wstr wstr long) kernel32.FindResourceExW @ stdcall FindStringOrdinal(long wstr long wstr long long) kernel32.FindStringOrdinal @ stdcall FreeLibrary(long) kernel32.FreeLibrary diff --git a/dlls/api-ms-win-core-libraryloader-l1-2-1/api-ms-win-core-libraryloader-l1-2-1.spec b/dlls/api-ms-win-core-libraryloader-l1-2-1/api-ms-win-core-libraryloader-l1-2-1.spec index 5e2842196f3..42bba4d3ab8 100644 --- a/dlls/api-ms-win-core-libraryloader-l1-2-1/api-ms-win-core-libraryloader-l1-2-1.spec +++ b/dlls/api-ms-win-core-libraryloader-l1-2-1/api-ms-win-core-libraryloader-l1-2-1.spec @@ -2,10 +2,10 @@ @ stdcall DisableThreadLibraryCalls(long) kernel32.DisableThreadLibraryCalls @ stdcall EnumResourceLanguagesExA(long str str ptr long long long) kernel32.EnumResourceLanguagesExA @ stdcall EnumResourceLanguagesExW(long wstr wstr ptr long long long) kernel32.EnumResourceLanguagesExW -@ stub EnumResourceNamesExA -@ stub EnumResourceNamesExW -@ stub EnumResourceTypesExA -@ stub EnumResourceTypesExW +@ stdcall EnumResourceNamesExA(long str ptr long long long) kernel32.EnumResourceNamesExA +@ stdcall EnumResourceNamesExW(long wstr ptr long long long) kernel32.EnumResourceNamesExW +@ stdcall EnumResourceTypesExA(long ptr long long long) kernel32.EnumResourceTypesExA +@ stdcall EnumResourceTypesExW(long ptr long long long) kernel32.EnumResourceTypesExW @ stdcall FindResourceExW(long wstr wstr long) kernel32.FindResourceExW @ stdcall FindResourceW(long wstr wstr) kernel32.FindResourceW @ stdcall FindStringOrdinal(long wstr long wstr long long) kernel32.FindStringOrdinal diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 416cdf39399..2a53898aa7f 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -405,16 +405,16 @@ @ stdcall EnumLanguageGroupLocalesA(ptr long long ptr) @ stdcall EnumLanguageGroupLocalesW(ptr long long ptr) @ stdcall EnumResourceLanguagesA(long str str ptr long) -@ stdcall EnumResourceLanguagesExA(long str str ptr long long long) -@ stdcall EnumResourceLanguagesExW(long wstr wstr ptr long long long) +@ stdcall -import EnumResourceLanguagesExA(long str str ptr long long long) +@ stdcall -import EnumResourceLanguagesExW(long wstr wstr ptr long long long) @ stdcall EnumResourceLanguagesW(long wstr wstr ptr long) @ stdcall EnumResourceNamesA(long str ptr long) -# @ stub EnumResourceNamesExA -# @ stub EnumResourceNamesExW -@ stdcall EnumResourceNamesW(long wstr ptr long) +@ stdcall -import EnumResourceNamesExA(long str ptr long long long) +@ stdcall -import EnumResourceNamesExW(long wstr ptr long long long) +@ stdcall -import EnumResourceNamesW(long wstr ptr long) @ stdcall EnumResourceTypesA(long ptr long) -# @ stub EnumResourceTypesExA -# @ stub EnumResourceTypesExW +@ stdcall -import EnumResourceTypesExA(long ptr long long long) +@ stdcall -import EnumResourceTypesExW(long ptr long long long) @ stdcall EnumResourceTypesW(long ptr long) @ stdcall EnumSystemCodePagesA(ptr long) @ stdcall EnumSystemCodePagesW(ptr long) @@ -506,8 +506,8 @@ @ stdcall FindNLSStringEx(wstr long wstr long wstr long ptr ptr ptr long) @ stdcall FindResourceA(long str str) @ stdcall FindResourceExA(long str str long) -@ stdcall FindResourceExW(long wstr wstr long) -@ stdcall FindResourceW(long wstr wstr) +@ stdcall -import FindResourceExW(long wstr wstr long) +@ stdcall -import FindResourceW(long wstr wstr) @ stdcall FindStringOrdinal(long wstr long wstr long long) @ stdcall FindVolumeClose(ptr) @ stdcall FindVolumeMountPointClose(ptr) @@ -531,7 +531,7 @@ @ stdcall FreeLibrary(long) @ stdcall FreeLibraryAndExitThread(long long) @ stdcall FreeLibraryWhenCallbackReturns(ptr ptr) ntdll.TpCallbackUnloadDllOnCompletion -@ stdcall FreeResource(long) +@ stdcall -import FreeResource(long) @ stdcall -i386 -private FreeSLCallback(long) krnl386.exe16.FreeSLCallback @ stdcall FreeUserPhysicalPages(long ptr ptr) @ stub FreeVirtualBuffer @@ -1047,7 +1047,7 @@ @ stdcall LoadLibraryExW(wstr long long) @ stdcall LoadLibraryW(wstr) @ stdcall LoadModule(str ptr) -@ stdcall LoadResource(long long) +@ stdcall -import LoadResource(long long) # @ stub LoadStringBaseExW # @ stub LoadStringBaseW @ stdcall LocalAlloc(long long) @@ -1065,7 +1065,7 @@ # @ stub LocateXStateFeature @ stdcall LockFile(long long long long long) @ stdcall LockFileEx(long long long long long ptr) -@ stdcall LockResource(long) +@ stdcall -import LockResource(long) @ stdcall MakeCriticalSectionGlobal(ptr) @ stdcall -i386 -private -norelay MapHInstLS() krnl386.exe16.MapHInstLS @ stdcall -i386 -private -norelay MapHInstLS_PN() krnl386.exe16.MapHInstLS_PN @@ -1480,7 +1480,7 @@ @ stdcall SetupComm(long long long) @ stub ShowConsoleCursor @ stdcall -import SignalObjectAndWait(long long long long) -@ stdcall SizeofResource(long long) +@ stdcall -import SizeofResource(long long) @ stdcall -import Sleep(long) @ stdcall -import SleepConditionVariableCS(ptr ptr long) @ stdcall -import SleepConditionVariableSRW(ptr ptr long long) diff --git a/dlls/kernel32/resource.c b/dlls/kernel32/resource.c index 5c9383d4195..b81ab3de5aa 100644 --- a/dlls/kernel32/resource.c +++ b/dlls/kernel32/resource.c @@ -59,53 +59,31 @@ static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str ) 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 (IS_INTRESOURCE(name)) - { - str->Buffer = ULongToPtr(LOWORD(name)); - return STATUS_SUCCESS; - } - if (name[0] == '#') - { - ULONG value; - RtlInitUnicodeString( str, name + 1 ); - if (RtlUnicodeStringToInteger( str, 10, &value ) != STATUS_SUCCESS || HIWORD(value)) - return STATUS_INVALID_PARAMETER; - str->Buffer = ULongToPtr(value); - return STATUS_SUCCESS; - } - RtlCreateUnicodeString( str, name ); - RtlUpcaseUnicodeString( str, str, FALSE ); - return STATUS_SUCCESS; -} -/* implementation of FindResourceExA */ -static HRSRC find_resourceA( HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang ) +/********************************************************************** + * FindResourceExA (KERNEL32.@) + */ +HRSRC WINAPI FindResourceExA( HMODULE module, LPCSTR type, LPCSTR name, WORD lang ) { NTSTATUS status; UNICODE_STRING nameW, typeW; - LDR_RESOURCE_INFO info; - const IMAGE_RESOURCE_DATA_ENTRY *entry = NULL; + HRSRC ret = NULL; + TRACE( "%p %s %s %04x\n", module, debugstr_a(type), debugstr_a(name), lang ); + + if (!module) module = GetModuleHandleW(0); nameW.Buffer = NULL; typeW.Buffer = 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_PTR)typeW.Buffer; - info.Name = (ULONG_PTR)nameW.Buffer; - info.Language = lang; - status = LdrFindResource_U( hModule, &info, 3, &entry ); - done: - if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + if (!(status = get_res_nameA( name, &nameW )) && !(status = get_res_nameA( type, &typeW ))) + ret = FindResourceExW( module, typeW.Buffer, nameW.Buffer, lang ); + else + SetLastError( RtlNtStatusToDosError(status) ); } __EXCEPT_PAGE_FAULT { @@ -115,51 +93,7 @@ static HRSRC find_resourceA( HMODULE hModule, LPCSTR type, LPCSTR name, WORD lan if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); if (!IS_INTRESOURCE(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_PTR)typeW.Buffer; - info.Name = (ULONG_PTR)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 (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); - if (!IS_INTRESOURCE(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); - return find_resourceA( hModule, type, name, lang ); + return ret; } @@ -172,75 +106,12 @@ HRSRC WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) } -/********************************************************************** - * FindResourceExW (KERNEL32.@) - */ -HRSRC WINAPI FindResourceExW( HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang ) -{ - TRACE( "%p %s %s %04x\n", hModule, debugstr_w(type), debugstr_w(name), lang ); - - if (!hModule) hModule = GetModuleHandleW(0); - return find_resourceW( hModule, type, name, lang ); -} - - -/********************************************************************** - * FindResourceW (KERNEL32.@) - */ -HRSRC WINAPI FindResourceW( HINSTANCE hModule, LPCWSTR name, LPCWSTR type ) -{ - return FindResourceExW( hModule, type, name, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) ); -} - - /********************************************************************** * 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 = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); - for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++) - { - if (et[i].u.s.NameIsString) - { - str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].u.s.NameOffset); - newlen = WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL); - if (newlen + 1 > len) - { - len = newlen + 1; - 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, UIntToPtr(et[i].u.Id), lparam ); - } - if (!ret) break; - } - HeapFree( GetProcessHeap(), 0, type ); - return ret; + return EnumResourceTypesExA( hmod, lpfun, lparam, 0, 0 ); } @@ -249,47 +120,7 @@ BOOL WINAPI EnumResourceTypesA( HMODULE hmod, ENUMRESTYPEPROCA lpfun, LONG_PTR l */ BOOL WINAPI EnumResourceTypesW( HMODULE hmod, ENUMRESTYPEPROCW lpfun, LONG_PTR lparam ) { - int i, len = 0; - BOOL ret = FALSE; - 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 = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); - for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++) - { - if (et[i].u.s.NameIsString) - { - str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].u.s.NameOffset); - if (str->Length + 1 > len) - { - len = str->Length + 1; - 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, UIntToPtr(et[i].u.Id), lparam ); - } - if (!ret) break; - } - HeapFree( GetProcessHeap(), 0, type ); - return ret; + return EnumResourceTypesExW( hmod, lpfun, lparam, 0, 0 ); } @@ -298,202 +129,7 @@ BOOL WINAPI EnumResourceTypesW( HMODULE hmod, ENUMRESTYPEPROCW lpfun, LONG_PTR l */ 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_PTR)typeW.Buffer; - if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS) - goto done; - - et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); - __TRY - { - for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++) - { - if (et[i].u.s.NameIsString) - { - str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u.s.NameOffset); - newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL); - if (newlen + 1 > len) - { - len = newlen + 1; - 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, UIntToPtr(et[i].u.Id), lparam ); - } - if (!ret) break; - } - } - __EXCEPT_PAGE_FAULT - { - ret = FALSE; - status = STATUS_ACCESS_VIOLATION; - } - __ENDTRY - -done: - HeapFree( GetProcessHeap(), 0, name ); - if (!IS_INTRESOURCE(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, len = 0; - BOOL ret = FALSE; - LPWSTR 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_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_PTR)typeW.Buffer; - if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS) - goto done; - - et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); - __TRY - { - for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++) - { - if (et[i].u.s.NameIsString) - { - str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u.s.NameOffset); - if (str->Length + 1 > len) - { - len = str->Length + 1; - 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, UIntToPtr(et[i].u.Id), lparam ); - } - if (!ret) break; - } - } - __EXCEPT_PAGE_FAULT - { - ret = FALSE; - status = STATUS_ACCESS_VIOLATION; - } - __ENDTRY -done: - HeapFree( GetProcessHeap(), 0, name ); - if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); - if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); - return ret; -} - - -/********************************************************************** - * EnumResourceLanguagesExA (KERNEL32.@) - */ -BOOL WINAPI EnumResourceLanguagesExA( HMODULE hmod, LPCSTR type, LPCSTR name, - ENUMRESLANGPROCA lpfun, LONG_PTR lparam, - DWORD flags, LANGID lang ) -{ - 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 %x %d\n", hmod, debugstr_a(type), debugstr_a(name), - lpfun, lparam, flags, lang ); - - if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE)) - FIXME( "unimplemented flags: %x\n", flags ); - - if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI; - - if (!(flags & RESOURCE_ENUM_LN)) return ret; - - 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_PTR)typeW.Buffer; - info.Name = (ULONG_PTR)nameW.Buffer; - if ((status = LdrFindResourceDirectory_U( hmod, &info, 2, &resdir )) != STATUS_SUCCESS) - goto done; - - et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); - __TRY - { - for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++) - { - ret = lpfun( hmod, type, name, et[i].u.Id, lparam ); - if (!ret) break; - } - } - __EXCEPT_PAGE_FAULT - { - ret = FALSE; - status = STATUS_ACCESS_VIOLATION; - } - __ENDTRY -done: - if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); - if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); - if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); - return ret; + return EnumResourceNamesExA( hmod, type, lpfun, lparam, 0, 0 ); } @@ -507,67 +143,6 @@ BOOL WINAPI EnumResourceLanguagesA( HMODULE hmod, LPCSTR type, LPCSTR name, } -/********************************************************************** - * EnumResourceLanguagesExW (KERNEL32.@) - */ -BOOL WINAPI EnumResourceLanguagesExW( HMODULE hmod, LPCWSTR type, LPCWSTR name, - ENUMRESLANGPROCW lpfun, LONG_PTR lparam, - DWORD flags, LANGID lang ) -{ - 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 %x %d\n", hmod, debugstr_w(type), debugstr_w(name), - lpfun, lparam, flags, lang ); - - if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE)) - FIXME( "unimplemented flags: %x\n", flags ); - - if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI; - - if (!(flags & RESOURCE_ENUM_LN)) return ret; - - 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_PTR)typeW.Buffer; - info.Name = (ULONG_PTR)nameW.Buffer; - if ((status = LdrFindResourceDirectory_U( hmod, &info, 2, &resdir )) != STATUS_SUCCESS) - goto done; - - et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); - __TRY - { - for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++) - { - ret = lpfun( hmod, type, name, et[i].u.Id, lparam ); - if (!ret) break; - } - } - __EXCEPT_PAGE_FAULT - { - ret = FALSE; - status = STATUS_ACCESS_VIOLATION; - } - __ENDTRY -done: - if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); - if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); - if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); - return ret; -} - - /********************************************************************** * EnumResourceLanguagesW (KERNEL32.@) */ @@ -578,51 +153,6 @@ BOOL WINAPI EnumResourceLanguagesW( HMODULE hmod, LPCWSTR type, LPCWSTR name, } -/********************************************************************** - * LoadResource (KERNEL32.@) - */ -HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc ) -{ - NTSTATUS status; - void *ret = NULL; - - TRACE( "%p %p\n", hModule, 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 ) -{ - return handle; -} - - -/********************************************************************** - * FreeResource (KERNEL32.@) - */ -BOOL WINAPI FreeResource( HGLOBAL handle ) -{ - return FALSE; -} - - -/********************************************************************** - * SizeofResource (KERNEL32.@) - */ -DWORD WINAPI DECLSPEC_HOTPATCH SizeofResource( HINSTANCE hModule, HRSRC hRsrc ) -{ - if (!hRsrc) return 0; - return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size; -} - /* * Data structure for updating resources. * Type/Name/Language is a keyset for accessing resource data. diff --git a/dlls/kernelbase/Makefile.in b/dlls/kernelbase/Makefile.in index ebc7bafc873..5a21294f3c7 100644 --- a/dlls/kernelbase/Makefile.in +++ b/dlls/kernelbase/Makefile.in @@ -4,6 +4,7 @@ IMPORTS = uuid ntdll winecrt0 kernel32 EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -mno-cygwin C_SRCS = \ + loader.c \ main.c \ path.c \ registry.c \ diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index a41fcd13592..6219eb3097d 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -304,13 +304,13 @@ # @ stub EnumProcessModules # @ stub EnumProcessModulesEx # @ stub EnumProcesses -@ stdcall EnumResourceLanguagesExA(long str str ptr long long long) kernel32.EnumResourceLanguagesExA -@ stdcall EnumResourceLanguagesExW(long wstr wstr ptr long long long) kernel32.EnumResourceLanguagesExW -# @ stub EnumResourceNamesExA -# @ stub EnumResourceNamesExW -@ stdcall EnumResourceNamesW(long wstr ptr long) kernel32.EnumResourceNamesW -# @ stub EnumResourceTypesExA -# @ stub EnumResourceTypesExW +@ stdcall EnumResourceLanguagesExA(long str str ptr long long long) +@ stdcall EnumResourceLanguagesExW(long wstr wstr ptr long long long) +@ stdcall EnumResourceNamesExA(long str ptr long long long) +@ stdcall EnumResourceNamesExW(long wstr ptr long long long) +@ stdcall EnumResourceNamesW(long wstr ptr long) +@ stdcall EnumResourceTypesExA(long ptr long long long) +@ stdcall EnumResourceTypesExW(long ptr long long long) @ stdcall EnumSystemCodePagesW(ptr long) kernel32.EnumSystemCodePagesW # @ stub EnumSystemFirmwareTables @ stdcall EnumSystemGeoID(long long ptr) kernel32.EnumSystemGeoID @@ -371,8 +371,8 @@ @ stdcall FindNextStreamW(long ptr) kernel32.FindNextStreamW @ stdcall FindNextVolumeW(long ptr long) kernel32.FindNextVolumeW # @ stub FindPackagesByPackageFamily -@ stdcall FindResourceExW(long wstr wstr long) kernel32.FindResourceExW -@ stdcall FindResourceW(long wstr wstr) kernel32.FindResourceW +@ stdcall FindResourceExW(long wstr wstr long) +@ stdcall FindResourceW(long wstr wstr) @ stdcall FindStringOrdinal(long wstr long wstr long long) kernel32.FindStringOrdinal @ stdcall FindVolumeClose(ptr) kernel32.FindVolumeClose @ stdcall FlsAlloc(ptr) kernel32.FlsAlloc @@ -397,7 +397,7 @@ @ stdcall FreeLibrary(long) kernel32.FreeLibrary @ stdcall FreeLibraryAndExitThread(long long) kernel32.FreeLibraryAndExitThread @ stdcall FreeLibraryWhenCallbackReturns(ptr ptr) ntdll.TpCallbackUnloadDllOnCompletion -@ stdcall FreeResource(long) kernel32.FreeResource +@ stdcall FreeResource(long) @ stdcall FreeSid(ptr) @ stdcall FreeUserPhysicalPages(long ptr ptr) kernel32.FreeUserPhysicalPages @ stdcall GenerateConsoleCtrlEvent(long long) kernel32.GenerateConsoleCtrlEvent @@ -928,7 +928,7 @@ @ stdcall LoadLibraryExW(wstr long long) kernel32.LoadLibraryExW @ stdcall LoadLibraryW(wstr) kernel32.LoadLibraryW # @ stub LoadPackagedLibrary -@ stdcall LoadResource(long long) kernel32.LoadResource +@ stdcall LoadResource(long long) @ stdcall LoadStringA(long long ptr long) @ stub LoadStringBaseExW @ stub LoadStringByReference @@ -943,7 +943,7 @@ # @ stub LocateXStateFeature @ stdcall LockFile(long long long long long) kernel32.LockFile @ stdcall LockFileEx(long long long long long ptr) kernel32.LockFileEx -@ stdcall LockResource(long) kernel32.LockResource +@ stdcall LockResource(long) @ stdcall MakeAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) @ stub MakeAbsoluteSD2 @ stdcall MakeSelfRelativeSD(ptr ptr ptr) @@ -1510,7 +1510,7 @@ @ stdcall SetupComm(long long long) kernel32.SetupComm # @ stub SharedLocalIsEnabled @ stdcall SignalObjectAndWait(long long long long) -@ stdcall SizeofResource(long long) kernel32.SizeofResource +@ stdcall SizeofResource(long long) @ stdcall Sleep(long) @ stdcall SleepConditionVariableCS(ptr ptr long) @ stdcall SleepConditionVariableSRW(ptr ptr long long) diff --git a/dlls/kernelbase/loader.c b/dlls/kernelbase/loader.c new file mode 100644 index 00000000000..73cce4b5527 --- /dev/null +++ b/dlls/kernelbase/loader.c @@ -0,0 +1,579 @@ +/* + * Module loader + * + * Copyright 1993 Robert J. Amstadt + * Copyright 2006 Mike McCormack + * Copyright 1995, 2003, 2019 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winternl.h" +#include "kernelbase.h" +#include "wine/debug.h" +#include "wine/exception.h" + +WINE_DEFAULT_DEBUG_CHANNEL(module); + + +/*********************************************************************** + * Resources + ***********************************************************************/ + + +#define IS_INTRESOURCE(x) (((ULONG_PTR)(x) >> 16) == 0) + +/* retrieve the resource name to pass to the ntdll functions */ +static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str ) +{ + if (IS_INTRESOURCE(name)) + { + str->Buffer = ULongToPtr( LOWORD(name) ); + return STATUS_SUCCESS; + } + if (name[0] == '#') + { + ULONG value; + if (RtlCharToInteger( name + 1, 10, &value ) != STATUS_SUCCESS || HIWORD(value)) + return STATUS_INVALID_PARAMETER; + str->Buffer = ULongToPtr(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 (IS_INTRESOURCE(name)) + { + str->Buffer = ULongToPtr( LOWORD(name) ); + return STATUS_SUCCESS; + } + if (name[0] == '#') + { + ULONG value; + RtlInitUnicodeString( str, name + 1 ); + if (RtlUnicodeStringToInteger( str, 10, &value ) != STATUS_SUCCESS || HIWORD(value)) + return STATUS_INVALID_PARAMETER; + str->Buffer = ULongToPtr(value); + return STATUS_SUCCESS; + } + RtlCreateUnicodeString( str, name ); + RtlUpcaseUnicodeString( str, str, FALSE ); + return STATUS_SUCCESS; +} + + +/********************************************************************** + * EnumResourceLanguagesExA (KERNEL32.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceLanguagesExA( HMODULE module, LPCSTR type, LPCSTR name, + ENUMRESLANGPROCA func, LONG_PTR param, + DWORD flags, LANGID lang ) +{ + 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 %x %d\n", module, debugstr_a(type), debugstr_a(name), + func, param, flags, lang ); + + if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE)) + FIXME( "unimplemented flags: %x\n", flags ); + + if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI; + if (!(flags & RESOURCE_ENUM_LN)) return ret; + + if (!module) module = GetModuleHandleW( 0 ); + typeW.Buffer = nameW.Buffer = NULL; + if ((status = LdrFindResourceDirectory_U( module, 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_PTR)typeW.Buffer; + info.Name = (ULONG_PTR)nameW.Buffer; + if ((status = LdrFindResourceDirectory_U( module, &info, 2, &resdir )) != STATUS_SUCCESS) + goto done; + + et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); + __TRY + { + for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++) + { + ret = func( module, type, name, et[i].u.Id, param ); + if (!ret) break; + } + } + __EXCEPT_PAGE_FAULT + { + ret = FALSE; + status = STATUS_ACCESS_VIOLATION; + } + __ENDTRY +done: + if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return ret; +} + + +/********************************************************************** + * EnumResourceLanguagesExW (KERNEL32.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceLanguagesExW( HMODULE module, LPCWSTR type, LPCWSTR name, + ENUMRESLANGPROCW func, LONG_PTR param, + DWORD flags, LANGID lang ) +{ + 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 %x %d\n", module, debugstr_w(type), debugstr_w(name), + func, param, flags, lang ); + + if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE)) + FIXME( "unimplemented flags: %x\n", flags ); + + if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI; + if (!(flags & RESOURCE_ENUM_LN)) return ret; + + if (!module) module = GetModuleHandleW( 0 ); + typeW.Buffer = nameW.Buffer = NULL; + if ((status = LdrFindResourceDirectory_U( module, 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_PTR)typeW.Buffer; + info.Name = (ULONG_PTR)nameW.Buffer; + if ((status = LdrFindResourceDirectory_U( module, &info, 2, &resdir )) != STATUS_SUCCESS) + goto done; + + et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); + __TRY + { + for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++) + { + ret = func( module, type, name, et[i].u.Id, param ); + if (!ret) break; + } + } + __EXCEPT_PAGE_FAULT + { + ret = FALSE; + status = STATUS_ACCESS_VIOLATION; + } + __ENDTRY +done: + if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return ret; +} + + +/********************************************************************** + * EnumResourceNamesExA (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesExA( HMODULE module, LPCSTR type, ENUMRESNAMEPROCA func, + LONG_PTR param, DWORD flags, LANGID lang ) +{ + 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", module, debugstr_a(type), func, param ); + + if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE)) + FIXME( "unimplemented flags: %x\n", flags ); + + if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI; + if (!(flags & RESOURCE_ENUM_LN)) return ret; + + if (!module) module = GetModuleHandleW( 0 ); + typeW.Buffer = NULL; + if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS) + goto done; + if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS) + goto done; + info.Type = (ULONG_PTR)typeW.Buffer; + if ((status = LdrFindResourceDirectory_U( module, &info, 1, &resdir )) != STATUS_SUCCESS) + goto done; + + et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); + __TRY + { + for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++) + { + if (et[i].u.s.NameIsString) + { + str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u.s.NameOffset); + newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL); + if (newlen + 1 > len) + { + len = newlen + 1; + 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 = func( module, type, name, param ); + } + else + { + ret = func( module, type, UIntToPtr(et[i].u.Id), param ); + } + if (!ret) break; + } + } + __EXCEPT_PAGE_FAULT + { + ret = FALSE; + status = STATUS_ACCESS_VIOLATION; + } + __ENDTRY + +done: + HeapFree( GetProcessHeap(), 0, name ); + if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return ret; +} + + +/********************************************************************** + * EnumResourceNamesExW (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesExW( HMODULE module, LPCWSTR type, ENUMRESNAMEPROCW func, + LONG_PTR param, DWORD flags, LANGID lang ) +{ + int i, len = 0; + BOOL ret = FALSE; + LPWSTR 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", module, debugstr_w(type), func, param ); + + if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE)) + FIXME( "unimplemented flags: %x\n", flags ); + + if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI; + if (!(flags & RESOURCE_ENUM_LN)) return ret; + + if (!module) module = GetModuleHandleW( 0 ); + typeW.Buffer = NULL; + if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &basedir )) != STATUS_SUCCESS) + goto done; + if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS) + goto done; + info.Type = (ULONG_PTR)typeW.Buffer; + if ((status = LdrFindResourceDirectory_U( module, &info, 1, &resdir )) != STATUS_SUCCESS) + goto done; + + et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); + __TRY + { + for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++) + { + if (et[i].u.s.NameIsString) + { + str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u.s.NameOffset); + if (str->Length + 1 > len) + { + len = str->Length + 1; + 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 = func( module, type, name, param ); + } + else + { + ret = func( module, type, UIntToPtr(et[i].u.Id), param ); + } + if (!ret) break; + } + } + __EXCEPT_PAGE_FAULT + { + ret = FALSE; + status = STATUS_ACCESS_VIOLATION; + } + __ENDTRY +done: + HeapFree( GetProcessHeap(), 0, name ); + if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return ret; +} + + +/********************************************************************** + * EnumResourceNamesW (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceNamesW( HMODULE module, LPCWSTR type, + ENUMRESNAMEPROCW func, LONG_PTR param ) +{ + return EnumResourceNamesExW( module, type, func, param, 0, 0 ); +} + + +/********************************************************************** + * EnumResourceTypesExA (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceTypesExA( HMODULE module, ENUMRESTYPEPROCA func, LONG_PTR param, + DWORD flags, LANGID lang ) +{ + 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", module, func, param ); + + if (flags & (RESOURCE_ENUM_MUI | RESOURCE_ENUM_MUI_SYSTEM | RESOURCE_ENUM_VALIDATE)) + FIXME( "unimplemented flags: %x\n", flags ); + + if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI; + if (!(flags & RESOURCE_ENUM_LN)) return ret; + + if (!module) module = GetModuleHandleW( 0 ); + + if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &resdir )) != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); + for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++) + { + if (et[i].u.s.NameIsString) + { + str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].u.s.NameOffset); + newlen = WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL); + if (newlen + 1 > len) + { + len = newlen + 1; + 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 = func( module, type, param ); + } + else + { + ret = func( module, UIntToPtr(et[i].u.Id), param ); + } + if (!ret) break; + } + HeapFree( GetProcessHeap(), 0, type ); + return ret; +} + + +/********************************************************************** + * EnumResourceTypesExW (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceTypesExW( HMODULE module, ENUMRESTYPEPROCW func, LONG_PTR param, + DWORD flags, LANGID lang ) +{ + int i, len = 0; + BOOL ret = FALSE; + 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", module, func, param ); + + if (!flags) flags = RESOURCE_ENUM_LN | RESOURCE_ENUM_MUI; + if (!(flags & RESOURCE_ENUM_LN)) return ret; + + if (!module) module = GetModuleHandleW( 0 ); + + if ((status = LdrFindResourceDirectory_U( module, NULL, 0, &resdir )) != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); + for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++) + { + if (et[i].u.s.NameIsString) + { + str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].u.s.NameOffset); + if (str->Length + 1 > len) + { + len = str->Length + 1; + 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 = func( module, type, param ); + } + else + { + ret = func( module, UIntToPtr(et[i].u.Id), param ); + } + if (!ret) break; + } + HeapFree( GetProcessHeap(), 0, type ); + return ret; +} + + +/********************************************************************** + * FindResourceExW (kernelbase.@) + */ +HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceExW( HMODULE module, 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", module, debugstr_w(type), debugstr_w(name), lang ); + + if (!module) module = GetModuleHandleW( 0 ); + 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_PTR)typeW.Buffer; + info.Name = (ULONG_PTR)nameW.Buffer; + info.Language = lang; + status = LdrFindResource_U( module, &info, 3, &entry ); + done: + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + } + __EXCEPT_PAGE_FAULT + { + SetLastError( ERROR_INVALID_PARAMETER ); + } + __ENDTRY + + if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); + if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); + return (HRSRC)entry; +} + + +/********************************************************************** + * FindResourceW (kernelbase.@) + */ +HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceW( HINSTANCE module, LPCWSTR name, LPCWSTR type ) +{ + return FindResourceExW( module, type, name, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) ); +} + + +/********************************************************************** + * FreeResource (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH FreeResource( HGLOBAL handle ) +{ + return FALSE; +} + + +/********************************************************************** + * LoadResource (kernelbase.@) + */ +HGLOBAL WINAPI DECLSPEC_HOTPATCH LoadResource( HINSTANCE module, HRSRC rsrc ) +{ + NTSTATUS status; + void *ret = NULL; + + TRACE( "%p %p\n", module, rsrc ); + + if (!rsrc) return 0; + if (!module) module = GetModuleHandleW( 0 ); + status = LdrAccessResource( module, (IMAGE_RESOURCE_DATA_ENTRY *)rsrc, &ret, NULL ); + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); + return ret; +} + + +/********************************************************************** + * LockResource (kernelbase.@) + */ +LPVOID WINAPI DECLSPEC_HOTPATCH LockResource( HGLOBAL handle ) +{ + return handle; +} + + +/********************************************************************** + * SizeofResource (kernelbase.@) + */ +DWORD WINAPI DECLSPEC_HOTPATCH SizeofResource( HINSTANCE module, HRSRC rsrc ) +{ + if (!rsrc) return 0; + return ((IMAGE_RESOURCE_DATA_ENTRY *)rsrc)->Size; +} diff --git a/include/winbase.h b/include/winbase.h index 3ad81ad9408..3e75a4baf54 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1984,9 +1984,15 @@ WINBASEAPI BOOL WINAPI EnumResourceLanguagesExW(HMODULE,LPCWSTR,LPCWSTR,E WINBASEAPI BOOL WINAPI EnumResourceNamesA(HMODULE,LPCSTR,ENUMRESNAMEPROCA,LONG_PTR); WINBASEAPI BOOL WINAPI EnumResourceNamesW(HMODULE,LPCWSTR,ENUMRESNAMEPROCW,LONG_PTR); #define EnumResourceNames WINELIB_NAME_AW(EnumResourceNames) +WINBASEAPI BOOL WINAPI EnumResourceNamesExA(HMODULE,LPCSTR,ENUMRESNAMEPROCA,LONG_PTR,DWORD,LANGID); +WINBASEAPI BOOL WINAPI EnumResourceNamesExW(HMODULE,LPCWSTR,ENUMRESNAMEPROCW,LONG_PTR,DWORD,LANGID); +#define EnumResourceNamesEx WINELIB_NAME_AW(EnumResourceNamesEx) WINBASEAPI BOOL WINAPI EnumResourceTypesA(HMODULE,ENUMRESTYPEPROCA,LONG_PTR); WINBASEAPI BOOL WINAPI EnumResourceTypesW(HMODULE,ENUMRESTYPEPROCW,LONG_PTR); #define EnumResourceTypes WINELIB_NAME_AW(EnumResourceTypes) +WINBASEAPI BOOL WINAPI EnumResourceTypesExA(HMODULE,ENUMRESTYPEPROCA,LONG_PTR,DWORD,LANGID); +WINBASEAPI BOOL WINAPI EnumResourceTypesExW(HMODULE,ENUMRESTYPEPROCW,LONG_PTR,DWORD,LANGID); +#define EnumResourceTypesEx WINELIB_NAME_AW(EnumResourceTypesEx) WINADVAPI BOOL WINAPI EqualSid(PSID, PSID); WINADVAPI BOOL WINAPI EqualPrefixSid(PSID,PSID); WINBASEAPI DWORD WINAPI EraseTape(HANDLE,DWORD,BOOL);