144 lines
2.8 KiB
C++
144 lines
2.8 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
IgnoreFreeLibrary.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Some applications free DLLs before they're actually ready to. When this occurs,
|
||
|
if the offending application attempts to make a call to an exported function,
|
||
|
the call fails. This results in an access violation.
|
||
|
|
||
|
This shim takes a command line of ; delimited DLL names. For each DLL on the command
|
||
|
line, a call to FreeLibrary for the specified DLL will be ignored.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
xanim.dll
|
||
|
|
||
|
video_3dfx.dll;glide.dll
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
This is a general purpose shim.
|
||
|
|
||
|
History:
|
||
|
|
||
|
10/31/2000 rparsons Created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
IMPLEMENT_SHIM_BEGIN(IgnoreFreeLibrary)
|
||
|
#include "ShimHookMacro.h"
|
||
|
|
||
|
APIHOOK_ENUM_BEGIN
|
||
|
APIHOOK_ENUM_ENTRY(FreeLibrary)
|
||
|
APIHOOK_ENUM_END
|
||
|
|
||
|
#define MAX_FILES 64
|
||
|
|
||
|
int g_nLibraryCountFreeLibrary = 0;
|
||
|
CString * g_rgLibrariesToIgnoreFreeLibrary = NULL;
|
||
|
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Hook the call to FreeLibrary. Determine if the file name that corresponds to this
|
||
|
module should be ignored.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
APIHOOK(FreeLibrary)(
|
||
|
HMODULE hModule
|
||
|
)
|
||
|
{
|
||
|
CSTRING_TRY
|
||
|
{
|
||
|
CString csModule;
|
||
|
csModule.GetModuleFileNameW(hModule);
|
||
|
|
||
|
CString csFileName;
|
||
|
csModule.GetLastPathComponent(csFileName);
|
||
|
|
||
|
for (int i = 0; i < g_nLibraryCountFreeLibrary; ++i)
|
||
|
{
|
||
|
if (csFileName.CompareNoCase(g_rgLibrariesToIgnoreFreeLibrary[i]) == 0)
|
||
|
{
|
||
|
DPFN( eDbgLevelInfo, "Caught attempt freeing %S\n", csModule.Get());
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
CSTRING_CATCH
|
||
|
{
|
||
|
// Do Nothing
|
||
|
}
|
||
|
|
||
|
return ORIGINAL_API(FreeLibrary)(hModule);
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
This function parses the COMMAND_LINE for the libraries that should
|
||
|
have their FreeLibrary call ignored.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL ParseCommandLine()
|
||
|
{
|
||
|
CSTRING_TRY
|
||
|
{
|
||
|
CString csCl(COMMAND_LINE);
|
||
|
CStringParser csParser(csCl, L";");
|
||
|
|
||
|
g_nLibraryCountFreeLibrary = csParser.GetCount();
|
||
|
g_rgLibrariesToIgnoreFreeLibrary = csParser.ReleaseArgv();
|
||
|
}
|
||
|
CSTRING_CATCH
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < g_nLibraryCountFreeLibrary; ++i) {
|
||
|
DPFN( eDbgLevelInfo, "Library %d: name: --%S--\n", i, g_rgLibrariesToIgnoreFreeLibrary[i].Get());
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
NOTIFY_FUNCTION(
|
||
|
DWORD fdwReason
|
||
|
)
|
||
|
{
|
||
|
if (fdwReason == DLL_PROCESS_ATTACH) {
|
||
|
return ParseCommandLine();
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Register hooked functions
|
||
|
|
||
|
--*/
|
||
|
|
||
|
HOOK_BEGIN
|
||
|
|
||
|
CALL_NOTIFY_FUNCTION
|
||
|
APIHOOK_ENTRY(KERNEL32.DLL, FreeLibrary)
|
||
|
|
||
|
HOOK_END
|
||
|
|
||
|
|
||
|
IMPLEMENT_SHIM_END
|
||
|
|