ReactOS  0.4.14-dev-317-g96040ec
shimlib.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Shim helper library
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Shim helper functions
5  * COPYRIGHT: Copyright 2016-2018 Mark Jansen (mark.jansen@reactos.org)
6  */
7 
8 #define WIN32_NO_STATUS
9 #include <windef.h>
10 #include <winbase.h>
11 #include <shimlib.h>
12 #include <strsafe.h>
13 #include <ndk/rtlfuncs.h>
14 
15 typedef struct UsedShim
16 {
19 #if (WINVER > _WIN32_WINNT_WS03)
20  BOOL bInitCalled;
21 #endif
23 
24 
29 
31 {
33  g_ShimLib_Heap = HeapCreate(0, 0x10000, 0);
34 
37 }
38 
40 {
41  // Is this a good idea?
43 }
44 
46 {
47  return HeapAlloc(g_ShimLib_Heap, 0, dwSize);
48 }
49 
51 {
53 }
54 
56 {
57  return g_ShimLib_hInstance;
58 }
59 
60 PCSTR ShimLib_StringNDuplicateA(PCSTR szString, SIZE_T stringLengthIncludingNullTerm)
61 {
62  PSTR NewString = ShimLib_ShimMalloc(stringLengthIncludingNullTerm);
63  StringCchCopyA(NewString, stringLengthIncludingNullTerm, szString);
64  return NewString;
65 }
66 
68 {
69  return ShimLib_StringNDuplicateA(szString, lstrlenA(szString) + 1);
70 }
71 
72 BOOL ShimLib_StrAEqualsWNC(PCSTR szString, PCWSTR wszString)
73 {
74  while (toupper(*szString) == towupper(*wszString))
75  {
76  if (!*szString)
77  return TRUE;
78 
79  szString++; wszString++;
80  }
81  return FALSE;
82 }
83 
84 #if defined(_MSC_VER)
85 
86 #if defined(_M_IA64) || defined(_M_AMD64)
87 #define _ATTRIBUTES read
88 #else
89 #define _ATTRIBUTES read
90 #endif
91 
92 
93 #pragma section(".shm",long,read)
94 #pragma section(".shm$AAA",long,read)
95 #pragma section(".shm$ZZZ",long,read)
96 #endif
97 
98 #ifdef _MSC_VER
99 #pragma comment(linker, "/merge:.shm=.rdata")
100 #endif
101 
102 
103 _SHMALLOC(".shm") SHIMREG _shim_start = { 0 };
104 _SHMALLOC(".shm$ZZZ") SHIMREG _shim_end = { 0 };
105 
106 
107 /* Generic GetHookAPIs function.
108  The macro's from <setup_shim.inl> and <implement_shim.inl> will register a list of all apis that should be hooked
109  for a specific shim
110  This helper function will return the correct shim, and call the init function */
111 PHOOKAPI WINAPI ShimLib_GetHookAPIs(IN LPCSTR szCommandLine, IN LPCWSTR wszShimName, OUT PDWORD pdwHookCount)
112 {
113  PSHIMREG ps = &_shim_start;
114  ps++;
115  for (; ps != &_shim_end; ps++)
116  {
117  if (ps->GetHookAPIs != NULL && ps->ShimName != NULL)
118  {
119  if (ShimLib_StrAEqualsWNC(ps->ShimName, wszShimName))
120  {
122  shim->pShim = ps;
123 #if (WINVER > _WIN32_WINNT_WS03)
124  shim->bInitCalled = FALSE;
125 #endif
127 
128  return ps->GetHookAPIs(SHIM_NOTIFY_ATTACH, szCommandLine, pdwHookCount);
129  }
130  }
131  }
132  return NULL;
133 }
134 
135 
137 {
139 
140  if (fdwReason < SHIM_REASON_INIT)
141  fdwReason += (SHIM_REASON_INIT - SHIM_NOTIFY_ATTACH);
142 
143  while (pEntry)
144  {
145  pUsedShim pUsed = CONTAINING_RECORD(pEntry, UsedShim, Entry);
146  _PVNotify Notify = pUsed->pShim->Notify;
147 #if (WINVER > _WIN32_WINNT_WS03)
148  if (pUsed->bInitCalled && fdwReason == SHIM_REASON_INIT)
149  Notify = NULL;
150 #endif
151  if (Notify)
152  Notify(fdwReason, ptr);
153 #if (WINVER > _WIN32_WINNT_WS03)
154  if (fdwReason == SHIM_REASON_INIT)
155  pUsed->bInitCalled = TRUE;
156 #endif
157 
158  pEntry = pEntry->Next;
159  }
160 
161  return TRUE;
162 }
163 
164 
166 {
167  static const UNICODE_STRING DebugKey = RTL_CONSTANT_STRING(L"SHIM_DEBUG_LEVEL");
168  UNICODE_STRING DebugValue;
170  ULONG NewLevel = SEI_MSG;
171  WCHAR Buffer[40];
172 
173  RtlInitEmptyUnicodeString(&DebugValue, Buffer, sizeof(Buffer));
174 
175  Status = RtlQueryEnvironmentVariable_U(NULL, &DebugKey, &DebugValue);
176 
177  if (NT_SUCCESS(Status))
178  {
179  if (!NT_SUCCESS(RtlUnicodeStringToInteger(&DebugValue, 10, &NewLevel)))
180  NewLevel = 0;
181  }
182  g_ShimEngDebugLevel = NewLevel;
183 }
184 
185 
198 {
199  char Buffer[512];
200  char* Current = Buffer;
201  const char* LevelStr;
202  size_t Length = sizeof(Buffer);
203  va_list ArgList;
204  HRESULT hr;
205 
206  if (g_ShimEngDebugLevel == 0xffffffff)
208 
210  return FALSE;
211 
212  switch (Level)
213  {
214  case SEI_MSG:
215  LevelStr = "MSG ";
216  break;
217  case SEI_FAIL:
218  LevelStr = "FAIL";
219  break;
220  case SEI_WARN:
221  LevelStr = "WARN";
222  break;
223  case SEI_INFO:
224  LevelStr = "INFO";
225  break;
226  default:
227  LevelStr = "USER";
228  break;
229  }
230 
231  if (Function)
232  hr = StringCchPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, "[%s] [%s] ", LevelStr, Function);
233  else
234  hr = StringCchPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, "[%s] ", LevelStr);
235 
236  if (!SUCCEEDED(hr))
237  return FALSE;
238 
239  va_start(ArgList, Format);
240  hr = StringCchVPrintfExA(Current, Length, &Current, &Length, STRSAFE_NULL_ON_FAILURE, Format, ArgList);
241  va_end(ArgList);
242  if (!SUCCEEDED(hr))
243  return FALSE;
244 
245  DbgPrint("%s", Buffer);
246  return TRUE;
247 }
248 
BOOL WINAPI SHIM_OBJ_NAME() Notify(DWORD fdwReason, PVOID ptr)
HINSTANCE ShimLib_Instance(VOID)
Definition: shimlib.c:55
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
_Must_inspect_result_ NTSYSAPI PSLIST_ENTRY NTAPI RtlFirstEntrySList(_In_ const SLIST_HEADER *ListHead)
Definition: slist.c:51
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define DbgPrint
Definition: loader.c:25
STRSAFEAPI StringCchVPrintfExA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPSTR *ppszDestEnd, size_t *pcchRemaining, STRSAFE_DWORD dwFlags, STRSAFE_LPCSTR pszFormat, va_list argList)
Definition: strsafe.h:650
HANDLE WINAPI HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize)
Definition: heapmem.c:45
_PVGetHookAPIs GetHookAPIs
Definition: shimlib.h:86
LONG NTSTATUS
Definition: precomp.h:26
struct UsedShim UsedShim
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
STRSAFEAPI StringCchPrintfExA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPSTR *ppszDestEnd, size_t *pcchRemaining, STRSAFE_DWORD dwFlags, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:575
_SHMALLOC(".shm")
Definition: shimlib.c:103
struct UsedShim * pUsedShim
BOOL ShimLib_StrAEqualsWNC(PCSTR szString, PCWSTR wszString)
Definition: shimlib.c:72
PHOOKAPI WINAPI ShimLib_GetHookAPIs(IN LPCSTR szCommandLine, IN LPCWSTR wszShimName, OUT PDWORD pdwHookCount)
Definition: shimlib.c:111
void ShimLib_Init(HINSTANCE hInstance)
Definition: shimlib.c:30
BOOL WINAPI HeapDestroy(HANDLE hHeap)
Definition: heapmem.c:85
PCSTR ShimLib_StringDuplicateA(PCSTR szString)
Definition: shimlib.c:67
BOOL WINAPIV SeiDbgPrint(SEI_LOG_LEVEL Level, PCSTR Function, PCSTR Format,...)
Definition: shimlib.c:197
HINSTANCE hInstance
Definition: charmap.c:20
void ShimLib_Deinit(VOID)
Definition: shimlib.c:39
#define va_end(ap)
Definition: acmsvcex.h:90
static LPOVERLAPPED_COMPLETION_ROUTINE Function
Definition: sync.c:684
unsigned int BOOL
Definition: ntddk_ex.h:94
static PVOID ptr
Definition: dispmode.c:27
NTSYSAPI NTSTATUS NTAPI RtlQueryEnvironmentVariable_U(_In_opt_ PWSTR Environment, _In_ PCUNICODE_STRING Name, _Out_ PUNICODE_STRING Value)
smooth NULL
Definition: ftsmooth.c:416
#define SHIM_REASON_INIT
Definition: shimlib.h:45
char * va_list
Definition: acmsvcex.h:78
Definition: bufpool.h:45
const char * LPCSTR
Definition: xmlstorage.h:183
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PCSTR ShimLib_StringNDuplicateA(PCSTR szString, SIZE_T stringLengthIncludingNullTerm)
Definition: shimlib.c:60
#define SHIM_NOTIFY_ATTACH
Definition: shimlib.h:50
ULONG g_ShimEngDebugLevel
Definition: shimlib.c:25
int toupper(int c)
Definition: utclib.c:881
NTSYSAPI PSLIST_ENTRY NTAPI RtlInterlockedPushEntrySList(_Inout_ PSLIST_HEADER ListHead, _Inout_ __drv_aliasesMem PSLIST_ENTRY ListEntry)
Definition: slist.c:157
BOOL(WINAPI * _PVNotify)(DWORD, PVOID)
Definition: shimlib.h:82
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_PVNotify Notify
Definition: shimlib.h:87
LONG HRESULT
Definition: typedefs.h:77
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
#define PSLIST_ENTRY
Definition: rtltypes.h:130
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static const WCHAR L[]
Definition: oid.c:1250
#define WINAPIV
Definition: sdbpapi.h:64
Status
Definition: gdiplustypes.h:24
union _SLIST_HEADER * PSLIST_HEADER
PVOID ShimLib_ShimMalloc(SIZE_T dwSize)
Definition: shimlib.c:45
enum _SEI_LOG_LEVEL SEI_LOG_LEVEL
NTSYSAPI VOID NTAPI RtlInitializeSListHead(_Out_ PSLIST_HEADER ListHead)
Definition: slist.c:25
ULONG_PTR SIZE_T
Definition: typedefs.h:78
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
static PSLIST_HEADER g_UsedShims
Definition: shimlib.c:28
SLIST_ENTRY Entry
Definition: shimlib.c:17
signed char * PSTR
Definition: retypes.h:7
static HANDLE g_ShimLib_Heap
Definition: shimlib.c:27
#define va_start(ap, A)
Definition: acmsvcex.h:91
VOID SeiInitDebugSupport(VOID)
Definition: shimlib.c:165
DWORD * PDWORD
Definition: pedump.c:68
#define SLIST_ENTRY(type)
Definition: queue.h:102
#define STRSAFE_NULL_ON_FAILURE
Definition: ntstrsafe.h:34
#define OUT
Definition: typedefs.h:39
static HINSTANCE g_ShimLib_hInstance
Definition: shimlib.c:26
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
unsigned int ULONG
Definition: retypes.h:1
const char * PCSTR
Definition: typedefs.h:51
#define towupper(c)
Definition: wctype.h:99
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
BOOL WINAPI ShimLib_NotifyShims(DWORD fdwReason, PVOID ptr)
Definition: shimlib.c:136
#define HeapFree(x, y, z)
Definition: compat.h:394
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
base of all file and directory entries
Definition: entries.h:82
#define SUCCEEDED(hr)
Definition: intsafe.h:57
PSHIMREG pShim
Definition: shimlib.c:18
PCSTR ShimName
Definition: shimlib.h:88
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
void ShimLib_ShimFree(PVOID pData)
Definition: shimlib.c:50