/* Release mapping, if any */ void CFileProjection::Release() { if(m_hctx != INVALID_HANDLE_VALUE) { ReleaseActCtx(m_hctx); m_hctx = INVALID_HANDLE_VALUE; } if(m_pData) { UnmapViewOfFile(m_pData); m_pData = nullptr; } if(m_hMapping && m_hMapping != INVALID_HANDLE_VALUE) { CloseHandle(m_hMapping); m_hMapping = NULL; } if(m_hFile != INVALID_HANDLE_VALUE) { CloseHandle(m_hFile); m_hFile = INVALID_HANDLE_VALUE; } }
void ReleaseActContext(void) { void (WINAPI *ReleaseActCtx)(HANDLE); BOOL (WINAPI *DeactivateActCtx)(DWORD dwFlags, ULONG_PTR ulCookie); HANDLE k32; if (!IsXPOrLater()) return; k32 = LoadLibrary("kernel32"); ReleaseActCtx = (void*)GetProcAddress(k32, "ReleaseActCtx"); DeactivateActCtx = (void*)GetProcAddress(k32, "DeactivateActCtx"); if (!ReleaseActCtx || !DeactivateActCtx) { VS("Cannot find ReleaseActCtx/DeactivateActCtx exports in kernel32.dll\n"); return; } __try { VS("Deactivating activation context\n"); if (!DeactivateActCtx(0, actToken)) VS("Error deactivating context!\n!"); VS("Releasing activation context\n"); if (hCtx != INVALID_HANDLE_VALUE) ReleaseActCtx(hCtx); VS("Done\n"); } __except (STATUS_SXS_EARLY_DEACTIVATION) { VS("XS early deactivation; somebody left the activation context dirty, let's ignore the problem\n"); } }
extern "C" BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) { switch (dwReason) { case DLL_PROCESS_ATTACH: g_hModThisDll = hInstance; g_cRefThisDll = 0; g_bActCtxCreated = FALSE; g_hActCtx = INVALID_HANDLE_VALUE; g_uWinVer = SwapV16(LOWORD(GetVersion())); #ifndef _WIN64 if (g_uWinVer < 0x0501) return(FALSE); #endif #ifdef _DLL DisableThreadLibraryCalls(hInstance); #endif break; case DLL_PROCESS_DETACH: if (g_bActCtxCreated && g_hActCtx != INVALID_HANDLE_VALUE) ReleaseActCtx(g_hActCtx); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return(TRUE); }
~ActivationContext() { if (hactctx != INVALID_HANDLE_VALUE) { DeactivateActCtx(0, actctx_cookie); ReleaseActCtx(hactctx); } }
void Release() { if ( m_hCtxt != INVALID_HANDLE_VALUE ) { Deactivate(); ReleaseActCtx( m_hCtxt ); } }
void Release() { if ( ActivationCtxHandle == INVALID_HANDLE_VALUE ) { return ; } DeActivate(); ReleaseActCtx( ActivationCtxHandle ); ActivationCtxHandle = INVALID_HANDLE_VALUE; }
/////////////////////////////////////////////////////////// // // DLL entry point // BOOL WINAPI DllMain(HINSTANCE hInst, WORD wReason, LPVOID lpReserved) { UNREFERENCED_PARAMETER(lpReserved); switch(wReason) { case DLL_PROCESS_ATTACH: { VERBOSE(DLLTEXT("Process attach.\r\n")); HRESULT hRes = ::CoInitialize(NULL); // If you are running on NT 4.0 or higher you can use the following call instead to // make the EXE free threaded. This means that calls come in on a random RPC thread. // HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); ATLASSERT(SUCCEEDED(hRes)); _Module.Init(0, hInst); // Store the module handle in case we need it later. ghInstance = hInst; // NOTE: We don't create an Activation Context on module load, // but on need of an Avtivation Context; the first time // GetMyActivationContext() or CreateMyActivationContext() is called. } break; case DLL_THREAD_ATTACH: VERBOSE(DLLTEXT("Thread attach.\r\n")); break; case DLL_PROCESS_DETACH: VERBOSE(DLLTEXT("Process detach.\r\n")); // Release the Activation Context if we created one somewhere // by calling GetMyActivationContext() or CreateMyActivationContext(); if(INVALID_HANDLE_VALUE != ghActCtx) { ReleaseActCtx(ghActCtx); ghActCtx = INVALID_HANDLE_VALUE; } _Module.Term(); ::CoUninitialize(); break; case DLL_THREAD_DETACH: VERBOSE(DLLTEXT("Thread detach.\r\n")); break; } return TRUE; }
ActivationContext(const int resid) { hactctx = INVALID_HANDLE_VALUE; actctx_cookie = 0; ACTCTXA actx = {0}; actx.cbSize = sizeof(ACTCTXA); actx.lpResourceName = MAKEINTRESOURCEA(resid); actx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; QString path = QCoreApplication::applicationDirPath() + "/opentrack-proto-simconnect.dll"; QByteArray name = QFile::encodeName(path); actx.lpSource = name.constData(); hactctx = CreateActCtxA(&actx); actctx_cookie = 0; if (hactctx != INVALID_HANDLE_VALUE) { if (!ActivateActCtx(hactctx, &actctx_cookie)) { qDebug() << "SC: can't set win32 activation context" << GetLastError(); ReleaseActCtx(hactctx); hactctx = INVALID_HANDLE_VALUE; } } else { qDebug() << "SC: can't create win32 activation context"; } }
bool CPython::init() { // // Initialize the python environment // std::wstring path; int iRslt = 0; DWORD nrslt = 0; std::vector<wchar> vetbuf; wchar buffer[MAX_PATH+1] = {0}; // First of all, get the python path from options . for (; GetOption(text("Python Path"), path); ) { nrslt = ::GetFullPathName ( // ... path.c_str(), _countof(buffer), buffer, nullptr ); if (nrslt == 0) { path.clear(); break; } if (nrslt < _countof(buffer)) { path = buffer; break; } vetbuf.resize(nrslt+1); // Allocate buffer ... nrslt = ::GetFullPathName ( // ... path.c_str(), vetbuf.size(), vetbuf.data(), nullptr ); if (!nrslt || nrslt >= vetbuf.size()) path.clear(); else path.assign(vetbuf.begin(), vetbuf.end()); break; } // Use the directory of the exe file if we fail to get python // path from options. for (std::size_t pos = 0; path.length() <= 0; ) { nrslt = GetModuleFileName ( // Try the first time ....... nullptr, buffer, _countof(buffer) ); if (nrslt == 0) { path.clear(); break; } if (nrslt < _countof(buffer)) { path = buffer; pos = path.find_last_not_of(text("\\/")); pos = path.find_last_of(text("\\/"),pos); path.replace( pos, -1, text("\\python")); break; } vetbuf.resize(nrslt*2); // Allocate buffer .......... nrslt = GetModuleFileName ( // Try the second time ...... nullptr, vetbuf.data(), vetbuf.size() ); if (nrslt != 0 && nrslt <= vetbuf.size()) { path.assign(vetbuf.begin(), vetbuf.end()); pos = path.find_last_not_of(text("\\/")); pos = path.find_last_of(text("\\/"),pos); path.replace( pos, -1, text("\\python")); } else path.clear(); break; } // Use current directory if we still can't get the python path . for (; path.length() <= 0; ) { nrslt = ::GetCurrentDirectory(_countof(buffer), buffer); if (nrslt == 0) { path.clear(); break; } if (nrslt < _countof(buffer)) { path = buffer; path += text("\\python"); } vetbuf.resize(nrslt+1); // Allocate buffer ... nrslt = ::GetCurrentDirectory(vetbuf.size(),vetbuf.data()); if (nrslt != 0 && nrslt <= vetbuf.size()) { path.assign(vetbuf.begin(), vetbuf.end()); path.append(text("\\python")); } else path.clear(); break; } // We return false if we still can't get the python path ... if(path.length()<=0) return false; path.push_back(text('\\')); // Now, We overwrite the environment variable PYTHONHOME.. // It's not a necessuary operation .. ::SetEnvironmentVariable(text("PYTHONHOME"), path.c_str()); // Locate the python kernel file "pythonxx.dll" .. WIN32_FIND_DATA fData = {0}; HANDLE hFile = nullptr; hFile = FindFirstFile((path+text("*.dll")).c_str(), &fData); if (hFile != INVALID_HANDLE_VALUE) { do { if (fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; // We skip all directory . _wcslwr_s(fData.cFileName, _countof(fData.cFileName)); if (wcsstr(fData.cFileName, text("python"))) break; else fData.cFileName[0] = text('\0'); } while (FindNextFile(hFile, &fData)); FindClose(hFile); // Finish finding .. } else fData.cFileName[0] = text('\0'); /// // Now, initialize all python interface dynamically. // The reason we query python interface dynamically is to // make sure our plugin can work without python .. /// m_pyModule = ::GetModuleHandle(fData.cFileName); if (m_pyModule == nullptr) { m_pyModule = ::LoadLibrary((path+fData.cFileName).c_str()); if (m_pyModule == nullptr) { m_pyModule = ::GetModuleHandle(text("python27.dll")); if (m_pyModule == nullptr) { m_pyModule = ::LoadLibrary(text("python27.dll")); if (m_pyModule == nullptr) return false; } } } if ( (Py_Finalize = reinterpret_cast<py_finalize>( ::GetProcAddress(m_pyModule, "Py_Finalize") )) == nullptr ) return false; if ( (Py_Initialize = reinterpret_cast<py_initialize>( ::GetProcAddress(m_pyModule, "Py_Initialize") )) == nullptr ) return false; if ( (Py_SetPythonHome = reinterpret_cast<py_setpythonhome>( ::GetProcAddress(m_pyModule, "Py_SetPythonHome") )) == nullptr ) return false; if ( (Py_SetProgramName = reinterpret_cast<py_setprogramname>( ::GetProcAddress(m_pyModule, "Py_SetProgramName") )) == nullptr ) return false; if ( (PyFile_AsFile = reinterpret_cast<pyfile_asfile>( ::GetProcAddress(m_pyModule, "PyFile_AsFile") )) == nullptr ) return false; if ( (PyFile_FromFile = reinterpret_cast<pyfile_fromfile>( ::GetProcAddress(m_pyModule, "PyFile_FromFile") )) == nullptr ) return false; if ( (PyFile_FromString = reinterpret_cast<pyfile_fromstring>( ::GetProcAddress(m_pyModule, "PyFile_FromString") )) == nullptr ) return false; if ( (PyEval_InitThreads = reinterpret_cast<pyeval_initthreads>( ::GetProcAddress(m_pyModule, "PyEval_InitThreads") )) == nullptr ) return false; if ( (PySys_SetArgv = reinterpret_cast<pysys_setargv>( ::GetProcAddress(m_pyModule, "PySys_SetArgv") )) == nullptr ) return false; if ( (PySys_GetObject = reinterpret_cast<pysys_getobject>( ::GetProcAddress(m_pyModule, "PySys_GetObject") )) == nullptr ) return false; if ( (PySys_SetObject = reinterpret_cast<pysys_setobject>( ::GetProcAddress(m_pyModule, "PySys_SetObject") )) == nullptr ) return false; if ( (PyObject_SetAttrString = reinterpret_cast<pyobject_setattrstring>( ::GetProcAddress(m_pyModule, "PyObject_SetAttrString") )) == nullptr ) return false; if ( (PyImport_ImportModule = reinterpret_cast<pyimport_importmodule>( ::GetProcAddress(m_pyModule, "PyImport_ImportModule") )) == nullptr ) return false; if ( (PyImport_AddModule = reinterpret_cast<pyimport_addmodule>( ::GetProcAddress(m_pyModule, "PyImport_AddModule") )) == nullptr ) return false; if ( (PyRun_SimpleString = reinterpret_cast<pyrun_simplestring>( ::GetProcAddress(m_pyModule, "PyRun_SimpleString") )) == nullptr ) return false; if ( (PyRun_SimpleStringFlags = reinterpret_cast<pyrun_simplestringflags>( ::GetProcAddress(m_pyModule, "PyRun_SimpleStringFlags") )) == nullptr ) return false; if ( (PyRun_SimpleFile = reinterpret_cast<pyrun_simplefile>( ::GetProcAddress(m_pyModule, "PyRun_SimpleFile") )) == nullptr ) return false; /*if ( (PyRun_SimpleFileFlags = reinterpret_cast<pyrun_simplefileflags>( ::GetProcAddress(m_pyModule, "PyRun_SimpleFileFlags") )) == nullptr ) return false;*/ if ( (PyRun_SimpleFileEx = reinterpret_cast<pyrun_simplefileex>( ::GetProcAddress(m_pyModule, "PyRun_SimpleFileEx") )) == nullptr ) return false; if ( (PyRun_SimpleFileExFlags = reinterpret_cast<pyrun_simplefileexflags>( ::GetProcAddress(m_pyModule, "PyRun_SimpleFileExFlags") )) == nullptr ) return false; // Initialize the python environment, prepare the hooks //if (Py_SetPythonHome) Py_SetPythonHome(cvt.to_bytes(path).c_str()); //if (Py_SetProgramName) Py_SetProgramName(cvt.to_bytes(buffer).c_str()); if (Py_Initialize) Py_Initialize(); if (PyEval_InitThreads) PyEval_InitThreads(); // ... /// // Now, initialize all MSVCR90 interface dynamically. /// ACTCTX ctx = {sizeof(ACTCTX), 0}; ULONG_PTR actToken = 0; ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID|ACTCTX_FLAG_HMODULE_VALID; ctx.hModule = m_pyModule; ctx.lpResourceName = MAKEINTRESOURCE(2); HANDLE hCtx = CreateActCtx(&ctx); if(hCtx != INVALID_HANDLE_VALUE) { if ( ActivateActCtx(hCtx, &actToken) ) { m_vcModule = ::GetModuleHandle(text("MSVCR90.dll")); if (m_vcModule == NULL) { m_vcModule = ::LoadLibrary(text("MSVCR90.dll")); if (m_vcModule == NULL) return false; } if ( (open_osfhandle = reinterpret_cast<__open_osfhandle>( ::GetProcAddress(m_vcModule, "_open_osfhandle") )) == nullptr ) return false; if ( (setvbuf = reinterpret_cast<__setvbuf>( ::GetProcAddress(m_vcModule, "setvbuf") )) == nullptr ) return false; if ( (fdopen = reinterpret_cast<__fdopen>( ::GetProcAddress(m_vcModule, "_fdopen") )) == nullptr ) return false; if ( (fclose = reinterpret_cast<__fclose>( ::GetProcAddress(m_vcModule, "fclose") )) == nullptr ) return false; // Deactive active context after finished .. DeactivateActCtx(0, actToken); } // Now close context ... ReleaseActCtx(hCtx); } return true; // All done, return true ... }
VOID WINAPI GetServiceMainFunctions ( _In_ PSVCHOST_SERVICE pService, _Out_ PVOID *pServiceMain, _Out_ PVOID *pPushServiceGlobals, _Out_ PDWORD lpdwError ) { DWORD dwError, cbDllLength, cbData, dwType; PSVCHOST_DLL pDll; ACTCTXW actCtx; LPCWSTR pszDllPath; HKEY hKey; HANDLE hActCtx; LPWSTR lpData; WCHAR szDllBuffer[MAX_PATH + 2], szManifestBuffer[MAX_PATH + 2]; /* Initialize the activation context we might need later */ RtlZeroMemory(&actCtx, sizeof(actCtx)); actCtx.cbSize = sizeof(actCtx); /* We clean these up in our failure path so initialize them to NULL here */ hActCtx = NULL; hKey = NULL; lpData = NULL; *lpdwError = ERROR_SUCCESS; /* Null terminate the string buffers */ szDllBuffer[0] = UNICODE_NULL; szManifestBuffer[0] = UNICODE_NULL; /* Do we already have a DLL ready to go for this service? */ pDll = pService->pDll; if (pDll != NULL) goto HaveDll; /* Nope, we're starting from scratch. Open a handle to parameters key */ dwError = OpenServiceParametersKey(pService->pszServiceName, &hKey); if (dwError) { *lpdwError = dwError; ASSERT(*lpdwError != NO_ERROR); goto Quickie; } /* Allocate enough space to hold a unicode path (NULL-terminated) */ cbData = MAX_PATH * sizeof(WCHAR) + sizeof(UNICODE_NULL); lpData = MemAlloc(0, cbData); if (lpData == NULL) { /* No memory, bail out */ *lpdwError = ERROR_NOT_ENOUGH_MEMORY; goto Quickie; } /* Query the DLL path */ lpData[0] = UNICODE_NULL; dwError = RegQueryValueExW(hKey, L"ServiceDll", 0, &dwType, (LPBYTE)lpData, &cbData); if (dwError != ERROR_SUCCESS) { *lpdwError = dwError; DBG_ERR("RegQueryValueEx for the ServiceDll parameter of the %ws " "service returned %u\n", pService->pszServiceName, dwError); goto Quickie; } /* Is the registry data valid and present? */ if ((dwType != REG_EXPAND_SZ) || (lpData[0] == UNICODE_NULL)) { /* Nope, bail out */ *lpdwError = ERROR_FILE_NOT_FOUND; DBG_ERR("The ServiceDll parameter for the %ws service is not of type " "REG_EXPAND_SZ\n", pService->pszServiceName); goto Quickie; } /* Convert the expandable path into an absolute path */ ExpandEnvironmentStringsW(lpData, szDllBuffer, MAX_PATH); SvchostCharLowerW(szDllBuffer); /* Check if the service has a manifest file associated with it */ cbData = MAX_PATH * sizeof(WCHAR) + sizeof(UNICODE_NULL); dwError = RegQueryValueExW(hKey, L"ServiceManifest", NULL, &dwType, (LPBYTE)lpData, &cbData); if (dwError != ERROR_SUCCESS) { /* Did we fail because one wasn't set? */ if ((dwError != ERROR_PATH_NOT_FOUND) && (dwError != ERROR_FILE_NOT_FOUND)) { /* We failed for some other reason, bail out */ *lpdwError = dwError; DBG_ERR("RegQueryValueEx for the ServiceManifest parameter of the " "%ws service returned %u\n", pService->pszServiceName, dwError); goto Quickie; } /* We have no manifest, make sure the buffer is empty */ szManifestBuffer[0] = UNICODE_NULL; /* We're done with this buffer */ MemFree(lpData); lpData = NULL; /* Use the whole DLL path, since we don't have a manifest */ pszDllPath = szDllBuffer; } else { /* Do we have invalid registry data? */ if ((dwType != REG_EXPAND_SZ) || (*lpData == UNICODE_NULL)) { /* Yes, pretend there's no manifest and bail out */ *lpdwError = ERROR_FILE_NOT_FOUND; DBG_ERR("The ServiceManifest parameter for the %ws service is not " "of type REG_EXPAND_SZ\n", pService->pszServiceName); goto Quickie; } /* Expand the string into our stack buffer */ ExpandEnvironmentStringsW(lpData, szManifestBuffer, MAX_PATH); /* We no longer need the heap buffer*/ MemFree(lpData); lpData = NULL; /* Lowercase the manifest path */ SvchostCharLowerW(szManifestBuffer); /* Now loop over the DLL path */ cbDllLength = lstrlenW(szDllBuffer); while (cbDllLength) { /* From the end, until we find the first path separator */ if (szDllBuffer[cbDllLength] == '\\' || szDllBuffer[cbDllLength] == '/') { /* Use just a short name (cut out the rest of the path) */ pszDllPath = &szDllBuffer[cbDllLength + 1]; break; } /* Try the next character */ cbDllLength--; } } /* See if we already have a matching DLL and manifest for this service */ pDll = FindDll(szManifestBuffer, pszDllPath, pService); if (pDll == NULL) { /* We don't have it yet -- does this DLL have a manifest? */ if (szManifestBuffer[0] != UNICODE_NULL) { /* Create an activation context for it */ actCtx.lpSource = szManifestBuffer; hActCtx = CreateActCtxW(&actCtx); if (hActCtx == INVALID_HANDLE_VALUE) { /* We've failed to create one, bail out */ *lpdwError = GetLastError(); DBG_ERR("CreateActCtxW(%ws) for the %ws service returned %u\n", szManifestBuffer, pService->pszServiceName, *lpdwError); goto Quickie; } } /* Add this new DLL into the database */ pDll = AddDll(szManifestBuffer, pszDllPath, pService, lpdwError); if (pDll) { /* Save the activation context and zero it so we don't release later */ pDll->hActCtx = hActCtx; hActCtx = NULL; } } /* We either found, added, or failed to add, the DLL for this service */ ASSERT(!pService->pDll); pService->pDll = pDll; /* In all cases, we will query the ServiceMain function, however*/ RegQueryStringA(hKey, L"ServiceMain", REG_SZ, &pService->pszServiceMain); /* And now we'll check if we were able to create it earlier (or find it) */ if (!pService->pDll) { /* We were not, so there's no point in going on */ ASSERT(*lpdwError != NO_ERROR); goto Quickie; } /* We do have a valid DLL, so now get the service main routine out of it */ HaveDll: *pServiceMain = GetServiceDllFunction(pDll, pService->pszServiceMain ? pService->pszServiceMain : "ServiceMain", lpdwError); /* And now get the globals routine out of it (this one is optional) */ *pPushServiceGlobals = GetServiceDllFunction(pDll, "SvchostPushServiceGlobals", NULL); Quickie: /* We're done, cleanup any resources we left behind */ if (hKey != NULL) RegCloseKey(hKey); if (lpData != NULL) MemFree(lpData); if ((hActCtx) && (hActCtx != INVALID_HANDLE_VALUE)) ReleaseActCtx(hActCtx); }
Win32UIBinding::~Win32UIBinding() { DeactivateActCtx(0, this->lpCookie); ReleaseActCtx(this->pActCtx); }