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