Author: mjansen
Date: Fri Dec 16 19:18:26 2016
New Revision: 73461
URL:
http://svn.reactos.org/svn/reactos?rev=73461&view=rev
Log:
[SHIMLIB] Shim helper functions keep a list of used shims, so that events can be
forwarded. CORE-11329
Added:
trunk/reactos/dll/appcompat/shims/shimlib/shimdbgsupp.c (with props)
Modified:
trunk/reactos/dll/appcompat/shims/layer/main.c
trunk/reactos/dll/appcompat/shims/layer/versionlie.c
trunk/reactos/dll/appcompat/shims/layer/versionlie.inl
trunk/reactos/dll/appcompat/shims/shimlib/CMakeLists.txt
trunk/reactos/dll/appcompat/shims/shimlib/implement_shim.inl
trunk/reactos/dll/appcompat/shims/shimlib/setup_shim.inl
trunk/reactos/dll/appcompat/shims/shimlib/shimlib.c
trunk/reactos/dll/appcompat/shims/shimlib/shimlib.h
Modified: trunk/reactos/dll/appcompat/shims/layer/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/layer/…
==============================================================================
--- trunk/reactos/dll/appcompat/shims/layer/main.c [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/shims/layer/main.c [iso-8859-1] Fri Dec 16 19:18:26 2016
@@ -16,10 +16,10 @@
return ShimLib_GetHookAPIs(szCommandLine, wszShimName, pdwHookCount);
}
-/* PLDR_DATA_TABLE_ENTRY */
-BOOL WINAPI NotifyShims(DWORD fdwReason, PVOID P)
+/* Forward to the generic implementation */
+BOOL WINAPI NotifyShims(DWORD fdwReason, PVOID ptr)
{
- return TRUE;
+ return ShimLib_NotifyShims(fdwReason, ptr);
}
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
Modified: trunk/reactos/dll/appcompat/shims/layer/versionlie.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/layer/…
==============================================================================
--- trunk/reactos/dll/appcompat/shims/layer/versionlie.c [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/shims/layer/versionlie.c [iso-8859-1] Fri Dec 16 19:18:26
2016
@@ -89,7 +89,6 @@
#define SHIM_NS Win95VersionLie
-
#include <setup_shim.inl>
DWORD WINAPI SHIM_OBJ_NAME(APIHook_GetVersion)()
@@ -128,7 +127,6 @@
#define SHIM_NS Win98VersionLie
-
#include <setup_shim.inl>
DWORD WINAPI SHIM_OBJ_NAME(APIHook_GetVersion)()
Modified: trunk/reactos/dll/appcompat/shims/layer/versionlie.inl
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/layer/…
==============================================================================
--- trunk/reactos/dll/appcompat/shims/layer/versionlie.inl [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/shims/layer/versionlie.inl [iso-8859-1] Fri Dec 16
19:18:26 2016
@@ -43,9 +43,9 @@
return FALSE;
}
-BOOL WINAPI SHIM_OBJ_NAME(Notify)(DWORD fdwReason)
+BOOL WINAPI SHIM_OBJ_NAME(Notify)(DWORD fdwReason, PVOID ptr)
{
- if (fdwReason == SHIM_REASON_ATTACH && VERSION_INFO.wServicePackMajor)
+ if (fdwReason == SHIM_NOTIFY_ATTACH && VERSION_INFO.wServicePackMajor)
{
static CONST WCHAR szServicePack[] =
{'S','e','r','v','i','c','e','
','P','a','c','k','
','%','u',0};
HRESULT hr = StringCbPrintfA(VERSION_INFO.szCSDVersionA,
sizeof(VERSION_INFO.szCSDVersionA),
Modified: trunk/reactos/dll/appcompat/shims/shimlib/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/shimli…
==============================================================================
--- trunk/reactos/dll/appcompat/shims/shimlib/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/shims/shimlib/CMakeLists.txt [iso-8859-1] Fri Dec 16
19:18:26 2016
@@ -1,7 +1,11 @@
list(APPEND SOURCE
+ shimdbgsupp.c
shimlib.c
- shimlib.h)
+ shimlib.h
+ # These .inl functions are included so they show up in vs
+ setup_shim.inl
+ implement_shim.inl)
add_library(shimlib ${SOURCE})
add_dependencies(shimlib xdk)
Modified: trunk/reactos/dll/appcompat/shims/shimlib/implement_shim.inl
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/shimli…
==============================================================================
--- trunk/reactos/dll/appcompat/shims/shimlib/implement_shim.inl [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/shims/shimlib/implement_shim.inl [iso-8859-1] Fri Dec 16
19:18:26 2016
@@ -2,7 +2,7 @@
* 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
+ * PURPOSE: Shimlib helper file, used to register shims setup with macro's
from setup_shim.inl
* PROGRAMMER: Mark Jansen
*/
@@ -18,57 +18,56 @@
#error "setup_shim.inl should be included before this file!"
#endif
+#if SHIM_NUM_HOOKS > 0
#ifndef SHIM_SETUP_HOOKS
#error "Please define a hook: #define SHIM_SETUP_HOOKS SHIM_HOOK(num, dll_name,
function_name, your_function)"
#endif
+#else
+#ifdef SHIM_SETUP_HOOKS
+#error "Hooks are defined, yet SHIM_NUM_HOOKS is <= 0 !"
+#endif
+#endif
-PHOOKAPI WINAPI SHIM_OBJ_NAME(InitializeHooksMulti)(DWORD fdwReason, PCSTR pszCmdLine,
PDWORD pdwHookCount)
+PHOOKAPI WINAPI SHIM_OBJ_NAME(GetHookAPIs)(DWORD fdwReason, PCSTR pszCmdLine, PDWORD
pdwHookCount)
{
- if (fdwReason == SHIM_REASON_ATTACH)
+ if (pszCmdLine)
{
- 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;
+ 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)
+ if (!SHIM_NOTIFY_FN(fdwReason, NULL))
return NULL;
#endif
- if (fdwReason == SHIM_REASON_ATTACH)
- {
- SHIM_SETUP_HOOKS
- }
+#if SHIM_NUM_HOOKS > 0
+ SHIM_SETUP_HOOKS
+#endif
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);
+_SHMALLOC(".shm$BBB") SHIMREG SHIM_OBJ_NAME(_shim_fn) =
+{
+ SHIM_OBJ_NAME(GetHookAPIs),
+#ifdef SHIM_NOTIFY_FN
+ SHIM_NOTIFY_FN,
+#else
+ NULL,
+#endif
+ SHIM_STRINGIFY(SHIM_NS)
+};
#undef SHIM_SETUP_HOOKS
#undef SHIM_NOTIFY_FN
Modified: trunk/reactos/dll/appcompat/shims/shimlib/setup_shim.inl
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/shimli…
==============================================================================
--- trunk/reactos/dll/appcompat/shims/shimlib/setup_shim.inl [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/shims/shimlib/setup_shim.inl [iso-8859-1] Fri Dec 16
19:18:26 2016
@@ -19,13 +19,15 @@
#define SHIM_STRINGIFY2(X_) # X_
#define SHIM_STRINGIFY(X_) SHIM_STRINGIFY2(X_)
+/* TODO: static_assert on (num < SHIM_NUM_HOOKS) */
+
#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;
+ SHIM_OBJ_NAME(g_pAPIHooks)[num].Reserved[0] = NULL; \
+ SHIM_OBJ_NAME(g_pAPIHooks)[num].Reserved[1] = NULL;
#define CALL_SHIM(SHIM_NUM, SHIM_CALLCONV) \
((SHIM_CALLCONV)(SHIM_OBJ_NAME(g_pAPIHooks)[SHIM_NUM].OriginalFunction))
Added: trunk/reactos/dll/appcompat/shims/shimlib/shimdbgsupp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/shimli…
==============================================================================
--- trunk/reactos/dll/appcompat/shims/shimlib/shimdbgsupp.c (added)
+++ trunk/reactos/dll/appcompat/shims/shimlib/shimdbgsupp.c [iso-8859-1] Fri Dec 16
19:18:26 2016
@@ -0,0 +1,79 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Shim library
+ * FILE: dll/appcompat/shims/shimlib/shimdbgsupp.c
+ * PURPOSE: Shim debug helper functions
+ * PROGRAMMER: Mark Jansen
+ */
+
+#include <windef.h>
+#include <winbase.h>
+#include <shimlib.h>
+#include <strsafe.h>
+
+#include "wine/winternl.h"
+
+#define DPFLTR_APPCOMPAT_ID 123
+
+void ApphelppInitDebugSupport(PCWSTR KeyName, PULONG Level);
+static void SeiInitDebugSupport()
+{
+ ApphelppInitDebugSupport(L"SHIMENG_DEBUG_LEVEL",
&g_ShimEngDebugLevel);
+}
+
+
+/**
+ * Outputs diagnostic info.
+ *
+ * @param [in] Level The level to log this message with, choose any of
[SHIM_ERR,
+ * SHIM_WARN, SHIM_INFO].
+ * @param [in] FunctionName The function this log should be attributed to.
+ * @param [in] Format The format string.
+ * @param ... Variable arguments providing additional information.
+ *
+ * @return Success: TRUE Failure: FALSE.
+ */
+BOOL WINAPIV SeiDbgPrint(SEI_LOG_LEVEL Level, PCSTR FunctionName, PCSTR Format, ...)
+{
+ char Buffer[512];
+ va_list ArgList;
+ char* Current = Buffer;
+ const char* LevelStr;
+ size_t Length = sizeof(Buffer);
+
+ if (g_ShimEngDebugLevel == 0xffffffff)
+ SeiInitDebugSupport();
+
+ if (Level > g_ShimEngDebugLevel)
+ return FALSE;
+
+ switch (Level)
+ {
+ case SEI_ERR:
+ LevelStr = "Err ";
+ Level = DPFLTR_MASK | (1 << DPFLTR_ERROR_LEVEL);
+ break;
+ case SEI_WARN:
+ LevelStr = "Warn";
+ Level = DPFLTR_MASK | (1 << DPFLTR_WARNING_LEVEL);
+ break;
+ case SEI_INFO:
+ LevelStr = "Info";
+ Level = DPFLTR_MASK | (1 << DPFLTR_INFO_LEVEL);
+ break;
+ default:
+ LevelStr = "User";
+ Level = DPFLTR_MASK | (1 << DPFLTR_INFO_LEVEL);
+ break;
+ }
+ StringCchPrintfExA(Current, Length, &Current, &Length,
STRSAFE_NULL_ON_FAILURE, "[%s][%-20s] ", LevelStr, FunctionName);
+ va_start(ArgList, Format);
+ StringCchVPrintfExA(Current, Length, &Current, &Length,
STRSAFE_NULL_ON_FAILURE, Format, ArgList);
+ va_end(ArgList);
+#if defined(APPCOMPAT_USE_DBGPRINTEX) && APPCOMPAT_USE_DBGPRINTEX
+ return NT_SUCCESS(DbgPrintEx(DPFLTR_APPCOMPAT_ID, Level, "%s", Buffer));
+#else
+ OutputDebugStringA(Buffer);
+ return TRUE;
+#endif
+}
Propchange: trunk/reactos/dll/appcompat/shims/shimlib/shimdbgsupp.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/appcompat/shims/shimlib/shimlib.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/shimli…
==============================================================================
--- trunk/reactos/dll/appcompat/shims/shimlib/shimlib.c [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/shims/shimlib/shimlib.c [iso-8859-1] Fri Dec 16 19:18:26
2016
@@ -11,13 +11,25 @@
#include <shimlib.h>
#include <strsafe.h>
-HINSTANCE g_hinstDll;
+typedef struct UsedShim
+{
+ SLIST_ENTRY Entry;
+ PSHIMREG pShim;
+#if (WINVER > _WIN32_WINNT_WS03)
+ BOOL bInitCalled;
+#endif
+} UsedShim, *pUsedShim;
+
+
static HANDLE g_ShimLib_Heap;
+static PSLIST_HEADER g_UsedShims;
void ShimLib_Init(HINSTANCE hInstance)
{
- g_hinstDll = hInstance;
g_ShimLib_Heap = HeapCreate(0, 0x10000, 0);
+
+ g_UsedShims = (PSLIST_HEADER)ShimLib_ShimMalloc(sizeof(SLIST_HEADER));
+ RtlInitializeSListHead(g_UsedShims);
}
void ShimLib_Deinit()
@@ -43,6 +55,18 @@
return lstrcpyA(NewString, szString);
}
+BOOL ShimLib_StrAEqualsW(PCSTR szString, PCWSTR wszString)
+{
+ while (*szString == *wszString)
+ {
+ if (!*szString)
+ return TRUE;
+
+ szString++; wszString++;
+ }
+ return FALSE;
+}
+
#if defined(_MSC_VER)
#if defined(_M_IA64) || defined(_M_AMD64)
@@ -62,8 +86,8 @@
#endif
-_SHMALLOC(".shm") _PVSHIM _shim_start = 0;
-_SHMALLOC(".shm$ZZZ") _PVSHIM _shim_end = 0;
+_SHMALLOC(".shm") SHIMREG _shim_start = { 0 };
+_SHMALLOC(".shm$ZZZ") SHIMREG _shim_end = { 0 };
/* Generic GetHookAPIs function.
@@ -72,21 +96,53 @@
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))
+ PSHIMREG ps = &_shim_start;
+ ps++;
+ for (; ps != &_shim_end; ps++)
{
- _PVSHIM* pfunc = (_PVSHIM *)ps;
- if (*pfunc != NULL)
+ if (ps->GetHookAPIs != NULL && ps->ShimName != NULL)
{
- PVOID res = (*pfunc)(wszShimName);
- if (res)
+ if (ShimLib_StrAEqualsW(ps->ShimName, wszShimName))
{
- PHOOKAPI (WINAPI* PFN)(DWORD, PCSTR, PDWORD) = res;
- return (*PFN)(SHIM_REASON_ATTACH, szCommandLine, pdwHookCount);
+ pUsedShim shim = (pUsedShim)ShimLib_ShimMalloc(sizeof(UsedShim));
+ shim->pShim = ps;
+#if (WINVER > _WIN32_WINNT_WS03)
+ shim->bInitCalled = FALSE;
+#endif
+ RtlInterlockedPushEntrySList(g_UsedShims, &(shim->Entry));
+
+ return ps->GetHookAPIs(SHIM_NOTIFY_ATTACH, szCommandLine,
pdwHookCount);
}
}
}
return NULL;
}
+
+BOOL WINAPI ShimLib_NotifyShims(DWORD fdwReason, PVOID ptr)
+{
+ PSLIST_ENTRY pEntry = RtlFirstEntrySList(g_UsedShims);
+
+ if (fdwReason < SHIM_REASON_INIT)
+ fdwReason += (SHIM_REASON_INIT - SHIM_NOTIFY_ATTACH);
+
+ while (pEntry)
+ {
+ pUsedShim pUsed = CONTAINING_RECORD(pEntry, UsedShim, Entry);
+ _PVNotify Notify = pUsed->pShim->Notify;
+#if (WINVER > _WIN32_WINNT_WS03)
+ if (pUsed->bInitCalled && fdwReason == SHIM_REASON_INIT)
+ Notify = NULL;
+#endif
+ if (Notify)
+ Notify(fdwReason, ptr);
+#if (WINVER > _WIN32_WINNT_WS03)
+ if (fdwReason == SHIM_REASON_INIT)
+ pUsed->bInitCalled = TRUE;
+#endif
+
+ pEntry = pEntry->Next;
+ }
+
+ return TRUE;
+}
Modified: trunk/reactos/dll/appcompat/shims/shimlib/shimlib.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/shims/shimli…
==============================================================================
--- trunk/reactos/dll/appcompat/shims/shimlib/shimlib.h [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/shims/shimlib/shimlib.h [iso-8859-1] Fri Dec 16 19:18:26
2016
@@ -8,32 +8,71 @@
#pragma once
-typedef struct tagHOOKAPI {
+typedef struct tagHOOKAPI
+{
PCSTR LibraryName;
PCSTR FunctionName;
PVOID ReplacementFunction;
PVOID OriginalFunction;
- PVOID Unk1;
- PVOID Unk2;
+ PVOID Reserved[2];
} 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);
+BOOL ShimLib_StrAEqualsW(PCSTR, PCWSTR);
-#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 */
+/* Forward events to generic handlers */
+void ShimLib_Init(HINSTANCE);
+void ShimLib_Deinit(void);
+PHOOKAPI WINAPI ShimLib_GetHookAPIs(LPCSTR,LPCWSTR,PDWORD);
+BOOL WINAPI ShimLib_NotifyShims(DWORD fdwReason, PVOID ptr);
-typedef PVOID (__cdecl *_PVSHIM)(PCWSTR);
+/* Shims should respond to SHIM_REASON_XXXX in the Notify routines.
+ SHIM_NOTIFY_ codes are sent by apphelp, and translated to SHIM_REASON_ by the shimlib
routines.
+ The only exception being SHIM_NOTIFY_ATTACH, that is also set for one-time init.
+ */
+
+#define SHIM_REASON_INIT 100
+#define SHIM_REASON_DEINIT 101
+#define SHIM_REASON_DLL_LOAD 102 /* Arg: PLDR_DATA_TABLE_ENTRY */
+#define SHIM_REASON_DLL_UNLOAD 103 /* Arg: PLDR_DATA_TABLE_ENTRY */
+
+#define SHIM_NOTIFY_ATTACH 1
+#define SHIM_NOTIFY_DETACH 2
+#define SHIM_NOTIFY_DLL_LOAD 3 /* Arg: PLDR_DATA_TABLE_ENTRY */
+#define SHIM_NOTIFY_DLL_UNLOAD 4 /* Arg: PLDR_DATA_TABLE_ENTRY */
+
+
+
+typedef enum _SEI_LOG_LEVEL {
+ SEI_ERR = 1,
+ SEI_WARN = 2,
+ SEI_INFO = 3,
+} SEI_LOG_LEVEL;
+
+BOOL WINAPIV SeiDbgPrint(SEI_LOG_LEVEL Level, PCSTR FunctionName, PCSTR Format, ...);
+extern ULONG g_ShimEngDebugLevel;
+
+#define SHIMENG_ERR(fmt, ...) do { if (g_ShimEngDebugLevel) SeiDbgPrint(SEI_ERR,
__FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
+#define SHIMENG_WARN(fmt, ...) do { if (g_ShimEngDebugLevel) SeiDbgPrint(SEI_WARN,
__FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
+#define SHIMENG_INFO(fmt, ...) do { if (g_ShimEngDebugLevel) SeiDbgPrint(SEI_INFO,
__FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
+
+
+
+typedef PHOOKAPI (WINAPI* _PVGetHookAPIs)(DWORD, PCSTR, PDWORD);
+typedef BOOL (WINAPI* _PVNotify)(DWORD, PVOID);
+
+typedef struct tagSHIMREG
+{
+ _PVGetHookAPIs GetHookAPIs;
+ _PVNotify Notify;
+ PCSTR ShimName;
+} SHIMREG, *PSHIMREG;
+
#if defined(_MSC_VER)
#define _SHMALLOC(x) __declspec(allocate(x))