// 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" STDMETHODIMP NetfxSearchParseFromXml( __in NETFX_SEARCHES* pSearches, __in IXMLDOMNode* pixnBootstrapperExtension ) { HRESULT hr = S_OK; IXMLDOMNodeList* pixnNodes = NULL; IXMLDOMNode* pixnNode = NULL; DWORD cNodes = 0; BSTR bstrNodeName = NULL; // Select Netfx search nodes. hr = XmlSelectNodes(pixnBootstrapperExtension, L"NetFxNetCoreSearch|NetFxNetCoreSdkSearch|NetFxNetCoreSdkFeatureBandSearch", &pixnNodes); BextExitOnFailure(hr, "Failed to select Netfx search nodes."); // Get Netfx search node count. hr = pixnNodes->get_length((long*)&cNodes); BextExitOnFailure(hr, "Failed to get Netfx search node count."); if (!cNodes) { ExitFunction(); } // Allocate memory for searches. pSearches->rgSearches = (NETFX_SEARCH*)MemAlloc(sizeof(NETFX_SEARCH) * cNodes, TRUE); BextExitOnNull(pSearches->rgSearches, hr, E_OUTOFMEMORY, "Failed to allocate memory for search structs."); pSearches->cSearches = cNodes; // Parse search elements. for (DWORD i = 0; i < cNodes; ++i) { NETFX_SEARCH* pSearch = &pSearches->rgSearches[i]; hr = XmlNextElement(pixnNodes, &pixnNode, &bstrNodeName); BextExitOnFailure(hr, "Failed to get next node."); // @Id hr = XmlGetAttributeEx(pixnNode, L"Id", &pSearch->sczId); BextExitOnFailure(hr, "Failed to get @Id."); // Read type specific attributes. if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"NetFxNetCoreSearch", -1)) { pSearch->Type = NETFX_SEARCH_TYPE_NET_CORE_SEARCH; auto& netCoreSearch = pSearch->NetCoreSearch; // @RuntimeType hr = XmlGetAttributeUInt32(pixnNode, L"RuntimeType", reinterpret_cast(&netCoreSearch.runtimeType)); BextExitOnFailure(hr, "Failed to get @RuntimeType."); // @Platform hr = XmlGetAttributeUInt32(pixnNode, L"Platform", reinterpret_cast(&netCoreSearch.platform)); BextExitOnFailure(hr, "Failed to get @Platform."); // @MajorVersion hr = XmlGetAttributeEx(pixnNode, L"MajorVersion", &netCoreSearch.sczMajorVersion); BextExitOnFailure(hr, "Failed to get @MajorVersion."); } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"NetFxNetCoreSdkSearch", -1)) { pSearch->Type = NETFX_SEARCH_TYPE_NET_CORE_SDK_SEARCH; auto& netCoreSdkSearch = pSearch->NetCoreSdkSearch; // @Platform hr = XmlGetAttributeUInt32(pixnNode, L"Platform", reinterpret_cast(&netCoreSdkSearch.platform)); BextExitOnFailure(hr, "Failed to get @Platform."); // @MajorVersion hr = XmlGetAttributeEx(pixnNode, L"MajorVersion", &netCoreSdkSearch.sczMajorVersion); BextExitOnFailure(hr, "Failed to get @MajorVersion."); } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"NetFxNetCoreSdkFeatureBandSearch", -1)) { pSearch->Type = NETFX_SEARCH_TYPE_NET_CORE_SDK_FEATURE_BAND_SEARCH; auto& netCoreSdkSearch = pSearch->NetCoreSdkFeatureBandSearch; // @Platform hr = XmlGetAttributeUInt32(pixnNode, L"Platform", reinterpret_cast(&netCoreSdkSearch.platform)); BextExitOnFailure(hr, "Failed to get @Platform."); // @MajorVersion hr = XmlGetAttributeEx(pixnNode, L"MajorVersion", &netCoreSdkSearch.sczMajorVersion); BextExitOnFailure(hr, "Failed to get @MajorVersion."); // @MinorVersion hr = XmlGetAttributeEx(pixnNode, L"MinorVersion", &netCoreSdkSearch.sczMinorVersion); BextExitOnFailure(hr, "Failed to get @MinorVersion."); // @PatchVersion hr = XmlGetAttributeEx(pixnNode, L"PatchVersion", &netCoreSdkSearch.sczPatchVersion); BextExitOnFailure(hr, "Failed to get @PatchVersion."); } else { BextExitWithRootFailure(hr, E_UNEXPECTED, "Unexpected element name: %ls", bstrNodeName); } // prepare next iteration ReleaseNullObject(pixnNode); ReleaseNullBSTR(bstrNodeName); } LExit: ReleaseBSTR(bstrNodeName); ReleaseObject(pixnNode); ReleaseObject(pixnNodes); return hr; } void NetfxSearchUninitialize( __in NETFX_SEARCHES* pSearches ) { if (pSearches->rgSearches) { for (DWORD i = 0; i < pSearches->cSearches; ++i) { NETFX_SEARCH* pSearch = &pSearches->rgSearches[i]; ReleaseStr(pSearch->sczId); } MemFree(pSearches->rgSearches); } } STDMETHODIMP NetfxSearchExecute( __in NETFX_SEARCHES* pSearches, __in LPCWSTR wzSearchId, __in LPCWSTR wzVariable, __in IBootstrapperExtensionEngine* pEngine, __in LPCWSTR wzBaseDirectory ) { HRESULT hr = S_OK; NETFX_SEARCH* pSearch = NULL; hr = NetfxSearchFindById(pSearches, wzSearchId, &pSearch); BextExitOnFailure(hr, "Search id '%ls' is unknown to the util extension.", wzSearchId); switch (pSearch->Type) { case NETFX_SEARCH_TYPE_NET_CORE_SEARCH: hr = NetfxPerformDetectNetCore(wzVariable, pSearch, pEngine, wzBaseDirectory); break; case NETFX_SEARCH_TYPE_NET_CORE_SDK_SEARCH: hr = NetfxPerformDetectNetCoreSdk(wzVariable, pSearch, pEngine, wzBaseDirectory); break; case NETFX_SEARCH_TYPE_NET_CORE_SDK_FEATURE_BAND_SEARCH: hr = NetfxPerformDetectNetCoreSdkFeatureBand(wzVariable, pSearch, pEngine, wzBaseDirectory); break; default: hr = E_UNEXPECTED; } LExit: return hr; } STDMETHODIMP NetfxSearchFindById( __in NETFX_SEARCHES* pSearches, __in LPCWSTR wzId, __out NETFX_SEARCH** ppSearch ) { HRESULT hr = S_OK; for (DWORD i = 0; i < pSearches->cSearches; ++i) { NETFX_SEARCH* pSearch = &pSearches->rgSearches[i]; if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pSearch->sczId, -1, wzId, -1)) { *ppSearch = pSearch; ExitFunction1(hr = S_OK); } } hr = E_NOTFOUND; LExit: return hr; }