mirror of
https://github.com/reactos/reactos.git
synced 2025-07-06 19:31:22 +00:00
[APITEST] Move RedirectIat into it's own header so that it can be used from multiple tests.
svn path=/trunk/; revision=75041
This commit is contained in:
parent
0d157ecbc8
commit
272bc3ef9f
3 changed files with 90 additions and 132 deletions
|
@ -30,7 +30,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "wine/test.h"
|
#include "wine/test.h"
|
||||||
|
#include "apitest_iathook.h"
|
||||||
#include "apphelp_apitest.h"
|
#include "apphelp_apitest.h"
|
||||||
|
|
||||||
#define GPLK_USER 1
|
#define GPLK_USER 1
|
||||||
|
@ -612,73 +612,6 @@ UINT WINAPI mGetDriveTypeW(LPCWSTR target)
|
||||||
return uRet;
|
return uRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PIMAGE_IMPORT_DESCRIPTOR FindImportDescriptor(PBYTE DllBase, PCSTR DllName)
|
|
||||||
{
|
|
||||||
ULONG Size;
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = RtlImageDirectoryEntryToData((HMODULE)DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size);
|
|
||||||
while (ImportDescriptor->Name && ImportDescriptor->OriginalFirstThunk)
|
|
||||||
{
|
|
||||||
PCHAR Name = (PCHAR)(DllBase + ImportDescriptor->Name);
|
|
||||||
if (!lstrcmpiA(Name, DllName))
|
|
||||||
{
|
|
||||||
return ImportDescriptor;
|
|
||||||
}
|
|
||||||
ImportDescriptor++;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL RedirectIat(PCSTR TargetDllName, PCSTR DllName, PCSTR FunctionName, ULONG_PTR NewFunction, ULONG_PTR* OriginalFunction)
|
|
||||||
{
|
|
||||||
PBYTE DllBase = (PBYTE)GetModuleHandleA(TargetDllName);
|
|
||||||
if (DllBase)
|
|
||||||
{
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = FindImportDescriptor(DllBase, DllName);
|
|
||||||
if (ImportDescriptor)
|
|
||||||
{
|
|
||||||
// On loaded images, OriginalFirstThunk points to the name / ordinal of the function
|
|
||||||
PIMAGE_THUNK_DATA OriginalThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->OriginalFirstThunk);
|
|
||||||
// FirstThunk points to the resolved address.
|
|
||||||
PIMAGE_THUNK_DATA FirstThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->FirstThunk);
|
|
||||||
while (OriginalThunk->u1.AddressOfData && FirstThunk->u1.Function)
|
|
||||||
{
|
|
||||||
if (!IMAGE_SNAP_BY_ORDINAL32(OriginalThunk->u1.AddressOfData))
|
|
||||||
{
|
|
||||||
PIMAGE_IMPORT_BY_NAME ImportName = (PIMAGE_IMPORT_BY_NAME)(DllBase + OriginalThunk->u1.AddressOfData);
|
|
||||||
if (!lstrcmpiA((PCSTR)ImportName->Name, FunctionName))
|
|
||||||
{
|
|
||||||
DWORD dwOld;
|
|
||||||
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), PAGE_EXECUTE_READWRITE, &dwOld);
|
|
||||||
*OriginalFunction = FirstThunk->u1.Function;
|
|
||||||
FirstThunk->u1.Function = NewFunction;
|
|
||||||
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), dwOld, &dwOld);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OriginalThunk++;
|
|
||||||
FirstThunk++;
|
|
||||||
}
|
|
||||||
skip("Unable to find the Import '%s' from '%s' in %s'\n", FunctionName, DllName, TargetDllName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
skip("Unable to find the ImportDescriptor for '%s' in '%s'\n", DllName, TargetDllName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
skip("Unable to find the loaded module '%s'\n", TargetDllName);
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL RestoreIat(PCSTR target, PCSTR DllName, PCSTR FunctionName, ULONG_PTR OriginalFunction)
|
|
||||||
{
|
|
||||||
ULONG_PTR old = 0;
|
|
||||||
return RedirectIat(target, DllName, FunctionName, OriginalFunction, &old);
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL wrapSdbSetPermLayerKeys2(LPCSTR dir, LPCSTR name, PCSTR szLayers, BOOL bMachine)
|
static BOOL wrapSdbSetPermLayerKeys2(LPCSTR dir, LPCSTR name, PCSTR szLayers, BOOL bMachine)
|
||||||
{
|
{
|
||||||
char szPath[MAX_PATH];
|
char szPath[MAX_PATH];
|
||||||
|
@ -759,7 +692,8 @@ static void test_Sign_Media(void)
|
||||||
ok(ret, "DefineDosDeviceA error: %d\n", GetLastError());
|
ok(ret, "DefineDosDeviceA error: %d\n", GetLastError());
|
||||||
if(ret)
|
if(ret)
|
||||||
{
|
{
|
||||||
ret = RedirectIat("apphelp.dll", "kernel32.dll", "GetDriveTypeW", (ULONG_PTR)mGetDriveTypeW, (ULONG_PTR*)&pGetDriveTypeW);
|
ret = RedirectIat(GetModuleHandleA("apphelp.dll"), "kernel32.dll", "GetDriveTypeW",
|
||||||
|
(ULONG_PTR)mGetDriveTypeW, (ULONG_PTR*)&pGetDriveTypeW);
|
||||||
if (g_WinVersion < WINVER_WIN8)
|
if (g_WinVersion < WINVER_WIN8)
|
||||||
ok(ret, "Expected redirect_iat to succeed\n");
|
ok(ret, "Expected redirect_iat to succeed\n");
|
||||||
if(ret)
|
if(ret)
|
||||||
|
@ -862,7 +796,7 @@ static void test_Sign_Media(void)
|
||||||
ok(wrapSdbSetPermLayerKeys2(drive, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
|
ok(wrapSdbSetPermLayerKeys2(drive, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = RestoreIat("apphelp.dll", "kernel32.dll", "GetDriveTypeW", (ULONG_PTR)pGetDriveTypeW);
|
ret = RestoreIat(GetModuleHandleA("apphelp.dll"), "kernel32.dll", "GetDriveTypeW", (ULONG_PTR)pGetDriveTypeW);
|
||||||
ok(ret, "Expected restore_iat to succeed\n");
|
ok(ret, "Expected restore_iat to succeed\n");
|
||||||
|
|
||||||
ok(delete_file(subdir, "test.bbb"), "delete_file error: %d\n", GetLastError());
|
ok(delete_file(subdir, "test.bbb"), "delete_file error: %d\n", GetLastError());
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
#include "wine/test.h"
|
#include "wine/test.h"
|
||||||
|
#include "apitest_iathook.h"
|
||||||
|
|
||||||
static DWORD g_Version;
|
static DWORD g_Version;
|
||||||
#define WINVER_ANY 0
|
#define WINVER_ANY 0
|
||||||
|
@ -311,58 +312,6 @@ static void post_theme_no(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PIMAGE_IMPORT_DESCRIPTOR FindImportDescriptor(PBYTE DllBase, PCSTR DllName)
|
|
||||||
{
|
|
||||||
ULONG Size;
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = RtlImageDirectoryEntryToData((HMODULE)DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size);
|
|
||||||
while (ImportDescriptor->Name && ImportDescriptor->OriginalFirstThunk)
|
|
||||||
{
|
|
||||||
PCHAR Name = (PCHAR)(DllBase + ImportDescriptor->Name);
|
|
||||||
if (!lstrcmpiA(Name, DllName))
|
|
||||||
{
|
|
||||||
return ImportDescriptor;
|
|
||||||
}
|
|
||||||
ImportDescriptor++;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL RedirectIat(HMODULE TargetDll, PCSTR DllName, PCSTR FunctionName, ULONG_PTR NewFunction, ULONG_PTR* OriginalFunction)
|
|
||||||
{
|
|
||||||
PBYTE DllBase = (PBYTE)TargetDll;
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = FindImportDescriptor(DllBase, DllName);
|
|
||||||
if (ImportDescriptor)
|
|
||||||
{
|
|
||||||
// On loaded images, OriginalFirstThunk points to the name / ordinal of the function
|
|
||||||
PIMAGE_THUNK_DATA OriginalThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->OriginalFirstThunk);
|
|
||||||
// FirstThunk points to the resolved address.
|
|
||||||
PIMAGE_THUNK_DATA FirstThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->FirstThunk);
|
|
||||||
while (OriginalThunk->u1.AddressOfData && FirstThunk->u1.Function)
|
|
||||||
{
|
|
||||||
if (!IMAGE_SNAP_BY_ORDINAL32(OriginalThunk->u1.AddressOfData))
|
|
||||||
{
|
|
||||||
PIMAGE_IMPORT_BY_NAME ImportName = (PIMAGE_IMPORT_BY_NAME)(DllBase + OriginalThunk->u1.AddressOfData);
|
|
||||||
if (!lstrcmpiA((PCSTR)ImportName->Name, FunctionName))
|
|
||||||
{
|
|
||||||
DWORD dwOld;
|
|
||||||
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), PAGE_EXECUTE_READWRITE, &dwOld);
|
|
||||||
*OriginalFunction = FirstThunk->u1.Function;
|
|
||||||
FirstThunk->u1.Function = NewFunction;
|
|
||||||
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), dwOld, &dwOld);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OriginalThunk++;
|
|
||||||
FirstThunk++;
|
|
||||||
}
|
|
||||||
skip("Unable to find the Import %s!%s\n", DllName, FunctionName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
skip("Unable to find the ImportDescriptor for %s\n", DllName);
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL hook_disp(HMODULE dll)
|
static BOOL hook_disp(HMODULE dll)
|
||||||
{
|
{
|
||||||
|
@ -370,11 +319,21 @@ static BOOL hook_disp(HMODULE dll)
|
||||||
RedirectIat(dll, "user32.dll", "EnumDisplaySettingsA", (ULONG_PTR)mEnumDisplaySettingsA, (ULONG_PTR*)&pEnumDisplaySettingsA);
|
RedirectIat(dll, "user32.dll", "EnumDisplaySettingsA", (ULONG_PTR)mEnumDisplaySettingsA, (ULONG_PTR*)&pEnumDisplaySettingsA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID unhook_disp(HMODULE dll)
|
||||||
|
{
|
||||||
|
RestoreIat(dll, "user32.dll", "ChangeDisplaySettingsA", (ULONG_PTR)pChangeDisplaySettingsA);
|
||||||
|
RestoreIat(dll, "user32.dll", "EnumDisplaySettingsA", (ULONG_PTR)pEnumDisplaySettingsA);
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL hook_theme(HMODULE dll)
|
static BOOL hook_theme(HMODULE dll)
|
||||||
{
|
{
|
||||||
return RedirectIat(dll, "uxtheme.dll", "SetThemeAppProperties", (ULONG_PTR)mSetThemeAppProperties, (ULONG_PTR*)&pSetThemeAppProperties);
|
return RedirectIat(dll, "uxtheme.dll", "SetThemeAppProperties", (ULONG_PTR)mSetThemeAppProperties, (ULONG_PTR*)&pSetThemeAppProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID unhook_theme(HMODULE dll)
|
||||||
|
{
|
||||||
|
RestoreIat(dll, "uxtheme.dll", "SetThemeAppProperties", (ULONG_PTR)pSetThemeAppProperties);
|
||||||
|
}
|
||||||
|
|
||||||
static void test_one(LPCSTR shim, DWORD dwReason, void(*pre)(), void(*post)(), void(*second)(void))
|
static void test_one(LPCSTR shim, DWORD dwReason, void(*pre)(), void(*post)(), void(*second)(void))
|
||||||
{
|
{
|
||||||
|
@ -424,24 +383,25 @@ static struct test_info
|
||||||
DWORD winver;
|
DWORD winver;
|
||||||
DWORD reason;
|
DWORD reason;
|
||||||
BOOL(*hook)(HMODULE);
|
BOOL(*hook)(HMODULE);
|
||||||
|
void(*unhook)(HMODULE);
|
||||||
void(*pre)(void);
|
void(*pre)(void);
|
||||||
void(*post)(void);
|
void(*post)(void);
|
||||||
void(*second)(void);
|
void(*second)(void);
|
||||||
} tests[] =
|
} tests[] =
|
||||||
{
|
{
|
||||||
/* Success */
|
/* Success */
|
||||||
{ "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, pre_8bit, post_8bit, post_8bit_no },
|
{ "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit, post_8bit, post_8bit_no },
|
||||||
{ "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, pre_8bit, post_8bit, post_8bit_no },
|
{ "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp,pre_8bit, post_8bit, post_8bit_no },
|
||||||
{ "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, pre_640, post_640, post_640_no },
|
{ "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640, post_640, post_640_no },
|
||||||
{ "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, pre_640, post_640, post_640_no },
|
{ "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640, post_640, post_640_no },
|
||||||
{ "DisableThemes", L"\\acgenral.dll", WINVER_ANY, 1, hook_theme, pre_theme, post_theme, post_theme_no },
|
{ "DisableThemes", L"\\acgenral.dll", WINVER_ANY, 1, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no },
|
||||||
{ "DisableThemes", L"\\acgenral.dll", _WIN32_WINNT_VISTA, 100, hook_theme, pre_theme, post_theme, post_theme_no },
|
{ "DisableThemes", L"\\acgenral.dll", _WIN32_WINNT_VISTA, 100, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no },
|
||||||
|
|
||||||
/* No need to change anything */
|
/* No need to change anything */
|
||||||
{ "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no },
|
{ "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no },
|
||||||
{ "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no },
|
{ "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no },
|
||||||
{ "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, pre_640_2, post_640_2, post_640_2_no },
|
{ "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no },
|
||||||
{ "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, pre_640_2, post_640_2, post_640_2_no },
|
{ "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
64
rostests/apitests/include/apitest_iathook.h
Normal file
64
rostests/apitests/include/apitest_iathook.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#ifndef _APITEST_IATHOOK_H
|
||||||
|
#define _APITEST_IATHOOK_H
|
||||||
|
|
||||||
|
static PIMAGE_IMPORT_DESCRIPTOR FindImportDescriptor(PBYTE DllBase, PCSTR DllName)
|
||||||
|
{
|
||||||
|
ULONG Size;
|
||||||
|
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = RtlImageDirectoryEntryToData((HMODULE)DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size);
|
||||||
|
while (ImportDescriptor->Name && ImportDescriptor->OriginalFirstThunk)
|
||||||
|
{
|
||||||
|
PCHAR Name = (PCHAR)(DllBase + ImportDescriptor->Name);
|
||||||
|
if (!lstrcmpiA(Name, DllName))
|
||||||
|
{
|
||||||
|
return ImportDescriptor;
|
||||||
|
}
|
||||||
|
ImportDescriptor++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL RedirectIat(HMODULE TargetDll, PCSTR DllName, PCSTR FunctionName, ULONG_PTR NewFunction, ULONG_PTR* OriginalFunction)
|
||||||
|
{
|
||||||
|
PBYTE DllBase = (PBYTE)TargetDll;
|
||||||
|
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = FindImportDescriptor(DllBase, DllName);
|
||||||
|
if (ImportDescriptor)
|
||||||
|
{
|
||||||
|
// On loaded images, OriginalFirstThunk points to the name / ordinal of the function
|
||||||
|
PIMAGE_THUNK_DATA OriginalThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->OriginalFirstThunk);
|
||||||
|
// FirstThunk points to the resolved address.
|
||||||
|
PIMAGE_THUNK_DATA FirstThunk = (PIMAGE_THUNK_DATA)(DllBase + ImportDescriptor->FirstThunk);
|
||||||
|
while (OriginalThunk->u1.AddressOfData && FirstThunk->u1.Function)
|
||||||
|
{
|
||||||
|
if (!IMAGE_SNAP_BY_ORDINAL32(OriginalThunk->u1.AddressOfData))
|
||||||
|
{
|
||||||
|
PIMAGE_IMPORT_BY_NAME ImportName = (PIMAGE_IMPORT_BY_NAME)(DllBase + OriginalThunk->u1.AddressOfData);
|
||||||
|
if (!lstrcmpiA((PCSTR)ImportName->Name, FunctionName))
|
||||||
|
{
|
||||||
|
DWORD dwOld;
|
||||||
|
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), PAGE_EXECUTE_READWRITE, &dwOld);
|
||||||
|
*OriginalFunction = FirstThunk->u1.Function;
|
||||||
|
FirstThunk->u1.Function = NewFunction;
|
||||||
|
VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR), dwOld, &dwOld);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OriginalThunk++;
|
||||||
|
FirstThunk++;
|
||||||
|
}
|
||||||
|
skip("Unable to find the Import %s!%s\n", DllName, FunctionName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skip("Unable to find the ImportDescriptor for %s\n", DllName);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL RestoreIat(HMODULE TargetDll, PCSTR DllName, PCSTR FunctionName, ULONG_PTR OriginalFunction)
|
||||||
|
{
|
||||||
|
ULONG_PTR old = 0;
|
||||||
|
return RedirectIat(TargetDll, DllName, FunctionName, OriginalFunction, &old);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _APITEST_IATHOOK_H
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue