From 0d3d54992104288e9ee0c834d0b96e8502fd2d42 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 11 Jan 2024 18:26:20 -0800 Subject: Move the BootstrapperApplication out of proc --- src/ext/Bal/mbahost/mbahost.cpp | 693 ---------------------------------------- 1 file changed, 693 deletions(-) delete mode 100644 src/ext/Bal/mbahost/mbahost.cpp (limited to 'src/ext/Bal/mbahost/mbahost.cpp') diff --git a/src/ext/Bal/mbahost/mbahost.cpp b/src/ext/Bal/mbahost/mbahost.cpp deleted file mode 100644 index 9d8acc8a..00000000 --- a/src/ext/Bal/mbahost/mbahost.cpp +++ /dev/null @@ -1,693 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -#include "precomp.h" - -static const DWORD NET452_RELEASE = 379893; - -using namespace mscorlib; - -extern "C" typedef HRESULT (WINAPI *PFN_CORBINDTOCURRENTRUNTIME)( - __in LPCWSTR pwszFileName, - __in REFCLSID rclsid, - __in REFIID riid, - __out LPVOID *ppv - ); - -static MBASTATE vstate = { }; - - -// internal function declarations - -static HRESULT GetAppDomain( - __in MBASTATE* pState - ); -static HRESULT LoadModulePaths( - __in MBASTATE* pState - ); -static HRESULT LoadMbaConfiguration( - __in MBASTATE* pState, - __in const BOOTSTRAPPER_CREATE_ARGS* pArgs - ); -static HRESULT CheckSupportedFrameworks( - __in LPCWSTR wzConfigPath - ); -static HRESULT UpdateSupportedRuntime( - __in IXMLDOMDocument* pixdManifest, - __in IXMLDOMNode* pixnSupportedFramework, - __out BOOL* pfUpdatedManifest - ); -static HRESULT LoadRuntime( - __in MBASTATE* pState - ); -static HRESULT CreateManagedBootstrapperApplication( - __in _AppDomain* pAppDomain, - __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, - __inout BOOTSTRAPPER_CREATE_RESULTS* pResults - ); -static HRESULT CreateManagedBootstrapperApplicationFactory( - __in _AppDomain* pAppDomain, - __out IBootstrapperApplicationFactory** ppAppFactory - ); -static HRESULT CreatePrerequisiteBA( - __in MBASTATE* pState, - __in IBootstrapperEngine* pEngine, - __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, - __inout BOOTSTRAPPER_CREATE_RESULTS* pResults - ); -static HRESULT VerifyNET4RuntimeIsSupported( - ); - - -// function definitions - -extern "C" BOOL WINAPI DllMain( - IN HINSTANCE hInstance, - IN DWORD dwReason, - IN LPVOID /* pvReserved */ - ) -{ - switch (dwReason) - { - case DLL_PROCESS_ATTACH: - ::DisableThreadLibraryCalls(hInstance); - vstate.hInstance = hInstance; - break; - - case DLL_PROCESS_DETACH: - vstate.hInstance = NULL; - break; - } - - return TRUE; -} - -// Note: This function assumes that COM was already initialized on the thread. -extern "C" HRESULT WINAPI BootstrapperApplicationCreate( - __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, - __inout BOOTSTRAPPER_CREATE_RESULTS* pResults - ) -{ - HRESULT hr = S_OK; - IBootstrapperEngine* pEngine = NULL; - - if (vstate.fStoppedRuntime) - { - BalExitWithRootFailure(hr, E_INVALIDSTATE, "Reloaded mbahost after stopping .NET runtime."); - } - - hr = BalInitializeFromCreateArgs(pArgs, &pEngine); - ExitOnFailure(hr, "Failed to initialize Bal."); - - if (!vstate.fInitialized) - { - hr = XmlInitialize(); - BalExitOnFailure(hr, "Failed to initialize XML."); - - hr = LoadModulePaths(&vstate); - BalExitOnFailure(hr, "Failed to load the module paths."); - - hr = LoadMbaConfiguration(&vstate, pArgs); - BalExitOnFailure(hr, "Failed to get the mba configuration."); - - vstate.fInitialized = TRUE; - } - - if (vstate.prereqData.fAlwaysInstallPrereqs && !vstate.prereqData.fCompleted) - { - BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading prerequisite bootstrapper application since it's configured to always run before loading the runtime."); - - hr = CreatePrerequisiteBA(&vstate, pEngine, pArgs, pResults); - BalExitOnFailure(hr, "Failed to create the pre-requisite bootstrapper application."); - - ExitFunction(); - } - - if (!vstate.fInitializedRuntime) - { - hr = LoadRuntime(&vstate); - - vstate.fInitializedRuntime = SUCCEEDED(hr); - } - - if (vstate.fInitializedRuntime) - { - hr = GetAppDomain(&vstate); - BalExitOnFailure(hr, "Failed to create the AppDomain for the managed bootstrapper application."); - - BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading managed bootstrapper application."); - - hr = CreateManagedBootstrapperApplication(vstate.pAppDomain, pArgs, pResults); - BalExitOnFailure(hr, "Failed to create the managed bootstrapper application."); - } - else // fallback to the prerequisite BA. - { - if (E_MBAHOST_NET452_ON_WIN7RTM == hr) - { - BalLogError(hr, "The Burn engine cannot run with an MBA under the .NET 4 CLR on Windows 7 RTM with .NET 4.5.2 (or greater) installed."); - vstate.prereqData.hrFatalError = hr; - } - else if (vstate.prereqData.fCompleted) - { - hr = E_PREREQBA_INFINITE_LOOP; - BalLogError(hr, "The prerequisites were already installed. The bootstrapper application will not be reloaded to prevent an infinite loop."); - vstate.prereqData.hrFatalError = hr; - } - else - { - vstate.prereqData.hrFatalError = S_OK; - } - - BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading prerequisite bootstrapper application because managed host could not be loaded, error: 0x%08x.", hr); - - hr = CreatePrerequisiteBA(&vstate, pEngine, pArgs, pResults); - BalExitOnFailure(hr, "Failed to create the pre-requisite bootstrapper application."); - } - -LExit: - ReleaseNullObject(pEngine); - - return hr; -} - -extern "C" void WINAPI BootstrapperApplicationDestroy( - __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs, - __in BOOTSTRAPPER_DESTROY_RESULTS* pResults - ) -{ - BOOTSTRAPPER_DESTROY_RESULTS childResults = { }; - - if (vstate.pAppDomain) - { - HRESULT hr = vstate.pCLRHost->UnloadDomain(vstate.pAppDomain); - if (FAILED(hr)) - { - BalLogError(hr, "Failed to unload app domain."); - } - - vstate.pAppDomain->Release(); - vstate.pAppDomain = NULL; - } - - // pCLRHost can only be stopped once per process. - if (vstate.pCLRHost && !pArgs->fReload) - { - vstate.pCLRHost->Stop(); - vstate.pCLRHost->Release(); - vstate.pCLRHost = NULL; - vstate.fStoppedRuntime = TRUE; - } - - if (vstate.hMbapreqModule) - { - PFN_BOOTSTRAPPER_APPLICATION_DESTROY pfnDestroy = reinterpret_cast(::GetProcAddress(vstate.hMbapreqModule, "PrereqBootstrapperApplicationDestroy")); - if (pfnDestroy) - { - (*pfnDestroy)(pArgs, &childResults); - } - - ::FreeLibrary(vstate.hMbapreqModule); - vstate.hMbapreqModule = NULL; - } - - BalUninitialize(); - - // Need to keep track of state between reloads. - pResults->fDisableUnloading = TRUE; -} - -// Gets the custom AppDomain for loading managed BA. -static HRESULT GetAppDomain( - __in MBASTATE* pState - ) -{ - HRESULT hr = S_OK; - IUnknown *pUnk = NULL; - IAppDomainSetup* pAppDomainSetup = NULL; - BSTR bstrAppBase = NULL; - BSTR bstrConfigPath = NULL; - - // Create the setup information for a new AppDomain to set the app base and config. - hr = pState->pCLRHost->CreateDomainSetup(&pUnk); - BalExitOnRootFailure(hr, "Failed to create the AppDomainSetup object."); - - hr = pUnk->QueryInterface(__uuidof(IAppDomainSetup), reinterpret_cast(&pAppDomainSetup)); - BalExitOnRootFailure(hr, "Failed to query for the IAppDomainSetup interface."); - ReleaseNullObject(pUnk); - - // Set properties on the AppDomainSetup object. - bstrAppBase = ::SysAllocString(pState->sczAppBase); - BalExitOnNull(bstrAppBase, hr, E_OUTOFMEMORY, "Failed to allocate the application base path for the AppDomainSetup."); - - hr = pAppDomainSetup->put_ApplicationBase(bstrAppBase); - BalExitOnRootFailure(hr, "Failed to set the application base path for the AppDomainSetup."); - - bstrConfigPath = ::SysAllocString(pState->sczConfigPath); - BalExitOnNull(bstrConfigPath, hr, E_OUTOFMEMORY, "Failed to allocate the application configuration file for the AppDomainSetup."); - - hr = pAppDomainSetup->put_ConfigurationFile(bstrConfigPath); - BalExitOnRootFailure(hr, "Failed to set the configuration file path for the AppDomainSetup."); - - // Create the AppDomain to load the factory type. - hr = pState->pCLRHost->CreateDomainEx(L"MBA", pAppDomainSetup, NULL, &pUnk); - BalExitOnRootFailure(hr, "Failed to create the MBA AppDomain."); - - hr = pUnk->QueryInterface(__uuidof(_AppDomain), reinterpret_cast(&pState->pAppDomain)); - BalExitOnRootFailure(hr, "Failed to query for the _AppDomain interface."); - -LExit: - ReleaseBSTR(bstrConfigPath); - ReleaseBSTR(bstrAppBase); - ReleaseNullObject(pUnk); - - return hr; -} - -static HRESULT LoadModulePaths( - __in MBASTATE* pState - ) -{ - HRESULT hr = S_OK; - LPWSTR sczFullPath = NULL; - - hr = PathForCurrentProcess(&sczFullPath, pState->hInstance); - BalExitOnFailure(hr, "Failed to get the full host path."); - - hr = PathGetDirectory(sczFullPath, &pState->sczAppBase); - BalExitOnFailure(hr, "Failed to get the directory of the full process path."); - - hr = PathConcat(pState->sczAppBase, MBA_CONFIG_FILE_NAME, &pState->sczConfigPath); - BalExitOnFailure(hr, "Failed to get the full path to the application configuration file."); - -LExit: - ReleaseStr(sczFullPath); - - return hr; -} - -static HRESULT LoadMbaConfiguration( - __in MBASTATE* pState, - __in const BOOTSTRAPPER_CREATE_ARGS* pArgs - ) -{ - HRESULT hr = S_OK; - IXMLDOMDocument* pixdManifest = NULL; - IXMLDOMNode* pixnHost = NULL; - BOOL fXmlFound = FALSE; - - hr = XmlLoadDocumentFromFile(pArgs->pCommand->wzBootstrapperApplicationDataPath, &pixdManifest); - BalExitOnFailure(hr, "Failed to load BalManifest '%ls'", pArgs->pCommand->wzBootstrapperApplicationDataPath); - - hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixMbaPrereqOptions", &pixnHost); - BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to find WixMbaPrereqOptions element in bootstrapper application config."); - - if (fXmlFound) - { - hr = XmlGetAttributeNumber(pixnHost, L"AlwaysInstallPrereqs", reinterpret_cast(&pState->prereqData.fAlwaysInstallPrereqs)); - BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get AlwaysInstallPrereqs value."); - } - - pState->prereqData.fPerformHelp = !pState->prereqData.fAlwaysInstallPrereqs; - -LExit: - ReleaseObject(pixnHost); - ReleaseObject(pixdManifest); - - return hr; -} - -// Checks whether at least one of required supported frameworks is installed via the NETFX registry keys. -static HRESULT CheckSupportedFrameworks( - __in LPCWSTR wzConfigPath - ) -{ - HRESULT hr = S_OK; - IXMLDOMDocument* pixdManifest = NULL; - IXMLDOMNodeList* pNodeList = NULL; - IXMLDOMNode* pNode = NULL; - DWORD cSupportedFrameworks = 0; - LPWSTR sczSupportedFrameworkVersion = NULL; - LPWSTR sczFrameworkRegistryKey = NULL; - HKEY hkFramework = NULL; - DWORD dwFrameworkInstalled = 0; - BOOL fUpdatedManifest = FALSE; - - hr = XmlLoadDocumentFromFile(wzConfigPath, &pixdManifest); - BalExitOnFailure(hr, "Failed to load bootstrapper config file from path: %ls", wzConfigPath); - - hr = XmlSelectNodes(pixdManifest, L"/configuration/wix.bootstrapper/host/supportedFramework", &pNodeList); - BalExitOnFailure(hr, "Failed to select all supportedFramework elements."); - - hr = pNodeList->get_length(reinterpret_cast(&cSupportedFrameworks)); - BalExitOnFailure(hr, "Failed to get the supported framework count."); - - if (cSupportedFrameworks) - { - while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, NULL))) - { - hr = XmlGetAttributeEx(pNode, L"version", &sczSupportedFrameworkVersion); - BalExitOnRequiredXmlQueryFailure(hr, "Failed to get supportedFramework/@version."); - - hr = StrAllocFormatted(&sczFrameworkRegistryKey, L"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\%ls", sczSupportedFrameworkVersion); - BalExitOnFailure(hr, "Failed to allocate path to supported framework Install registry key."); - - hr = RegOpen(HKEY_LOCAL_MACHINE, sczFrameworkRegistryKey, KEY_READ, &hkFramework); - if (SUCCEEDED(hr)) - { - hr = RegReadNumber(hkFramework, L"Install", &dwFrameworkInstalled); - if (dwFrameworkInstalled) - { - hr = S_OK; - break; - } - } - - ReleaseNullObject(pNode); - } - - // If we looped through all the supported frameworks but didn't find anything, ensure we return a failure. - if (S_FALSE == hr) - { - BalExitWithRootFailure(hr, E_NOTFOUND, "Failed to find a supported framework."); - } - - hr = UpdateSupportedRuntime(pixdManifest, pNode, &fUpdatedManifest); - BalExitOnFailure(hr, "Failed to update supportedRuntime."); - } - // else no supported frameworks specified, so the startup/supportedRuntime must be enough. - - if (fUpdatedManifest) - { - hr = XmlSaveDocument(pixdManifest, wzConfigPath); - BalExitOnFailure(hr, "Failed to save updated manifest over config file: %ls", wzConfigPath); - } - -LExit: - ReleaseRegKey(hkFramework); - ReleaseStr(sczFrameworkRegistryKey); - ReleaseStr(sczSupportedFrameworkVersion); - ReleaseObject(pNode); - ReleaseObject(pNodeList); - ReleaseObject(pixdManifest); - - return hr; -} - -// Fixes the supportedRuntime element if necessary. -static HRESULT UpdateSupportedRuntime( - __in IXMLDOMDocument* pixdManifest, - __in IXMLDOMNode* pixnSupportedFramework, - __out BOOL* pfUpdatedManifest - ) -{ - HRESULT hr = S_OK; - LPWSTR sczSupportedRuntimeVersion = NULL; - IXMLDOMNode* pixnStartup = NULL; - IXMLDOMNode* pixnSupportedRuntime = NULL; - BOOL fXmlFound = FALSE; - - *pfUpdatedManifest = FALSE; - - // If the runtime version attribute is not specified, don't update the manifest. - hr = XmlGetAttributeEx(pixnSupportedFramework, L"runtimeVersion", &sczSupportedRuntimeVersion); - BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get supportedFramework/@runtimeVersion."); - - if (!fXmlFound) - { - ExitFunction(); - } - - // Get the startup element. Fail if we can't find it since it'll be necessary to load the - // correct runtime. - hr = XmlSelectSingleNode(pixdManifest, L"/configuration/startup", &pixnStartup); - BalExitOnRequiredXmlQueryFailure(hr, "Failed to get startup element."); - - // Remove any pre-existing supported runtimes because they'll just get in the way and create our new one. - hr = XmlRemoveChildren(pixnStartup, L"supportedRuntime"); - BalExitOnFailure(hr, "Failed to remove pre-existing supportedRuntime elements."); - - hr = XmlCreateChild(pixnStartup, L"supportedRuntime", &pixnSupportedRuntime); - BalExitOnFailure(hr, "Failed to create supportedRuntime element."); - - hr = XmlSetAttribute(pixnSupportedRuntime, L"version", sczSupportedRuntimeVersion); - BalExitOnFailure(hr, "Failed to set supportedRuntime/@version to '%ls'.", sczSupportedRuntimeVersion); - - *pfUpdatedManifest = TRUE; - -LExit: - ReleaseObject(pixnSupportedRuntime); - ReleaseObject(pixnStartup); - ReleaseStr(sczSupportedRuntimeVersion); - - return hr; -} - -// Gets the CLR host and caches it. -static HRESULT LoadRuntime( - __in MBASTATE* pState - ) -{ - HRESULT hr = S_OK; - UINT uiMode = 0; - HMODULE hModule = NULL; - BOOL fFallbackToCorBindToCurrentRuntime = TRUE; - CLRCreateInstanceFnPtr pfnCLRCreateInstance = NULL; - ICLRMetaHostPolicy* pCLRMetaHostPolicy = NULL; - IStream* pCfgStream = NULL; - LPWSTR pwzVersion = NULL; - DWORD cchVersion = 0; - DWORD dwConfigFlags = 0; - ICLRRuntimeInfo* pCLRRuntimeInfo = NULL; - PFN_CORBINDTOCURRENTRUNTIME pfnCorBindToCurrentRuntime = NULL; - - // Always set the error mode because we will always restore it below. - uiMode = ::SetErrorMode(0); - - // Check that the supported framework is installed. - hr = CheckSupportedFrameworks(pState->sczConfigPath); - BalExitOnFailure(hr, "Failed to find supported framework."); - - // Cache the CLR host to be shutdown later. This can occur on a different thread. - // Disable message boxes from being displayed on error and blocking execution. - ::SetErrorMode(uiMode | SEM_FAILCRITICALERRORS); - - hr = LoadSystemLibrary(L"mscoree.dll", &hModule); - BalExitOnFailure(hr, "Failed to load mscoree.dll"); - - pfnCLRCreateInstance = reinterpret_cast(::GetProcAddress(hModule, "CLRCreateInstance")); - - if (pfnCLRCreateInstance) - { - hr = pfnCLRCreateInstance(CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy, reinterpret_cast(&pCLRMetaHostPolicy)); - if (E_NOTIMPL != hr) - { - BalExitOnRootFailure(hr, "Failed to create instance of ICLRMetaHostPolicy."); - - fFallbackToCorBindToCurrentRuntime = FALSE; - } - } - - if (fFallbackToCorBindToCurrentRuntime) - { - pfnCorBindToCurrentRuntime = reinterpret_cast(::GetProcAddress(hModule, "CorBindToCurrentRuntime")); - BalExitOnNullWithLastError(pfnCorBindToCurrentRuntime, hr, "Failed to get procedure address for CorBindToCurrentRuntime."); - - hr = pfnCorBindToCurrentRuntime(pState->sczConfigPath, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, reinterpret_cast(&pState->pCLRHost)); - BalExitOnRootFailure(hr, "Failed to create the CLR host using the application configuration file path."); - } - else - { - - hr = SHCreateStreamOnFileEx(pState->sczConfigPath, STGM_READ | STGM_SHARE_DENY_WRITE, 0, FALSE, NULL, &pCfgStream); - BalExitOnFailure(hr, "Failed to load bootstrapper config file from path: %ls", pState->sczConfigPath); - - hr = pCLRMetaHostPolicy->GetRequestedRuntime(METAHOST_POLICY_HIGHCOMPAT, NULL, pCfgStream, NULL, &cchVersion, NULL, NULL, &dwConfigFlags, IID_ICLRRuntimeInfo, reinterpret_cast(&pCLRRuntimeInfo)); - BalExitOnRootFailure(hr, "Failed to get the CLR runtime info using the application configuration file path."); - - // .NET 4 RTM had a bug where it wouldn't set pcchVersion if pwzVersion was NULL. - if (!cchVersion) - { - hr = pCLRRuntimeInfo->GetVersionString(NULL, &cchVersion); - if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) != hr) - { - BalExitOnFailure(hr, "Failed to get the length of the CLR version string."); - } - } - - hr = StrAlloc(&pwzVersion, cchVersion); - ExitOnFailure(hr, "Failed to allocate the CLR version string."); - - hr = pCLRRuntimeInfo->GetVersionString(pwzVersion, &cchVersion); - ExitOnFailure(hr, "Failed to get the CLR version string."); - - if (CSTR_EQUAL == CompareString(LOCALE_NEUTRAL, 0, L"v4.0.30319", -1, pwzVersion, cchVersion)) - { - hr = VerifyNET4RuntimeIsSupported(); - BalExitOnFailure(hr, "Found unsupported .NET 4 Runtime."); - } - - if (METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_TRUE == (METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_MASK & dwConfigFlags)) - { - hr = pCLRRuntimeInfo->BindAsLegacyV2Runtime(); - BalExitOnRootFailure(hr, "Failed to bind as legacy V2 runtime."); - } - - hr = pCLRRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, reinterpret_cast(&pState->pCLRHost)); - BalExitOnRootFailure(hr, "Failed to get instance of ICorRuntimeHost."); - } - - hr = pState->pCLRHost->Start(); - BalExitOnRootFailure(hr, "Failed to start the CLR host."); - -LExit: - ReleaseStr(pwzVersion); - ReleaseNullObject(pCLRRuntimeInfo); - ReleaseNullObject(pCfgStream); - ReleaseNullObject(pCLRMetaHostPolicy); - - // Unload the module so it's not in use when we install .NET. - if (FAILED(hr)) - { - ::FreeLibrary(hModule); - } - - ::SetErrorMode(uiMode); // restore the previous error mode. - - return hr; -} - -// Creates the bootstrapper app and returns it for the engine. -static HRESULT CreateManagedBootstrapperApplication( - __in _AppDomain* pAppDomain, - __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, - __inout BOOTSTRAPPER_CREATE_RESULTS* pResults - ) -{ - HRESULT hr = S_OK; - IBootstrapperApplicationFactory* pAppFactory = NULL; - - hr = CreateManagedBootstrapperApplicationFactory(pAppDomain, &pAppFactory); - BalExitOnFailure(hr, "Failed to create the factory to create the bootstrapper application."); - - hr = pAppFactory->Create(pArgs, pResults); - BalExitOnFailure(hr, "Failed to create the bootstrapper application."); - -LExit: - ReleaseNullObject(pAppFactory); - - return hr; -} - -// Creates the app factory to create the managed app in the default AppDomain. -static HRESULT CreateManagedBootstrapperApplicationFactory( - __in _AppDomain* pAppDomain, - __out IBootstrapperApplicationFactory** ppAppFactory - ) -{ - HRESULT hr = S_OK; - BSTR bstrAssemblyName = NULL; - BSTR bstrTypeName = NULL; - _ObjectHandle* pObj = NULL; - VARIANT vtBAFactory; - - ::VariantInit(&vtBAFactory); - - bstrAssemblyName = ::SysAllocString(MBA_ASSEMBLY_FULL_NAME); - BalExitOnNull(bstrAssemblyName, hr, E_OUTOFMEMORY, "Failed to allocate the full assembly name for the bootstrapper application factory."); - - bstrTypeName = ::SysAllocString(MBA_ENTRY_TYPE); - BalExitOnNull(bstrTypeName, hr, E_OUTOFMEMORY, "Failed to allocate the full type name for the BA factory."); - - hr = pAppDomain->CreateInstance(bstrAssemblyName, bstrTypeName, &pObj); - BalExitOnRootFailure(hr, "Failed to create the BA factory object."); - - hr = pObj->Unwrap(&vtBAFactory); - BalExitOnRootFailure(hr, "Failed to unwrap the BA factory object into the host domain."); - BalExitOnNull(vtBAFactory.punkVal, hr, E_UNEXPECTED, "The variant did not contain the expected IUnknown pointer."); - - hr = vtBAFactory.punkVal->QueryInterface(__uuidof(IBootstrapperApplicationFactory), reinterpret_cast(ppAppFactory)); - BalExitOnRootFailure(hr, "Failed to query for the bootstrapper app factory interface."); - -LExit: - ReleaseVariant(vtBAFactory); - ReleaseNullObject(pObj); - ReleaseBSTR(bstrTypeName); - ReleaseBSTR(bstrAssemblyName); - - return hr; -} - -static HRESULT CreatePrerequisiteBA( - __in MBASTATE* pState, - __in IBootstrapperEngine* pEngine, - __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, - __inout BOOTSTRAPPER_CREATE_RESULTS* pResults - ) -{ - HRESULT hr = S_OK; - LPWSTR sczMbapreqPath = NULL; - HMODULE hModule = NULL; - - hr = PathConcat(pState->sczAppBase, L"mbapreq.dll", &sczMbapreqPath); - BalExitOnFailure(hr, "Failed to get path to pre-requisite BA."); - - hModule = ::LoadLibraryExW(sczMbapreqPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - BalExitOnNullWithLastError(hModule, hr, "Failed to load pre-requisite BA DLL."); - - PFN_PREQ_BOOTSTRAPPER_APPLICATION_CREATE pfnCreate = reinterpret_cast(::GetProcAddress(hModule, "PrereqBootstrapperApplicationCreate")); - BalExitOnNullWithLastError(pfnCreate, hr, "Failed to get PrereqBootstrapperApplicationCreate entry-point from: %ls", sczMbapreqPath); - - hr = pfnCreate(&pState->prereqData, pEngine, pArgs, pResults); - BalExitOnFailure(hr, "Failed to create prequisite bootstrapper app."); - - pState->hMbapreqModule = hModule; - hModule = NULL; - -LExit: - if (hModule) - { - ::FreeLibrary(hModule); - } - ReleaseStr(sczMbapreqPath); - - return hr; -} - -static HRESULT VerifyNET4RuntimeIsSupported( - ) -{ - HRESULT hr = S_OK; - OS_VERSION osv = OS_VERSION_UNKNOWN; - DWORD dwServicePack = 0; - HKEY hKey = NULL; - DWORD er = ERROR_SUCCESS; - DWORD dwRelease = 0; - DWORD cchRelease = sizeof(dwRelease); - - OsGetVersion(&osv, &dwServicePack); - if (OS_VERSION_WIN7 == osv && 0 == dwServicePack) - { - hr = RegOpen(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full", KEY_QUERY_VALUE, &hKey); - if (E_FILENOTFOUND == hr) - { - ExitFunction1(hr = S_OK); - } - BalExitOnFailure(hr, "Failed to open registry key for .NET 4."); - - er = ::RegQueryValueExW(hKey, L"Release", NULL, NULL, reinterpret_cast(&dwRelease), &cchRelease); - if (ERROR_FILE_NOT_FOUND == er) - { - ExitFunction1(hr = S_OK); - } - BalExitOnWin32Error(er, hr, "Failed to get Release value."); - - if (NET452_RELEASE <= dwRelease) - { - hr = E_MBAHOST_NET452_ON_WIN7RTM; - } - } - -LExit: - ReleaseRegKey(hKey); - - return hr; -} -- cgit v1.2.3-55-g6feb