mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[APPHELP] Begin shimlib implementation. CORE-11329
Implement some macro's and functions that help when registering shims. These are all written in C, so that wine can use the shim libraries as well. svn path=/trunk/; revision=71439
This commit is contained in:
parent
849c418010
commit
b6d0f03c96
7 changed files with 264 additions and 0 deletions
|
@ -1,2 +1,5 @@
|
|||
project(appcompat)
|
||||
|
||||
set(SHIMLIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/shims/shimlib)
|
||||
add_subdirectory(apphelp)
|
||||
add_subdirectory(shims)
|
||||
|
|
3
reactos/dll/appcompat/shims/CMakeLists.txt
Normal file
3
reactos/dll/appcompat/shims/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
add_subdirectory(shimlib)
|
||||
|
7
reactos/dll/appcompat/shims/shimlib/CMakeLists.txt
Normal file
7
reactos/dll/appcompat/shims/shimlib/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
list(APPEND SOURCE
|
||||
shimlib.c
|
||||
shimlib.h)
|
||||
|
||||
add_library(shimlib ${SOURCE})
|
||||
add_dependencies(shimlib xdk)
|
76
reactos/dll/appcompat/shims/shimlib/implement_shim.inl
Normal file
76
reactos/dll/appcompat/shims/shimlib/implement_shim.inl
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Shim library
|
||||
* FILE: dll/appcompat/shims/shimlib/implement_shim.inl
|
||||
* PURPOSE: Shimlib helper file, used to register shims using the earlier prepared macro's
|
||||
* PROGRAMMER: Mark Jansen
|
||||
*/
|
||||
|
||||
#ifndef SHIM_NS
|
||||
#error "A namespace should be provided in SHIM_NS before including this file!"
|
||||
#endif
|
||||
|
||||
#ifndef SHIM_NUM_HOOKS
|
||||
#error "The number of hooks should be provided in SHIM_NUM_HOOKS before including this file!"
|
||||
#endif
|
||||
|
||||
#ifndef SHIM_OBJ_NAME
|
||||
#error "setup_shim.inl should be included before this file!"
|
||||
#endif
|
||||
|
||||
#ifndef SHIM_SETUP_HOOKS
|
||||
#error "Please define a hook: #define SHIM_SETUP_HOOKS SHIM_HOOK(num, dll_name, function_name, your_function)"
|
||||
#endif
|
||||
|
||||
PHOOKAPI WINAPI SHIM_OBJ_NAME(InitializeHooksMulti)(DWORD fdwReason, PCSTR pszCmdLine, PDWORD pdwHookCount)
|
||||
{
|
||||
if (fdwReason == SHIM_REASON_ATTACH)
|
||||
{
|
||||
if (pszCmdLine)
|
||||
{
|
||||
SHIM_OBJ_NAME(g_szCommandLine) = ShimLib_StringDuplicateA(pszCmdLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
SHIM_OBJ_NAME(g_szCommandLine) = "";
|
||||
}
|
||||
SHIM_OBJ_NAME(g_pAPIHooks) = ShimLib_ShimMalloc(sizeof(HOOKAPI) * SHIM_NUM_HOOKS);
|
||||
ZeroMemory(SHIM_OBJ_NAME(g_pAPIHooks), sizeof(HOOKAPI) * SHIM_NUM_HOOKS);
|
||||
*pdwHookCount = SHIM_NUM_HOOKS;
|
||||
}
|
||||
|
||||
#ifdef SHIM_NOTIFY_FN
|
||||
if (!SHIM_NOTIFY_FN(fdwReason) && fdwReason == SHIM_REASON_ATTACH)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
if (fdwReason == SHIM_REASON_ATTACH)
|
||||
{
|
||||
SHIM_SETUP_HOOKS
|
||||
}
|
||||
return SHIM_OBJ_NAME(g_pAPIHooks);
|
||||
}
|
||||
|
||||
|
||||
PVOID SHIM_OBJ_NAME(FindShim)(PCWSTR wszString)
|
||||
{
|
||||
PCSTR szString = SHIM_OBJ_NAME(g_szModuleName);
|
||||
while (*szString == *wszString)
|
||||
{
|
||||
if (!*szString)
|
||||
return SHIM_OBJ_NAME(InitializeHooksMulti);
|
||||
szString++; wszString++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma section(".shm$BBB",long,read)
|
||||
#endif
|
||||
|
||||
_SHMALLOC(".shm$BBB") _PVSHIM SHIM_OBJ_NAME(_shim_fn) = SHIM_OBJ_NAME(FindShim);
|
||||
|
||||
#undef SHIM_SETUP_HOOKS
|
||||
#undef SHIM_NOTIFY_FN
|
||||
#undef SHIM_NUM_HOOKS
|
||||
#undef SHIM_NS
|
39
reactos/dll/appcompat/shims/shimlib/setup_shim.inl
Normal file
39
reactos/dll/appcompat/shims/shimlib/setup_shim.inl
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Shim library
|
||||
* FILE: dll/appcompat/shims/shimlib/setup_shim.inl
|
||||
* PURPOSE: Shimlib helper file, used for setting up the macro's used when registering a shim.
|
||||
* PROGRAMMER: Mark Jansen
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SHIM_NS
|
||||
#error "A namespace should be provided in SHIM_NS before including this file!"
|
||||
#endif
|
||||
|
||||
#ifndef SHIM_OBJ_NAME
|
||||
#define SHIM_OBJ_NAME3(ns, name) ns ## _ ## name
|
||||
#define SHIM_OBJ_NAME2(ns, name) SHIM_OBJ_NAME3(ns, name)
|
||||
#define SHIM_OBJ_NAME(name) SHIM_OBJ_NAME2(SHIM_NS, name)
|
||||
|
||||
#define SHIM_STRINGIFY2(X_) # X_
|
||||
#define SHIM_STRINGIFY(X_) SHIM_STRINGIFY2(X_)
|
||||
|
||||
#define SHIM_HOOK(num, dll, function, target) \
|
||||
SHIM_OBJ_NAME(g_pAPIHooks)[num].LibraryName = dll; \
|
||||
SHIM_OBJ_NAME(g_pAPIHooks)[num].FunctionName = function; \
|
||||
SHIM_OBJ_NAME(g_pAPIHooks)[num].ReplacementFunction = target; \
|
||||
SHIM_OBJ_NAME(g_pAPIHooks)[num].OriginalFunction = NULL; \
|
||||
SHIM_OBJ_NAME(g_pAPIHooks)[num].Unk1 = NULL; \
|
||||
SHIM_OBJ_NAME(g_pAPIHooks)[num].Unk2 = NULL;
|
||||
|
||||
#define CALL_SHIM(SHIM_NUM, SHIM_CALLCONV) \
|
||||
((SHIM_CALLCONV)(SHIM_OBJ_NAME(g_pAPIHooks)[SHIM_NUM].OriginalFunction))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
PCSTR SHIM_OBJ_NAME(g_szModuleName) = SHIM_STRINGIFY(SHIM_NS);
|
||||
PCSTR SHIM_OBJ_NAME(g_szCommandLine);
|
||||
PHOOKAPI SHIM_OBJ_NAME(g_pAPIHooks);
|
||||
|
91
reactos/dll/appcompat/shims/shimlib/shimlib.c
Normal file
91
reactos/dll/appcompat/shims/shimlib/shimlib.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Shim library
|
||||
* FILE: dll/appcompat/shims/shimlib/shimlib.c
|
||||
* PURPOSE: Shim helper functions
|
||||
* PROGRAMMER: Mark Jansen
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <shimlib.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
HINSTANCE g_hinstDll;
|
||||
static HANDLE g_ShimLib_Heap;
|
||||
|
||||
void ShimLib_Init(HINSTANCE hInstance)
|
||||
{
|
||||
g_hinstDll = hInstance;
|
||||
g_ShimLib_Heap = HeapCreate(0, 0x10000, 0);
|
||||
}
|
||||
|
||||
void ShimLib_Deinit()
|
||||
{
|
||||
// Is this a good idea?
|
||||
HeapDestroy(g_ShimLib_Heap);
|
||||
}
|
||||
|
||||
PVOID ShimLib_ShimMalloc(SIZE_T dwSize)
|
||||
{
|
||||
return HeapAlloc(g_ShimLib_Heap, 0, dwSize);
|
||||
}
|
||||
|
||||
void ShimLib_ShimFree(PVOID pData)
|
||||
{
|
||||
HeapFree(g_ShimLib_Heap, 0, pData);
|
||||
}
|
||||
|
||||
PCSTR ShimLib_StringDuplicateA(PCSTR szString)
|
||||
{
|
||||
SIZE_T Length = lstrlenA(szString);
|
||||
PSTR NewString = ShimLib_ShimMalloc(Length+1);
|
||||
return lstrcpyA(NewString, szString);
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#if defined(_M_IA64) || defined(_M_AMD64)
|
||||
#define _ATTRIBUTES read
|
||||
#else
|
||||
#define _ATTRIBUTES read
|
||||
#endif
|
||||
|
||||
|
||||
#pragma section(".shm",long,read)
|
||||
#pragma section(".shm$AAA",long,read)
|
||||
#pragma section(".shm$ZZZ",long,read)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(linker, "/merge:.shm=.rdata")
|
||||
#endif
|
||||
|
||||
|
||||
_SHMALLOC(".shm") _PVSHIM _shim_start = 0;
|
||||
_SHMALLOC(".shm$ZZZ") _PVSHIM _shim_end = 0;
|
||||
|
||||
|
||||
/* Generic GetHookAPIs function.
|
||||
The macro's from <setup_shim.inl> and <implement_shim.inl> will register a list of all apis that should be hooked
|
||||
for a specific shim
|
||||
This helper function will return the correct shim, and call the init function */
|
||||
PHOOKAPI WINAPI ShimLib_GetHookAPIs(IN LPCSTR szCommandLine, IN LPCWSTR wszShimName, OUT PDWORD pdwHookCount)
|
||||
{
|
||||
uintptr_t ps = (uintptr_t)&_shim_start;
|
||||
ps += sizeof(uintptr_t);
|
||||
for (; ps != (uintptr_t)&_shim_end; ps += sizeof(uintptr_t))
|
||||
{
|
||||
_PVSHIM* pfunc = (_PVSHIM *)ps;
|
||||
if (*pfunc != NULL)
|
||||
{
|
||||
PVOID res = (*pfunc)(wszShimName);
|
||||
if (res)
|
||||
{
|
||||
PHOOKAPI (WINAPI* PFN)(DWORD, PCSTR, PDWORD) = res;
|
||||
return (*PFN)(SHIM_REASON_ATTACH, szCommandLine, pdwHookCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
45
reactos/dll/appcompat/shims/shimlib/shimlib.h
Normal file
45
reactos/dll/appcompat/shims/shimlib/shimlib.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Shim Engine
|
||||
* FILE: dll/appcompat/shims/shimlib/shimlib.h
|
||||
* PURPOSE: ReactOS Shim Engine
|
||||
* PROGRAMMER: Mark Jansen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct tagHOOKAPI {
|
||||
PCSTR LibraryName;
|
||||
PCSTR FunctionName;
|
||||
PVOID ReplacementFunction;
|
||||
PVOID OriginalFunction;
|
||||
PVOID Unk1;
|
||||
PVOID Unk2;
|
||||
} HOOKAPI, *PHOOKAPI;
|
||||
|
||||
extern HINSTANCE g_hinstDll;
|
||||
|
||||
void ShimLib_Init(HINSTANCE);
|
||||
void ShimLib_Deinit(void);
|
||||
PVOID ShimLib_ShimMalloc(SIZE_T);
|
||||
void ShimLib_ShimFree(PVOID);
|
||||
PCSTR ShimLib_StringDuplicateA(PCSTR);
|
||||
PHOOKAPI WINAPI ShimLib_GetHookAPIs(LPCSTR,LPCWSTR,PDWORD);
|
||||
|
||||
|
||||
#define SHIM_REASON_ATTACH 1
|
||||
#define SHIM_REASON_DETACH 2
|
||||
#define SHIM_REASON_DLL_LOAD 3 /* Arg: PLDR_DATA_TABLE_ENTRY */
|
||||
#define SHIM_REASON_DLL_UNLOAD 4 /* Arg: Module Handle */
|
||||
|
||||
|
||||
typedef PVOID (__cdecl *_PVSHIM)(PCWSTR);
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define _SHMALLOC(x) __declspec(allocate(x))
|
||||
#elif defined(__GNUC__)
|
||||
#define _SHMALLOC(x) __attribute__ ((section (x) ))
|
||||
#else
|
||||
#error Your compiler is not supported.
|
||||
#endif
|
||||
|
Loading…
Reference in a new issue