mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 03:22:27 +00:00 
			
		
		
		
	svn+ssh://pythondev@svn.python.org/python/trunk ........ r81029 | antoine.pitrou | 2010-05-09 16:46:46 +0200 (dim., 09 mai 2010) | 3 lines Untabify C files. Will watch buildbots. ........
		
			
				
	
	
		
			106 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 | 
						|
Entry point for the Windows NT DLL.
 | 
						|
 | 
						|
About the only reason for having this, is so initall() can automatically
 | 
						|
be called, removing that burden (and possible source of frustration if
 | 
						|
forgotten) from the programmer.
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
#include "Python.h"
 | 
						|
#include "windows.h"
 | 
						|
 | 
						|
#ifdef Py_ENABLE_SHARED
 | 
						|
char dllVersionBuffer[16] = ""; // a private buffer
 | 
						|
 | 
						|
// Python Globals
 | 
						|
HMODULE PyWin_DLLhModule = NULL;
 | 
						|
const char *PyWin_DLLVersionString = dllVersionBuffer;
 | 
						|
 | 
						|
// 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.
 | 
						|
 | 
						|
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");
 | 
						|
}
 | 
						|
 | 
						|
BOOL    WINAPI  DllMain (HANDLE hInst,
 | 
						|
                                                ULONG ul_reason_for_call,
 | 
						|
                                                LPVOID lpReserved)
 | 
						|
{
 | 
						|
    switch (ul_reason_for_call)
 | 
						|
    {
 | 
						|
        case DLL_PROCESS_ATTACH:
 | 
						|
            PyWin_DLLhModule = 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));
 | 
						|
 | 
						|
            // 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");
 | 
						|
            break;
 | 
						|
 | 
						|
        case DLL_PROCESS_DETACH:
 | 
						|
            if (pfnReleaseActCtx)
 | 
						|
                (*pfnReleaseActCtx)(PyWin_DLLhActivationContext);
 | 
						|
            break;
 | 
						|
    }
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* Py_ENABLE_SHARED */
 |