~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to PC/dl_nt.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
Entry point for the Windows NT DLL.
 
4
 
 
5
About the only reason for having this, is so initall() can automatically
 
6
be called, removing that burden (and possible source of frustration if 
 
7
forgotten) from the programmer.
 
8
 
 
9
*/
 
10
 
 
11
#include "Python.h"
 
12
#include "windows.h"
 
13
 
 
14
#ifdef Py_ENABLE_SHARED
 
15
char dllVersionBuffer[16] = ""; // a private buffer
 
16
 
 
17
// Python Globals
 
18
HMODULE PyWin_DLLhModule = NULL;
 
19
const char *PyWin_DLLVersionString = dllVersionBuffer;
 
20
 
 
21
// Windows "Activation Context" work:
 
22
// Our .pyd extension modules are generally built without a manifest (ie,
 
23
// those included with Python and those built with a default distutils.
 
24
// This requires we perform some "activation context" magic when loading our
 
25
// extensions.  In summary:
 
26
// * As our DLL loads we save the context being used.
 
27
// * Before loading our extensions we re-activate our saved context.
 
28
// * After extension load is complete we restore the old context.
 
29
// As an added complication, this magic only works on XP or later - we simply
 
30
// use the existence (or not) of the relevant function pointers from kernel32.
 
31
// See bug 4566 (http://python.org/sf/4566) for more details.
 
32
 
 
33
typedef BOOL (WINAPI * PFN_GETCURRENTACTCTX)(HANDLE *);
 
34
typedef BOOL (WINAPI * PFN_ACTIVATEACTCTX)(HANDLE, ULONG_PTR *);
 
35
typedef BOOL (WINAPI * PFN_DEACTIVATEACTCTX)(DWORD, ULONG_PTR);
 
36
typedef BOOL (WINAPI * PFN_ADDREFACTCTX)(HANDLE);
 
37
typedef BOOL (WINAPI * PFN_RELEASEACTCTX)(HANDLE);
 
38
 
 
39
// locals and function pointers for this activation context magic.
 
40
static HANDLE PyWin_DLLhActivationContext = NULL; // one day it might be public
 
41
static PFN_GETCURRENTACTCTX pfnGetCurrentActCtx = NULL;
 
42
static PFN_ACTIVATEACTCTX pfnActivateActCtx = NULL;
 
43
static PFN_DEACTIVATEACTCTX pfnDeactivateActCtx = NULL;
 
44
static PFN_ADDREFACTCTX pfnAddRefActCtx = NULL;
 
45
static PFN_RELEASEACTCTX pfnReleaseActCtx = NULL;
 
46
 
 
47
void _LoadActCtxPointers()
 
48
{
 
49
        HINSTANCE hKernel32 = GetModuleHandleW(L"kernel32.dll");
 
50
        if (hKernel32)
 
51
                pfnGetCurrentActCtx = (PFN_GETCURRENTACTCTX) GetProcAddress(hKernel32, "GetCurrentActCtx");
 
52
        // If we can't load GetCurrentActCtx (ie, pre XP) , don't bother with the rest.
 
53
        if (pfnGetCurrentActCtx) {
 
54
                pfnActivateActCtx = (PFN_ACTIVATEACTCTX) GetProcAddress(hKernel32, "ActivateActCtx");
 
55
                pfnDeactivateActCtx = (PFN_DEACTIVATEACTCTX) GetProcAddress(hKernel32, "DeactivateActCtx");
 
56
                pfnAddRefActCtx = (PFN_ADDREFACTCTX) GetProcAddress(hKernel32, "AddRefActCtx");
 
57
                pfnReleaseActCtx = (PFN_RELEASEACTCTX) GetProcAddress(hKernel32, "ReleaseActCtx");
 
58
        }
 
59
}
 
60
 
 
61
ULONG_PTR _Py_ActivateActCtx()
 
62
{
 
63
        ULONG_PTR ret = 0;
 
64
        if (PyWin_DLLhActivationContext && pfnActivateActCtx)
 
65
                if (!(*pfnActivateActCtx)(PyWin_DLLhActivationContext, &ret)) {
 
66
                        OutputDebugString("Python failed to activate the activation context before loading a DLL\n");
 
67
                        ret = 0; // no promise the failing function didn't change it!
 
68
                }
 
69
        return ret;
 
70
}
 
71
 
 
72
void _Py_DeactivateActCtx(ULONG_PTR cookie)
 
73
{
 
74
        if (cookie && pfnDeactivateActCtx)
 
75
                if (!(*pfnDeactivateActCtx)(0, cookie))
 
76
                        OutputDebugString("Python failed to de-activate the activation context\n");
 
77
}
 
78
 
 
79
BOOL    WINAPI  DllMain (HANDLE hInst, 
 
80
                                                ULONG ul_reason_for_call,
 
81
                                                LPVOID lpReserved)
 
82
{
 
83
        switch (ul_reason_for_call)
 
84
        {
 
85
                case DLL_PROCESS_ATTACH:
 
86
                        PyWin_DLLhModule = hInst;
 
87
                        // 1000 is a magic number I picked out of the air.  Could do with a #define, I spose...
 
88
                        LoadString(hInst, 1000, dllVersionBuffer, sizeof(dllVersionBuffer));
 
89
 
 
90
                        // and capture our activation context for use when loading extensions.
 
91
                        _LoadActCtxPointers();
 
92
                        if (pfnGetCurrentActCtx && pfnAddRefActCtx)
 
93
                                if ((*pfnGetCurrentActCtx)(&PyWin_DLLhActivationContext))
 
94
                                        if (!(*pfnAddRefActCtx)(PyWin_DLLhActivationContext))
 
95
                                                OutputDebugString("Python failed to load the default activation context\n");
 
96
                        break;
 
97
 
 
98
                case DLL_PROCESS_DETACH:
 
99
                        if (pfnReleaseActCtx)
 
100
                                (*pfnReleaseActCtx)(PyWin_DLLhActivationContext);
 
101
                        break;
 
102
        }
 
103
        return TRUE;
 
104
}
 
105
 
 
106
#endif /* Py_ENABLE_SHARED */