diff options
author | Aaron Robinson <arobins@microsoft.com> | 2018-07-02 16:21:59 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-02 16:21:59 -0700 |
commit | 7222c56c42be22ecb0b61ce2d49e3e916ecdadb6 (patch) | |
tree | 71c3d7112577c5eae1e86340bbea3e140ff07595 /src/coreclr | |
parent | 5f306d6823b85ea65e1e955a490853f68dcca2a3 (diff) | |
download | coreclr-7222c56c42be22ecb0b61ce2d49e3e916ecdadb6.tar.gz coreclr-7222c56c42be22ecb0b61ce2d49e3e916ecdadb6.tar.bz2 coreclr-7222c56c42be22ecb0b61ce2d49e3e916ecdadb6.zip |
Set the activation context for the CoreRun application to what is defined (#18728)
in the target managed assembly. This allows RegFree COM scenarios and ensures
the intended app manifest is used for the 'exe' scenario.
Diffstat (limited to 'src/coreclr')
-rw-r--r-- | src/coreclr/hosts/corerun/corerun.cpp | 76 |
1 files changed, 69 insertions, 7 deletions
diff --git a/src/coreclr/hosts/corerun/corerun.cpp b/src/coreclr/hosts/corerun/corerun.cpp index 47ec363105..c1d1fcef49 100644 --- a/src/coreclr/hosts/corerun/corerun.cpp +++ b/src/coreclr/hosts/corerun/corerun.cpp @@ -110,7 +110,7 @@ public: // Check for %CORE_ROOT% and try to load CoreCLR.dll from it if it is set StackSString coreRoot; - m_coreCLRModule = NULL; // Initialize this here since we don't call TryLoadCoreCLR if CORE_ROOT is unset. + m_coreCLRModule = NULL; // Initialize this here since we don't call TryLoadCoreCLR if CORE_ROOT is unset. if (WszGetEnvironmentVariable(W("CORE_ROOT"), coreRoot) > 0 && coreRoot.GetCount() > 0) { coreRoot.Append(W('\\')); @@ -365,6 +365,64 @@ STARTUP_FLAGS CreateStartupFlags() { return initialFlags; } +// Class used to manage activation context. +// See: https://docs.microsoft.com/en-us/windows/desktop/SbsCs/using-the-activation-context-api +class ActivationContext +{ +public: + // logger - Logger to record errors + // assemblyPath - Assembly containing activation context manifest + ActivationContext(Logger &logger, _In_z_ const WCHAR *assemblyPath) + : _actCookie{} + , _actCxt{ INVALID_HANDLE_VALUE } + , _logger{ logger } + { + ACTCTX cxt{}; + cxt.cbSize = sizeof(cxt); + cxt.dwFlags = (ACTCTX_FLAG_APPLICATION_NAME_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID); + cxt.lpSource = assemblyPath; + cxt.lpResourceName = MAKEINTRESOURCEW(1); // The CreateProcess manifest which contains the context details + + _actCxt = ::CreateActCtxW(&cxt); + if (_actCxt == INVALID_HANDLE_VALUE) + { + DWORD err = ::GetLastError(); + if (err == ERROR_RESOURCE_TYPE_NOT_FOUND) + { + _logger << W("Assembly does not contain a manifest for activation") << Logger::endl; + } + else + { + _logger << W("Activation Context creation failed. Error Code: ") << Logger::hresult << err << Logger::endl; + } + } + else + { + BOOL res = ::ActivateActCtx(_actCxt, &_actCookie); + if (res == FALSE) + _logger << W("Failed to activate Activation Context. Error Code: ") << Logger::hresult << ::GetLastError() << Logger::endl; + } + } + + ~ActivationContext() + { + if (_actCookie != ULONG_PTR{}) + { + BOOL res = ::DeactivateActCtx(0, _actCookie); + if (res == FALSE) + _logger << W("Failed to de-activate Activation Context. Error Code: ") << Logger::hresult << ::GetLastError() << Logger::endl; + } + + if (_actCxt != INVALID_HANDLE_VALUE) + ::ReleaseActCtx(_actCxt); + } + +private: + Logger &_logger; + HANDLE _actCxt; + ULONG_PTR _actCookie; +}; + bool TryRun(const int argc, const wchar_t* argv[], Logger &log, const bool verbose, const bool waitForDebugger, DWORD &exitCode) { @@ -578,14 +636,18 @@ bool TryRun(const int argc, const wchar_t* argv[], Logger &log, const bool verbo } } - hr = host->ExecuteAssembly(domainId, managedAssemblyFullName, argc-1, (argc-1)?&(argv[1]):NULL, &exitCode); - if (FAILED(hr)) { - log << W("Failed call to ExecuteAssembly. ERRORCODE: ") << Logger::hresult << hr << Logger::endl; - return false; - } + { + ActivationContext cxt{ log, managedAssemblyFullName.GetUnicode() }; - log << W("App exit value = ") << exitCode << Logger::endl; + hr = host->ExecuteAssembly(domainId, managedAssemblyFullName, argc - 1, (argc - 1) ? &(argv[1]) : NULL, &exitCode); + if (FAILED(hr)) + { + log << W("Failed call to ExecuteAssembly. ERRORCODE: ") << Logger::hresult << hr << Logger::endl; + return false; + } + log << W("App exit value = ") << exitCode << Logger::endl; + } //------------------------------------------------------------- |