|
|
|
@ -23,68 +23,6 @@ char dllVersionBuffer[16] = ""; // a private buffer |
|
|
|
HMODULE PyWin_DLLhModule = NULL; |
|
|
|
const char *PyWin_DLLVersionString = dllVersionBuffer; |
|
|
|
|
|
|
|
#if HAVE_SXS |
|
|
|
// Windows "Activation Context" work. |
|
|
|
// Our .pyd extension modules are generally built without a manifest (ie, |
|
|
|
// those included with Python and those built with a default distutils. |
|
|
|
// This requires we perform some "activation context" magic when loading our |
|
|
|
// extensions. In summary: |
|
|
|
// * As our DLL loads we save the context being used. |
|
|
|
// * Before loading our extensions we re-activate our saved context. |
|
|
|
// * After extension load is complete we restore the old context. |
|
|
|
// As an added complication, this magic only works on XP or later - we simply |
|
|
|
// use the existence (or not) of the relevant function pointers from kernel32. |
|
|
|
// See bug 4566 (http://python.org/sf/4566) for more details. |
|
|
|
// In Visual Studio 2010, side by side assemblies are no longer used by |
|
|
|
// default. |
|
|
|
|
|
|
|
typedef BOOL (WINAPI * PFN_GETCURRENTACTCTX)(HANDLE *); |
|
|
|
typedef BOOL (WINAPI * PFN_ACTIVATEACTCTX)(HANDLE, ULONG_PTR *); |
|
|
|
typedef BOOL (WINAPI * PFN_DEACTIVATEACTCTX)(DWORD, ULONG_PTR); |
|
|
|
typedef BOOL (WINAPI * PFN_ADDREFACTCTX)(HANDLE); |
|
|
|
typedef BOOL (WINAPI * PFN_RELEASEACTCTX)(HANDLE); |
|
|
|
|
|
|
|
// locals and function pointers for this activation context magic. |
|
|
|
static HANDLE PyWin_DLLhActivationContext = NULL; // one day it might be public |
|
|
|
static PFN_GETCURRENTACTCTX pfnGetCurrentActCtx = NULL; |
|
|
|
static PFN_ACTIVATEACTCTX pfnActivateActCtx = NULL; |
|
|
|
static PFN_DEACTIVATEACTCTX pfnDeactivateActCtx = NULL; |
|
|
|
static PFN_ADDREFACTCTX pfnAddRefActCtx = NULL; |
|
|
|
static PFN_RELEASEACTCTX pfnReleaseActCtx = NULL; |
|
|
|
|
|
|
|
void _LoadActCtxPointers() |
|
|
|
{ |
|
|
|
HINSTANCE hKernel32 = GetModuleHandleW(L"kernel32.dll"); |
|
|
|
if (hKernel32) |
|
|
|
pfnGetCurrentActCtx = (PFN_GETCURRENTACTCTX) GetProcAddress(hKernel32, "GetCurrentActCtx"); |
|
|
|
// If we can't load GetCurrentActCtx (ie, pre XP) , don't bother with the rest. |
|
|
|
if (pfnGetCurrentActCtx) { |
|
|
|
pfnActivateActCtx = (PFN_ACTIVATEACTCTX) GetProcAddress(hKernel32, "ActivateActCtx"); |
|
|
|
pfnDeactivateActCtx = (PFN_DEACTIVATEACTCTX) GetProcAddress(hKernel32, "DeactivateActCtx"); |
|
|
|
pfnAddRefActCtx = (PFN_ADDREFACTCTX) GetProcAddress(hKernel32, "AddRefActCtx"); |
|
|
|
pfnReleaseActCtx = (PFN_RELEASEACTCTX) GetProcAddress(hKernel32, "ReleaseActCtx"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ULONG_PTR _Py_ActivateActCtx() |
|
|
|
{ |
|
|
|
ULONG_PTR ret = 0; |
|
|
|
if (PyWin_DLLhActivationContext && pfnActivateActCtx) |
|
|
|
if (!(*pfnActivateActCtx)(PyWin_DLLhActivationContext, &ret)) { |
|
|
|
OutputDebugString("Python failed to activate the activation context before loading a DLL\n"); |
|
|
|
ret = 0; // no promise the failing function didn't change it! |
|
|
|
} |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
void _Py_DeactivateActCtx(ULONG_PTR cookie) |
|
|
|
{ |
|
|
|
if (cookie && pfnDeactivateActCtx) |
|
|
|
if (!(*pfnDeactivateActCtx)(0, cookie)) |
|
|
|
OutputDebugString("Python failed to de-activate the activation context\n"); |
|
|
|
} |
|
|
|
#endif /* HAVE_SXS */ |
|
|
|
|
|
|
|
BOOL WINAPI DllMain (HANDLE hInst, |
|
|
|
ULONG ul_reason_for_call, |
|
|
|
LPVOID lpReserved) |
|
|
|
@ -98,22 +36,9 @@ BOOL WINAPI DllMain (HANDLE hInst, |
|
|
|
// 1000 is a magic number I picked out of the air. Could do with a #define, I spose... |
|
|
|
LoadString(hInst, 1000, dllVersionBuffer, sizeof(dllVersionBuffer)); |
|
|
|
#endif |
|
|
|
|
|
|
|
#if HAVE_SXS |
|
|
|
// and capture our activation context for use when loading extensions. |
|
|
|
_LoadActCtxPointers(); |
|
|
|
if (pfnGetCurrentActCtx && pfnAddRefActCtx) |
|
|
|
if ((*pfnGetCurrentActCtx)(&PyWin_DLLhActivationContext)) |
|
|
|
if (!(*pfnAddRefActCtx)(PyWin_DLLhActivationContext)) |
|
|
|
OutputDebugString("Python failed to load the default activation context\n"); |
|
|
|
#endif |
|
|
|
break; |
|
|
|
|
|
|
|
case DLL_PROCESS_DETACH: |
|
|
|
#if HAVE_SXS |
|
|
|
if (pfnReleaseActCtx) |
|
|
|
(*pfnReleaseActCtx)(PyWin_DLLhActivationContext); |
|
|
|
#endif |
|
|
|
break; |
|
|
|
} |
|
|
|
return TRUE; |
|
|
|
|