[APPHELP][SHIMLIB] Forward some events to loaded shims. CORE-11329
[reactos.git] / reactos / dll / appcompat / apphelp / shimeng.c
1 /*
2 * Copyright 2015-2017 Mark Jansen
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #define WIN32_NO_STATUS
20 #include "windows.h"
21 #include "ntndk.h"
22 #include "shimlib.h"
23 #include <strsafe.h>
24
25 HANDLE g_pShimEngModHandle = 0;
26
27
28 ULONG g_ShimEngDebugLevel = 0xffffffff;
29
30
31
32
33 VOID SeiInitDebugSupport(VOID)
34 {
35 static const UNICODE_STRING DebugKey = RTL_CONSTANT_STRING(L"SHIMENG_DEBUG_LEVEL");
36 UNICODE_STRING DebugValue;
37 NTSTATUS Status;
38 ULONG NewLevel = 0;
39 WCHAR Buffer[40];
40
41 RtlInitEmptyUnicodeString(&DebugValue, Buffer, sizeof(Buffer));
42
43 Status = RtlQueryEnvironmentVariable_U(NULL, &DebugKey, &DebugValue);
44
45 if (NT_SUCCESS(Status))
46 {
47 if (!NT_SUCCESS(RtlUnicodeStringToInteger(&DebugValue, 10, &NewLevel)))
48 NewLevel = 0;
49 }
50 g_ShimEngDebugLevel = NewLevel;
51 }
52
53
54 /**
55 * Outputs diagnostic info.
56 *
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.
62 *
63 * @return Success: TRUE Failure: FALSE.
64 */
65 BOOL WINAPIV SeiDbgPrint(SEI_LOG_LEVEL Level, PCSTR Function, PCSTR Format, ...)
66 {
67 char Buffer[512];
68 char* Current = Buffer;
69 const char* LevelStr;
70 size_t Length = sizeof(Buffer);
71 va_list ArgList;
72 HRESULT hr;
73
74 if (g_ShimEngDebugLevel == 0xffffffff)
75 SeiInitDebugSupport();
76
77 if (Level > g_ShimEngDebugLevel)
78 return FALSE;
79
80 switch (Level)
81 {
82 case SEI_MSG:
83 LevelStr = "MSG ";
84 break;
85 case SEI_FAIL:
86 LevelStr = "FAIL";
87 break;
88 case SEI_WARN:
89 LevelStr = "WARN";
90 break;
91 case SEI_INFO:
92 LevelStr = "INFO";
93 break;
94 default:
95 LevelStr = "USER";
96 break;
97 }
98
99 if (Function)
100 hr = StringCchPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, "[%s] [%s] ", LevelStr, Function);
101 else
102 hr = StringCchPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, "[%s] ", LevelStr);
103
104 if (!SUCCEEDED(hr))
105 return FALSE;
106
107 va_start(ArgList, Format);
108 hr = StringCchVPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, Format, ArgList);
109 va_end(ArgList);
110 if (!SUCCEEDED(hr))
111 return FALSE;
112
113 DbgPrint("%s", Buffer);
114 return TRUE;
115 }
116
117
118
119
120
121
122 VOID NotifyShims(DWORD dwReason, PVOID Info)
123 {
124 /* Enumerate all loaded shims */
125 }
126
127
128 VOID NTAPI SE_InstallBeforeInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
129 {
130 SHIMENG_FAIL("(%wZ, %p)", ProcessImage, pShimData);
131 /* Find & Load all shims.. */
132 }
133
134 VOID NTAPI SE_InstallAfterInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
135 {
136 SHIMENG_FAIL("(%wZ, %p)", ProcessImage, pShimData);
137 NotifyShims(SHIM_NOTIFY_ATTACH, NULL);
138 }
139
140 VOID NTAPI SE_ProcessDying(VOID)
141 {
142 SHIMENG_FAIL("()");
143 NotifyShims(SHIM_NOTIFY_DETACH, NULL);
144 }
145
146 VOID WINAPI SE_DllLoaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
147 {
148 SHIMENG_FAIL("(%p)", LdrEntry);
149 NotifyShims(SHIM_REASON_DLL_LOAD, LdrEntry);
150 }
151
152 VOID WINAPI SE_DllUnloaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
153 {
154 SHIMENG_FAIL("(%p)", LdrEntry);
155 NotifyShims(SHIM_REASON_DLL_UNLOAD, LdrEntry);
156 }
157
158 BOOL WINAPI SE_IsShimDll(PVOID BaseAddress)
159 {
160 SHIMENG_FAIL("(%p)", BaseAddress);
161 return FALSE;
162 }
163