ReactOS  0.4.13-dev-455-g28ed234
ignorefreelib.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS 'General' Shim library
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Ignore FreeLibrary calls
5  * COPYRIGHT: Copyright 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 
14 
15 #define SHIM_NS IgnoreFreeLibrary
16 #include <setup_shim.inl>
17 
19 
20 const char** g_Names;
21 static int g_NameCount;
22 
24 {
25  char Buffer[MAX_PATH], *Ptr = Buffer;
26  DWORD len, wanted = ARRAYSIZE(Buffer);
27  for (;;)
28  {
29  len = GetModuleFileNameA(hModule, Ptr, wanted);
30  if (len < wanted)
31  break;
32 
33  wanted *= 2;
34  if (Ptr != Buffer)
36 
37  Ptr = ShimLib_ShimMalloc(wanted);
38  if (!Ptr)
39  break;
40  }
41 
42  if (Ptr && len)
43  {
44  char* ModuleName = NULL;
45  int n;
46  for (; len; len--)
47  {
48  ModuleName = Ptr + len;
49  if (ModuleName[-1] == '/' || ModuleName[-1] == '\\')
50  break;
51  }
52  for (n = 0; n < g_NameCount; ++n)
53  {
54  if (!stricmp(g_Names[n], ModuleName))
55  {
56  SHIM_INFO("Prevented unload of %s\n", ModuleName);
57  if (Ptr && Ptr != Buffer)
59  return TRUE;
60  }
61  }
62  }
63 
64  if (Ptr && Ptr != Buffer)
66 
67  return CALL_SHIM(0, FREELIBRARYPROC)(hModule);
68 }
69 
70 static VOID InitIgnoreFreeLibrary(PCSTR CommandLine)
71 {
72  PCSTR prev, cur;
73  int count = 1, n = 0;
74  const char** names;
75 
76  if (!CommandLine || !*CommandLine)
77  return;
78 
79  prev = CommandLine;
80  while ((cur = strchr(prev, ';')))
81  {
82  count++;
83  prev = cur + 1;
84  }
85 
86  names = ShimLib_ShimMalloc(sizeof(char*) * count);
87  if (!names)
88  {
89  SHIM_WARN("Unable to allocate %u bytes\n", sizeof(char*) * count);
90  return;
91  }
92 
93  prev = CommandLine;
94  while ((cur = strchr(prev, ';')))
95  {
96  names[n] = ShimLib_StringNDuplicateA(prev, cur - prev + 1);
97  if (!names[n])
98  {
99  SHIM_WARN("Unable to allocate %u bytes\n", cur - prev + 2);
100  goto fail;
101  }
102  n++;
103  prev = cur + 1;
104  }
106  if (!names[n])
107  {
108  SHIM_WARN("Unable to allocate last string\n");
109  goto fail;
110  }
111 
112  g_Names = names;
113  g_NameCount = count;
114  return;
115 
116 fail:
117  --n;
118  while (n >= 0)
119  {
120  if (names[n])
122 
123  --n;
124  }
126 }
127 
128 BOOL WINAPI SHIM_OBJ_NAME(Notify)(DWORD fdwReason, PVOID ptr)
129 {
130  if (fdwReason == SHIM_NOTIFY_ATTACH)
131  {
132  SHIM_MSG("IgnoreFreeLibrary(%s)\n", SHIM_OBJ_NAME(g_szCommandLine));
133  InitIgnoreFreeLibrary(SHIM_OBJ_NAME(g_szCommandLine));
134  }
135  return TRUE;
136 }
137 
138 
139 #define SHIM_NOTIFY_FN SHIM_OBJ_NAME(Notify)
140 #define SHIM_NUM_HOOKS 1
141 #define SHIM_SETUP_HOOKS \
142  SHIM_HOOK(0, "KERNEL32.DLL", "FreeLibrary", SHIM_OBJ_NAME(FreeLibrary))
143 
144 #include <implement_shim.inl>
BOOL WINAPI SHIM_OBJ_NAME() Notify(DWORD fdwReason, PVOID ptr)
#define TRUE
Definition: types.h:120
GLuint GLuint GLsizei count
Definition: gl.h:1545
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
GLdouble n
Definition: glext.h:7729
const char ** g_Names
Definition: ignorefreelib.c:20
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
static int g_NameCount
Definition: ignorefreelib.c:21
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1252
BOOL(WINAPI * FREELIBRARYPROC)(HMODULE)
Definition: ignorefreelib.c:18
#define BOOL
Definition: nt_native.h:43
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:546
GLuint GLuint * names
Definition: glext.h:11545
PCSTR ShimLib_StringDuplicateA(PCSTR szString)
Definition: shimlib.c:67
unsigned int BOOL
Definition: ntddk_ex.h:94
static PVOID ptr
Definition: dispmode.c:27
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
PCSTR ShimLib_StringNDuplicateA(PCSTR szString, SIZE_T stringLengthIncludingNullTerm)
Definition: shimlib.c:60
#define SHIM_NOTIFY_ATTACH
Definition: shimlib.h:50
_Check_return_ _CRTIMP int __cdecl stricmp(_In_z_ const char *_Str1, _In_z_ const char *_Str2)
#define SHIM_MSG(fmt,...)
Definition: shimlib.h:75
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
GLenum GLsizei len
Definition: glext.h:6722
BOOL WINAPI SHIM_OBJ_NAME() FreeLibrary(HMODULE hModule)
Definition: ignorefreelib.c:23
HANDLE HMODULE
Definition: typedefs.h:75
PVOID ShimLib_ShimMalloc(SIZE_T dwSize)
Definition: shimlib.c:45
static VOID InitIgnoreFreeLibrary(PCSTR CommandLine)
Definition: ignorefreelib.c:70
char * strchr(const char *String, int ch)
Definition: utclib.c:501
const char * PCSTR
Definition: typedefs.h:51
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
HMODULE hModule
Definition: animate.c:44
void ShimLib_ShimFree(PVOID pData)
Definition: shimlib.c:50