8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-01 04:43:03 +01:00
firebird-mirror/src/jrd/os/win32/mod_loader.cpp

203 lines
4.4 KiB
C++
Raw Normal View History

/*
* mod_loader.cpp
*
*/
// required to use activation context API structures
#define _WIN32_WINNT 0x0501
2006-07-27 14:19:30 +02:00
#include "firebird.h"
#include "../jrd/os/mod_loader.h"
#include <windows.h>
2002-11-17 16:46:24 +01:00
typedef Firebird::string string;
2004-02-08 18:08:34 +01:00
typedef Firebird::PathName PathName;
2002-11-17 16:46:24 +01:00
/// This is the Win32 implementation of the mod_loader abstraction.
HINSTANCE hDllInst = 0;
BOOL bEmbedded = false;
/// activation context API prototypes
typedef HANDLE (WINAPI * PFN_CAC)(PCACTCTXA pActCtx);
typedef BOOL (WINAPI * PFN_FINDAC)(DWORD dwFlags,
const GUID *lpExtensionGuid,
ULONG ulSectionId,
LPCSTR lpStringToFind,
PACTCTX_SECTION_KEYED_DATA ReturnedData);
typedef void (WINAPI * PFN_RAC)(HANDLE hActCtx);
typedef BOOL (WINAPI * PFN_AAC)(HANDLE hActCtx, ULONG_PTR *lpCookie);
typedef BOOL (WINAPI * PFN_DAC)(DWORD dwFlags, ULONG_PTR ulCookie);
/// end of activation context API prototypes
template <typename PFN>
class WinApiFunction
{
public:
WinApiFunction(const char *dllName, const char *fnName)
{
m_ptr = NULL;
const HMODULE hDll = GetModuleHandle(dllName);
if (hDll)
m_ptr = (PFN) GetProcAddress(hDll, fnName);
}
~WinApiFunction()
{}
PFN operator* () const
{ return m_ptr; }
operator bool() const
{ return (m_ptr != NULL); }
private:
PFN m_ptr;
};
const char* sKernel32 = "kernel32.dll";
class ContextActivator
{
public:
ContextActivator() :
mFindActCtxSectionString(sKernel32, "FindActCtxSectionStringA"),
mCreateActCtx(sKernel32, "CreateActCtxA"),
mReleaseActCtx(sKernel32, "ReleaseActCtx"),
mActivateActCtx(sKernel32, "ActivateActCtx"),
mDeactivateActCtx(sKernel32, "DeactivateActCtx")
{
hActCtx = INVALID_HANDLE_VALUE;
// if we don't use MSVC then we don't use MS CRT ?
#ifndef _MSC_VER
return;
#endif
if (!bEmbedded || !mCreateActCtx)
return;
ACTCTX_SECTION_KEYED_DATA ackd;
memset(&ackd, 0, sizeof(ackd));
ackd.cbSize = sizeof(ackd);
// if CRT already present in some activation context then nothing to do
if ((*mFindActCtxSectionString)
(0, NULL,
ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
#if _MSC_VER == 1400
"msvcr80.dll",
#else
#error Specify CRT DLL name here !
#endif
&ackd))
return;
// create and use activation context from our own manifest
ACTCTXA actCtx;
memset(&actCtx, 0, sizeof(actCtx));
actCtx.cbSize = sizeof(actCtx);
actCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID;
actCtx.lpResourceName = ISOLATIONAWARE_MANIFEST_RESOURCE_ID;
actCtx.hModule = hDllInst;
if (actCtx.hModule)
{
char name[1024];
GetModuleFileName(actCtx.hModule, name, sizeof(name));
actCtx.lpSource = name;
hActCtx = (*mCreateActCtx) (&actCtx);
if (hActCtx != INVALID_HANDLE_VALUE)
(*mActivateActCtx) (hActCtx, &mCookie);
}
}
~ContextActivator()
{
if (hActCtx != INVALID_HANDLE_VALUE)
{
(*mDeactivateActCtx)(0, mCookie);
(*mReleaseActCtx)(hActCtx);
}
}
private:
WinApiFunction<PFN_FINDAC> mFindActCtxSectionString;
WinApiFunction<PFN_CAC> mCreateActCtx;
WinApiFunction<PFN_RAC> mReleaseActCtx;
WinApiFunction<PFN_AAC> mActivateActCtx;
WinApiFunction<PFN_DAC> mDeactivateActCtx;
HANDLE hActCtx;
ULONG_PTR mCookie;
};
class Win32Module : public ModuleLoader::Module
{
public:
Win32Module(HMODULE m) : module(m) {}
~Win32Module();
2002-11-17 16:46:24 +01:00
void *findSymbol(const string&);
2008-12-05 02:20:14 +01:00
private:
HMODULE module;
};
2004-02-08 18:08:34 +01:00
bool ModuleLoader::isLoadableModule(const PathName& module)
{
ContextActivator ctx;
2003-03-14 12:28:10 +01:00
LPCSTR pszName = module.c_str();
HINSTANCE hMod = LoadLibraryEx(pszName, 0,
LOAD_WITH_ALTERED_SEARCH_PATH | LOAD_LIBRARY_AS_DATAFILE);
2003-03-14 12:28:10 +01:00
if (hMod) {
FreeLibrary((HMODULE)hMod);
}
return hMod != 0;
}
2004-02-08 18:08:34 +01:00
void ModuleLoader::doctorModuleExtention(Firebird::PathName& name)
{
2004-02-08 18:08:34 +01:00
PathName::size_type pos = name.rfind(".dll");
if (pos != PathName::npos && pos == name.length() - 4)
2002-11-17 16:46:24 +01:00
return;
name += ".dll";
}
2004-02-08 18:08:34 +01:00
ModuleLoader::Module *ModuleLoader::loadModule(const Firebird::PathName& modPath)
{
ContextActivator ctx;
HMODULE module = LoadLibraryEx(modPath.c_str(), 0, LOAD_WITH_ALTERED_SEARCH_PATH);
if (!module)
return 0;
2008-12-05 02:20:14 +01:00
return FB_NEW(*getDefaultMemoryPool()) Win32Module(module);
}
Win32Module::~Win32Module()
{
if (module)
FreeLibrary(module);
}
void *Win32Module::findSymbol(const Firebird::string& symName)
{
2002-11-17 16:46:24 +01:00
FARPROC result = GetProcAddress(module, symName.c_str());
if (!result)
{
2002-11-17 16:46:24 +01:00
string newSym = '_' + symName;
result = GetProcAddress(module, newSym.c_str());
}
2002-11-26 09:56:06 +01:00
return (void*) result;
}