HRESULT CallPlmToEnableDebugging() { // Calling public API. // EnableDebugging() implementation lives in COMBASE.DLL loaded into Explorer.exe's address space. // Explorer's security token is used on invocation. Since Explorer and this code might run under // different users, the following call might fail. HRESULT hr = m_packageDebugSettings->EnableDebugging(m_packageName, m_debuggerString, m_environmentVars); // Calling internal API on failure. // It's almost identical code like in EnableDebugging() but it uses a security token of the curent process. if (FAILED(hr) && hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { if (m_debuggerString != nullptr || m_environmentVars != nullptr) { // Enable debug on activation hr = ::RoEnableDebuggingForPackage(m_packageName, m_debuggerString, m_environmentVars); if (FAILED(hr)) { return hr; } } // Disable activation timeouts Microsoft::WRL::ComPtr<IApplicationActivationManagerPriv> spActivationManager; hr = CoCreateInstance(CLSID_ApplicationActivationManager, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&spActivationManager)); if (FAILED(hr)) { return hr; } if (SUCCEEDED(hr)) { hr = spActivationManager->PutPackageActivationSettings(Windows::Internal::StringReference(m_packageName).Get(), PAS_NORPCTIMEOUTS, PAS_NORPCTIMEOUTS); // CImmersiveApplicationDebugControlInternal, which implements IPackageDebugSettings, // does the following. We don't have an ISuspendResumeController, so we don't do it. // This must be what disables suspend/resume on the app (to aid debugging). // We probably don't need it for iDNA. //if (SUCCEEDED(hr)) //{ // hr = _spSuspendResumeController->OnDebugModeEnabled(m_packageName); //} } // Roll back on failure. if (FAILED(hr)) { HRESULT const disableHr = CallPlmToDisableDebugging(); if (FAILED(disableHr)) { LogError(disableHr, L"CallPlmToDisableDebugging() reported an error while aborting in CallPlmToEnableDebugging() .\n"); } } } return hr; }
HRESULT CallPlmToDisableDebugging() { HRESULT hr = m_packageDebugSettings->DisableDebugging(m_packageName); if (FAILED(hr) && hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { hr = ::RoDisableDebuggingForPackage(m_packageName); // It's possible that the package was never enabled for COM debugging (e.g. no debugger path string) // so ignore specific failures when disabling the package for debugging. if (FAILED(hr) && HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr) { return hr; } // CImmersiveApplicationDebugControlInternal, which implements IPackageDebugSettings, // does the following. We don't have an ISuspendResumeController, so we don't do it. // This must be what re-enables suspend/resume on the app (disabled to aid debugging). // We probably don't need it for iDNA. // hr = _spSuspendResumeController->OnDebugModeDisabled(m_packageName); // if (FAILED(hr)) // { // hrError = hr; // } // Reenable activation timeouts Microsoft::WRL::ComPtr<IApplicationActivationManagerPriv> spActivationManager; hr = CoCreateInstance(CLSID_ApplicationActivationManager, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&spActivationManager)); if (SUCCEEDED(hr)) { hr = spActivationManager->PutPackageActivationSettings(Windows::Internal::StringReference(m_packageName).Get(), PAS_NORPCTIMEOUTS, PAS_DEFAULT); } } return hr; }