#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()
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)
#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.
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;
+}