ยปCore Development>Code coverage>PC/dl_nt.c

Python code coverage for PC/dl_nt.c

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