| 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 | 
| Guido van Rossum | ec68092 | 1997-09-29 23:37:12 +0000 | [diff] [blame] | 15 | char dllVersionBuffer[16] = ""; // a private buffer | 
 | 16 |  | 
 | 17 | // Python Globals | 
| Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 18 | HMODULE PyWin_DLLhModule = NULL; | 
| Guido van Rossum | ec68092 | 1997-09-29 23:37:12 +0000 | [diff] [blame] | 19 | const char *PyWin_DLLVersionString = dllVersionBuffer; | 
 | 20 |  | 
| Mark Hammond | 9844a1f | 2009-01-27 23:46:57 +0000 | [diff] [blame] | 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 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 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 |     } | 
| Mark Hammond | 9844a1f | 2009-01-27 23:46:57 +0000 | [diff] [blame] | 59 | } | 
 | 60 |  | 
 | 61 | ULONG_PTR _Py_ActivateActCtx() | 
 | 62 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 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; | 
| Mark Hammond | 9844a1f | 2009-01-27 23:46:57 +0000 | [diff] [blame] | 70 | } | 
 | 71 |  | 
 | 72 | void _Py_DeactivateActCtx(ULONG_PTR cookie) | 
 | 73 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 74 |     if (cookie && pfnDeactivateActCtx) | 
 | 75 |         if (!(*pfnDeactivateActCtx)(0, cookie)) | 
 | 76 |             OutputDebugString("Python failed to de-activate the activation context\n"); | 
| Mark Hammond | 9844a1f | 2009-01-27 23:46:57 +0000 | [diff] [blame] | 77 | } | 
| Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 78 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 79 | BOOL    WINAPI  DllMain (HANDLE hInst, | 
 | 80 |                                                 ULONG ul_reason_for_call, | 
 | 81 |                                                 LPVOID lpReserved) | 
| Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 82 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 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)); | 
| Mark Hammond | 9844a1f | 2009-01-27 23:46:57 +0000 | [diff] [blame] | 89 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 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; | 
| Mark Hammond | 9844a1f | 2009-01-27 23:46:57 +0000 | [diff] [blame] | 97 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 98 |         case DLL_PROCESS_DETACH: | 
 | 99 |             if (pfnReleaseActCtx) | 
 | 100 |                 (*pfnReleaseActCtx)(PyWin_DLLhActivationContext); | 
 | 101 |             break; | 
 | 102 |     } | 
 | 103 |     return TRUE; | 
| Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 104 | } | 
| Christian Heimes | d59c64c | 2007-11-30 19:27:20 +0000 | [diff] [blame] | 105 |  | 
 | 106 | #endif /* Py_ENABLE_SHARED */ |