Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

254 lines
4.7 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
All rights reserved
Module Name:
loadwrap.cxx
Abstract:
This implements a wrapper for all spooler calls to the loader to ensure that
no exceptions are thrown from the loader and that on exit to every loader call,
the owner of the loader lock is not the current thread. This is in response to
a set of stress bugs where the loader lock is orphaned.
Author:
Mark Lawrence (mlawrenc) - 28 Feb 2001
Environment:
User Mode -Win32
Revision History:
--*/
#include "spllibp.hxx"
#include "loadwrap.hxx"
//
// Redefine all of the loader calls back to sanity.
//
#undef LoadLibrary
#undef GetProcAddress
#undef FreeLibrary
#undef LoadLibraryEx
#undef LoadResource
#undef LoadString
#ifdef UNICODE
#define LoadLibrary LoadLibraryW
#define LoadLibraryEx LoadLibraryExW
#define LoadString LoadStringW
#else
#define LoadLibrary LoadLibraryA
#define LoadLibraryEx LoadLibraryExA
#define LoadString LoadStringA
#endif // !UNICODE
inline
VOID
EnterNtLoaderLockCheck(
OUT BOOL *pbInLock
)
{
*pbInLock = NtCurrentTeb()->ClientId.UniqueThread ==
reinterpret_cast<PRTL_CRITICAL_SECTION>(NtCurrentPeb()->LoaderLock)->OwningThread;
if (*pbInLock)
{
DbgPrintEx(DPFLTR_PRINTSPOOLER_ID, DPFLTR_INFO_LEVEL, "Loader Lock owned by thread on entry. Probably LoadLibrary in DllMain.\n");
}
}
inline
VOID
CheckNotLoaderLockOwner(
IN BOOL bInLock
)
{
if (!bInLock &&
NtCurrentTeb()->ClientId.UniqueThread ==
reinterpret_cast<PRTL_CRITICAL_SECTION>(NtCurrentPeb()->LoaderLock)->OwningThread)
{
DbgPrint("Loader Lock owned by the current thread!\n");
DebugBreak();
}
}
inline
VOID
BreakAndAssert(
IN PCH pszMessage
)
{
DbgPrint("Unexpected Exception thrown from loader code : ");
DbgPrint(pszMessage);
DbgPrint(".\n");
DebugBreak();
}
EXTERN_C
HMODULE
WrapLoadLibrary(
IN LPCTSTR lpFileName
)
{
HMODULE hModule = NULL;
BOOL bLock = FALSE;
EnterNtLoaderLockCheck(&bLock);
__try
{
hModule = LoadLibrary(lpFileName);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
BreakAndAssert("LoadLibrary");
}
CheckNotLoaderLockOwner(bLock);
return hModule;
}
EXTERN_C
FARPROC
WrapGetProcAddress(
IN HMODULE hModule,
IN LPCSTR lpProcName
)
{
FARPROC pfnProc = NULL;
BOOL bLock = FALSE;
EnterNtLoaderLockCheck(&bLock);
__try
{
pfnProc = GetProcAddress(hModule, lpProcName);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
BreakAndAssert("GetProcAddress");
}
CheckNotLoaderLockOwner(bLock);
return pfnProc;
}
EXTERN_C
BOOL
WrapFreeLibrary(
IN HMODULE hModule
)
{
BOOL bRet = FALSE;
BOOL bLock = FALSE;
EnterNtLoaderLockCheck(&bLock);
__try
{
bRet = FreeLibrary(hModule);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
BreakAndAssert("FreeLibrary");
}
CheckNotLoaderLockOwner(bLock);
return bRet;
}
EXTERN_C
HMODULE
WrapLoadLibraryEx(
IN LPCTSTR lpFileName,
IN HANDLE hFile,
IN DWORD dwFlags
)
{
HMODULE hModule = NULL;
BOOL bLock = FALSE;
EnterNtLoaderLockCheck(&bLock);
__try
{
hModule = LoadLibraryEx(lpFileName, hFile, dwFlags);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
BreakAndAssert("LoadLibraryEx");
}
CheckNotLoaderLockOwner(bLock);
return hModule;
}
EXTERN_C
HGLOBAL
WrapLoadResource(
IN HMODULE hModule,
IN HRSRC hResInfo
)
{
HGLOBAL hGlobal = NULL;
BOOL bLock = FALSE;
EnterNtLoaderLockCheck(&bLock);
__try
{
hGlobal = LoadResource(hModule, hResInfo);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
BreakAndAssert("LoadResource");
}
CheckNotLoaderLockOwner(bLock);
return hGlobal;
}
EXTERN_C
int
WrapLoadString(
IN HINSTANCE hInstance,
IN UINT uID,
IN LPTSTR lpBuffer,
IN int nBufferMax
)
{
int iRet = 0;
BOOL bLock = FALSE;
EnterNtLoaderLockCheck(&bLock);
__try
{
iRet = LoadString(hInstance, uID, lpBuffer, nBufferMax);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
BreakAndAssert("LoadString");
}
CheckNotLoaderLockOwner(bLock);
return iRet;
}