Author: mjansen Date: Sat May 28 16:42:57 2016 New Revision: 71439 URL: http://svn.reactos.org/svn/reactos?rev=71439&view=rev Log: [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.
Added: trunk/reactos/dll/appcompat/shims/ trunk/reactos/dll/appcompat/shims/CMakeLists.txt (with props) trunk/reactos/dll/appcompat/shims/shimlib/ trunk/reactos/dll/appcompat/shims/shimlib/CMakeLists.txt (with props) trunk/reactos/dll/appcompat/shims/shimlib/implement_shim.inl (with props) trunk/reactos/dll/appcompat/shims/shimlib/setup_shim.inl (with props) trunk/reactos/dll/appcompat/shims/shimlib/shimlib.c (with props) trunk/reactos/dll/appcompat/shims/shimlib/shimlib.h (with props) Modified: trunk/reactos/dll/appcompat/CMakeLists.txt Modified: trunk/reactos/dll/appcompat/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/CMakeLists.txt?rev=71439&r1=71438&r2=71439&view=diff ============================================================================== --- trunk/reactos/dll/appcompat/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/dll/appcompat/CMakeLists.txt [iso-8859-1] Sat May 28 16:42:57 2016 @@ -1,2 +1,5 @@ +project(appcompat) +set(SHIMLIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/shims/shimlib) add_subdirectory(apphelp) +add_subdirectory(shims) Added: trunk/reactos/dll/appcompat/shims/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/CMakeLists.txt?rev=71439 ============================================================================== --- trunk/reactos/dll/appcompat/shims/CMakeLists.txt (added) +++ trunk/reactos/dll/appcompat/shims/CMakeLists.txt [iso-8859-1] Sat May 28 16:42:57 2016 @@ -0,0 +1,3 @@ + +add_subdirectory(shimlib) + Propchange: trunk/reactos/dll/appcompat/shims/CMakeLists.txt ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/dll/appcompat/shims/shimlib/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/shimlib/CMakeLists.txt?rev=71439 ============================================================================== --- trunk/reactos/dll/appcompat/shims/shimlib/CMakeLists.txt (added) +++ trunk/reactos/dll/appcompat/shims/shimlib/CMakeLists.txt [iso-8859-1] Sat May 28 16:42:57 2016 @@ -0,0 +1,7 @@ + +list(APPEND SOURCE + shimlib.c + shimlib.h) + +add_library(shimlib ${SOURCE}) +add_dependencies(shimlib xdk) Propchange: trunk/reactos/dll/appcompat/shims/shimlib/CMakeLists.txt ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/dll/appcompat/shims/shimlib/implement_shim.inl URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/shimlib/implement_shim.inl?rev=71439 ============================================================================== --- trunk/reactos/dll/appcompat/shims/shimlib/implement_shim.inl (added) +++ trunk/reactos/dll/appcompat/shims/shimlib/implement_shim.inl [iso-8859-1] Sat May 28 16:42:57 2016 @@ -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 Propchange: trunk/reactos/dll/appcompat/shims/shimlib/implement_shim.inl ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/dll/appcompat/shims/shimlib/setup_shim.inl URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/shimlib/setup_shim.inl?rev=71439 ============================================================================== --- trunk/reactos/dll/appcompat/shims/shimlib/setup_shim.inl (added) +++ trunk/reactos/dll/appcompat/shims/shimlib/setup_shim.inl [iso-8859-1] Sat May 28 16:42:57 2016 @@ -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); + Propchange: trunk/reactos/dll/appcompat/shims/shimlib/setup_shim.inl ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/dll/appcompat/shims/shimlib/shimlib.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/shimlib/shimlib.c?rev=71439 ============================================================================== --- trunk/reactos/dll/appcompat/shims/shimlib/shimlib.c (added) +++ trunk/reactos/dll/appcompat/shims/shimlib/shimlib.c [iso-8859-1] Sat May 28 16:42:57 2016 @@ -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; +} + Propchange: trunk/reactos/dll/appcompat/shims/shimlib/shimlib.c ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/dll/appcompat/shims/shimlib/shimlib.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/shimlib/shimlib.h?rev=71439 ============================================================================== --- trunk/reactos/dll/appcompat/shims/shimlib/shimlib.h (added) +++ trunk/reactos/dll/appcompat/shims/shimlib/shimlib.h [iso-8859-1] Sat May 28 16:42:57 2016 @@ -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 + Propchange: trunk/reactos/dll/appcompat/shims/shimlib/shimlib.h ------------------------------------------------------------------------------ svn:eol-style = native