2 * Copyright 2015-2017 Mark Jansen
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define WIN32_NO_STATUS
25 HANDLE g_pShimEngModHandle
= 0;
28 ULONG g_ShimEngDebugLevel
= 0xffffffff;
33 VOID
SeiInitDebugSupport(VOID
)
35 static const UNICODE_STRING DebugKey
= RTL_CONSTANT_STRING(L
"SHIMENG_DEBUG_LEVEL");
36 UNICODE_STRING DebugValue
;
41 RtlInitEmptyUnicodeString(&DebugValue
, Buffer
, sizeof(Buffer
));
43 Status
= RtlQueryEnvironmentVariable_U(NULL
, &DebugKey
, &DebugValue
);
45 if (NT_SUCCESS(Status
))
47 if (!NT_SUCCESS(RtlUnicodeStringToInteger(&DebugValue
, 10, &NewLevel
)))
50 g_ShimEngDebugLevel
= NewLevel
;
55 * Outputs diagnostic info.
57 * @param [in] Level The level to log this message with, choose any of [SHIM_ERR,
58 * SHIM_WARN, SHIM_INFO].
59 * @param [in] FunctionName The function this log should be attributed to.
60 * @param [in] Format The format string.
61 * @param ... Variable arguments providing additional information.
63 * @return Success: TRUE Failure: FALSE.
65 BOOL WINAPIV
SeiDbgPrint(SEI_LOG_LEVEL Level
, PCSTR Function
, PCSTR Format
, ...)
68 char* Current
= Buffer
;
70 size_t Length
= sizeof(Buffer
);
74 if (g_ShimEngDebugLevel
== 0xffffffff)
75 SeiInitDebugSupport();
77 if (Level
> g_ShimEngDebugLevel
)
100 hr
= StringCchPrintfExA(Current
, Length
, &Current
, &Length
, STRSAFE_NULL_ON_FAILURE
, "[%s] [%s] ", LevelStr
, Function
);
102 hr
= StringCchPrintfExA(Current
, Length
, &Current
, &Length
, STRSAFE_NULL_ON_FAILURE
, "[%s] ", LevelStr
);
107 va_start(ArgList
, Format
);
108 hr
= StringCchVPrintfExA(Current
, Length
, &Current
, &Length
, STRSAFE_NULL_ON_FAILURE
, Format
, ArgList
);
113 DbgPrint("%s", Buffer
);
122 VOID
NotifyShims(DWORD dwReason
, PVOID Info
)
124 /* Enumerate all loaded shims */
128 VOID NTAPI
SE_InstallBeforeInit(PUNICODE_STRING ProcessImage
, PVOID pShimData
)
130 SHIMENG_FAIL("(%wZ, %p)", ProcessImage
, pShimData
);
131 /* Find & Load all shims.. */
134 VOID NTAPI
SE_InstallAfterInit(PUNICODE_STRING ProcessImage
, PVOID pShimData
)
136 SHIMENG_FAIL("(%wZ, %p)", ProcessImage
, pShimData
);
137 NotifyShims(SHIM_NOTIFY_ATTACH
, NULL
);
140 VOID NTAPI
SE_ProcessDying(VOID
)
143 NotifyShims(SHIM_NOTIFY_DETACH
, NULL
);
146 VOID WINAPI
SE_DllLoaded(PLDR_DATA_TABLE_ENTRY LdrEntry
)
148 SHIMENG_FAIL("(%p)", LdrEntry
);
149 NotifyShims(SHIM_REASON_DLL_LOAD
, LdrEntry
);
152 VOID WINAPI
SE_DllUnloaded(PLDR_DATA_TABLE_ENTRY LdrEntry
)
154 SHIMENG_FAIL("(%p)", LdrEntry
);
155 NotifyShims(SHIM_REASON_DLL_UNLOAD
, LdrEntry
);
158 BOOL WINAPI
SE_IsShimDll(PVOID BaseAddress
)
160 SHIMENG_FAIL("(%p)", BaseAddress
);