1 #ifndef _PY_WIN_HELPERS_HPP_
2 #define _PY_WIN_HELPERS_HPP_
3 
IsPythonModule(HMODULE module,bool & isDebug)4 bool IsPythonModule(HMODULE module, bool &isDebug) {
5     wchar_t mod_name[MAX_PATH];
6     isDebug = false;
7     if (GetModuleBaseName(GetCurrentProcess(), module, mod_name, MAX_PATH)) {
8         if (_wcsnicmp(mod_name, L"python", 6) == 0) {
9             if (wcslen(mod_name) >= 10 && _wcsnicmp(mod_name + 8, L"_d", 2) == 0) {
10                 isDebug = true;
11             }
12 
13             // Check if the module has Py_IsInitialized.
14             DEFINE_PROC_NO_CHECK(isInit, Py_IsInitialized*, "Py_IsInitialized", 0);
15             DEFINE_PROC_NO_CHECK(gilEnsure, PyGILState_Ensure*, "PyGILState_Ensure", 51);
16             DEFINE_PROC_NO_CHECK(gilRelease, PyGILState_Release*, "PyGILState_Release", 51);
17             if (isInit == nullptr || gilEnsure == nullptr || gilRelease == nullptr) {
18                 return false;
19             }
20 
21 
22             return true;
23         }
24     }
25     return false;
26 }
27 
28 
29 struct ModuleInfo {
30     HMODULE module;
31     bool isDebug;
32     int errorGettingModule; // 0 means ok, negative values some error (should never be positive).
33 };
34 
35 
GetPythonModule()36 ModuleInfo GetPythonModule() {
37     HANDLE hProcess = GetCurrentProcess();
38     ModuleInfo moduleInfo;
39     moduleInfo.module = nullptr;
40     moduleInfo.isDebug = false;
41     moduleInfo.errorGettingModule = 0;
42 
43     DWORD modSize = sizeof(HMODULE) * 1024;
44     HMODULE* hMods = (HMODULE*)_malloca(modSize);
45     if (hMods == nullptr) {
46         std::cout << "hmods not allocated! " << std::endl << std::flush;
47         moduleInfo.errorGettingModule = -1;
48         return moduleInfo;
49     }
50 
51     DWORD modsNeeded;
52     while (!EnumProcessModules(hProcess, hMods, modSize, &modsNeeded)) {
53         // try again w/ more space...
54         _freea(hMods);
55         hMods = (HMODULE*)_malloca(modsNeeded);
56         if (hMods == nullptr) {
57             std::cout << "hmods not allocated (2)! " << std::endl << std::flush;
58             moduleInfo.errorGettingModule = -2;
59             return moduleInfo;
60         }
61         modSize = modsNeeded;
62     }
63 
64     for (size_t i = 0; i < modsNeeded / sizeof(HMODULE); i++) {
65         bool isDebug;
66         if (IsPythonModule(hMods[i], isDebug)) {
67             moduleInfo.isDebug = isDebug;
68             moduleInfo.module = hMods[i];
69             return moduleInfo;
70         }
71     }
72     std::cout << "Unable to find python module. " << std::endl << std::flush;
73     moduleInfo.errorGettingModule = -3;
74     return moduleInfo;
75 }
76 
77 #endif