extern "C" HRESULT MspEngineParsePackageFromXml( __in IXMLDOMNode* pixnMspPackage, __in BURN_PACKAGE* pPackage ) { HRESULT hr = S_OK; // @PatchCode hr = XmlGetAttributeEx(pixnMspPackage, L"PatchCode", &pPackage->Msp.sczPatchCode); ExitOnFailure(hr, "Failed to get @PatchCode."); // @PatchXml hr = XmlGetAttributeEx(pixnMspPackage, L"PatchXml", &pPackage->Msp.sczApplicabilityXml); ExitOnFailure(hr, "Failed to get @PatchXml."); // @DisplayInternalUI hr = XmlGetYesNoAttribute(pixnMspPackage, L"DisplayInternalUI", &pPackage->Msp.fDisplayInternalUI); ExitOnFailure(hr, "Failed to get @DisplayInternalUI."); // Read properties. hr = MsiEngineParsePropertiesFromXml(pixnMspPackage, &pPackage->Msp.rgProperties, &pPackage->Msp.cProperties); ExitOnFailure(hr, "Failed to parse properties from XML."); LExit: return hr; }
DAPI_(HRESULT) BalInfoParseFromXml( __in BAL_INFO_BUNDLE* pBundle, __in IXMLDOMDocument* pixdManifest ) { HRESULT hr = S_OK; IXMLDOMNode* pNode = NULL; hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixBundleProperties", &pNode); if (S_OK == hr) { hr = XmlGetYesNoAttribute(pNode, L"PerMachine", &pBundle->fPerMachine); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to read bundle information per-machine."); } hr = XmlGetAttributeEx(pNode, L"DisplayName", &pBundle->sczName); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to read bundle information display name."); } hr = XmlGetAttributeEx(pNode, L"LogPathVariable", &pBundle->sczLogVariable); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to read bundle information log path variable."); } } ExitOnFailure(hr, "Failed to select bundle information."); hr = ParsePackagesFromXml(&pBundle->packages, pixdManifest); BalExitOnFailure(hr, "Failed to parse package information from bootstrapper application data."); LExit: ReleaseObject(pNode); return hr; }
extern "C" HRESULT DependencyParseProvidersFromXml( __in BURN_PACKAGE* pPackage, __in IXMLDOMNode* pixnPackage ) { HRESULT hr = S_OK; IXMLDOMNodeList* pixnNodes = NULL; DWORD cNodes = 0; IXMLDOMNode* pixnNode = NULL; // Select dependency provider nodes. hr = XmlSelectNodes(pixnPackage, L"Provides", &pixnNodes); ExitOnFailure(hr, "Failed to select dependency provider nodes."); // Get dependency provider node count. hr = pixnNodes->get_length((long*)&cNodes); ExitOnFailure(hr, "Failed to get the dependency provider node count."); if (!cNodes) { ExitFunction1(hr = S_OK); } // Allocate memory for dependency provider pointers. pPackage->rgDependencyProviders = (BURN_DEPENDENCY_PROVIDER*)MemAlloc(sizeof(BURN_DEPENDENCY_PROVIDER) * cNodes, TRUE); ExitOnNull(pPackage->rgDependencyProviders, hr, E_OUTOFMEMORY, "Failed to allocate memory for dependency providers."); pPackage->cDependencyProviders = cNodes; // Parse dependency provider elements. for (DWORD i = 0; i < cNodes; i++) { BURN_DEPENDENCY_PROVIDER* pDependencyProvider = &pPackage->rgDependencyProviders[i]; hr = XmlNextElement(pixnNodes, &pixnNode, NULL); ExitOnFailure(hr, "Failed to get the next dependency provider node."); // @Key hr = XmlGetAttributeEx(pixnNode, L"Key", &pDependencyProvider->sczKey); ExitOnFailure(hr, "Failed to get the Key attribute."); // @Version hr = XmlGetAttributeEx(pixnNode, L"Version", &pDependencyProvider->sczVersion); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get the Version attribute."); } // @DisplayName hr = XmlGetAttributeEx(pixnNode, L"DisplayName", &pDependencyProvider->sczDisplayName); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get the DisplayName attribute."); } // @Imported hr = XmlGetYesNoAttribute(pixnNode, L"Imported", &pDependencyProvider->fImported); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get the Imported attribute."); } else { pDependencyProvider->fImported = FALSE; hr = S_OK; } // Prepare next iteration. ReleaseNullObject(pixnNode); } hr = S_OK; LExit: ReleaseObject(pixnNode); ReleaseObject(pixnNodes); return hr; }
extern "C" HRESULT ExeEngineParsePackageFromXml( __in IXMLDOMNode* pixnExePackage, __in BURN_PACKAGE* pPackage ) { HRESULT hr = S_OK; IXMLDOMNodeList* pixnNodes = NULL; IXMLDOMNode* pixnNode = NULL; DWORD cNodes = 0; LPWSTR scz = NULL; // @DetectCondition hr = XmlGetAttributeEx(pixnExePackage, L"DetectCondition", &pPackage->Exe.sczDetectCondition); ExitOnFailure(hr, "Failed to get @DetectCondition."); // @InstallArguments hr = XmlGetAttributeEx(pixnExePackage, L"InstallArguments", &pPackage->Exe.sczInstallArguments); ExitOnFailure(hr, "Failed to get @InstallArguments."); // @UninstallArguments hr = XmlGetAttributeEx(pixnExePackage, L"UninstallArguments", &pPackage->Exe.sczUninstallArguments); ExitOnFailure(hr, "Failed to get @UninstallArguments."); // @RepairArguments hr = XmlGetAttributeEx(pixnExePackage, L"RepairArguments", &pPackage->Exe.sczRepairArguments); ExitOnFailure(hr, "Failed to get @RepairArguments."); // @Repairable hr = XmlGetYesNoAttribute(pixnExePackage, L"Repairable", &pPackage->Exe.fRepairable); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get @Repairable."); } // @Protocol hr = XmlGetAttributeEx(pixnExePackage, L"Protocol", &scz); if (SUCCEEDED(hr)) { if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"burn", -1)) { pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_BURN; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"netfx4", -1)) { pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_NETFX4; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"none", -1)) { pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_NONE; } else { hr = E_UNEXPECTED; ExitOnFailure1(hr, "Invalid protocol type: %ls", scz); } } else if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get @Protocol."); } // select exit code nodes hr = XmlSelectNodes(pixnExePackage, L"ExitCode", &pixnNodes); ExitOnFailure(hr, "Failed to select exit code nodes."); // get exit code node count hr = pixnNodes->get_length((long*)&cNodes); ExitOnFailure(hr, "Failed to get exit code node count."); if (cNodes) { // allocate memory for exit codes pPackage->Exe.rgExitCodes = (BURN_EXE_EXIT_CODE*)MemAlloc(sizeof(BURN_EXE_EXIT_CODE) * cNodes, TRUE); ExitOnNull(pPackage->Exe.rgExitCodes, hr, E_OUTOFMEMORY, "Failed to allocate memory for exit code structs."); pPackage->Exe.cExitCodes = cNodes; // parse package elements for (DWORD i = 0; i < cNodes; ++i) { BURN_EXE_EXIT_CODE* pExitCode = &pPackage->Exe.rgExitCodes[i]; hr = XmlNextElement(pixnNodes, &pixnNode, NULL); ExitOnFailure(hr, "Failed to get next node."); // @Type hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); ExitOnFailure(hr, "Failed to get @Type."); if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"success", -1)) { pExitCode->type = BURN_EXE_EXIT_CODE_TYPE_SUCCESS; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"error", -1)) { pExitCode->type = BURN_EXE_EXIT_CODE_TYPE_ERROR; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"scheduleReboot", -1)) { pExitCode->type = BURN_EXE_EXIT_CODE_TYPE_SCHEDULE_REBOOT; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"forceReboot", -1)) { pExitCode->type = BURN_EXE_EXIT_CODE_TYPE_FORCE_REBOOT; } else { hr = E_UNEXPECTED; ExitOnFailure1(hr, "Invalid exit code type: %ls", scz); } // @Code hr = XmlGetAttributeEx(pixnNode, L"Code", &scz); ExitOnFailure(hr, "Failed to get @Code."); if (L'*' == scz[0]) { pExitCode->fWildcard = TRUE; } else { hr = StrStringToUInt32(scz, 0, (UINT*)&pExitCode->dwCode); ExitOnFailure1(hr, "Failed to parse @Code value: %ls", scz); } // prepare next iteration ReleaseNullObject(pixnNode); } } hr = S_OK; LExit: ReleaseObject(pixnNodes); ReleaseObject(pixnNode); ReleaseStr(scz); return hr; }
static HRESULT ParsePackagesFromXml( __in BAL_INFO_PACKAGES* pPackages, __in IXMLDOMDocument* pixdManifest ) { HRESULT hr = S_OK; IXMLDOMNodeList* pNodeList = NULL; IXMLDOMNode* pNode = NULL; BAL_INFO_PACKAGE* prgPackages = NULL; DWORD cPackages = 0; LPWSTR sczType = NULL; hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixPackageProperties", &pNodeList); ExitOnFailure(hr, "Failed to select all packages."); hr = pNodeList->get_length(reinterpret_cast<long*>(&cPackages)); ExitOnFailure(hr, "Failed to get the package count."); prgPackages = static_cast<BAL_INFO_PACKAGE*>(MemAlloc(sizeof(BAL_INFO_PACKAGE) * cPackages, TRUE)); ExitOnNull(prgPackages, hr, E_OUTOFMEMORY, "Failed to allocate memory for packages."); DWORD iPackage = 0; while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, NULL))) { hr = XmlGetAttributeEx(pNode, L"Package", &prgPackages[iPackage].sczId); ExitOnFailure(hr, "Failed to get package identifier for package."); hr = XmlGetAttributeEx(pNode, L"DisplayName", &prgPackages[iPackage].sczDisplayName); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get description for package."); } hr = XmlGetAttributeEx(pNode, L"Description", &prgPackages[iPackage].sczDescription); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get description for package."); } hr = XmlGetAttributeEx(pNode, L"PackageType", &sczType); ExitOnFailure(hr, "Failed to get description for package."); if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, L"Exe", -1, sczType, -1)) { prgPackages[iPackage].type = BAL_INFO_PACKAGE_TYPE_EXE; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, L"Msi", -1, sczType, -1)) { prgPackages[iPackage].type = BAL_INFO_PACKAGE_TYPE_MSI; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, L"Msp", -1, sczType, -1)) { prgPackages[iPackage].type = BAL_INFO_PACKAGE_TYPE_MSP; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, L"Msu", -1, sczType, -1)) { prgPackages[iPackage].type = BAL_INFO_PACKAGE_TYPE_MSU; } hr = XmlGetYesNoAttribute(pNode, L"Permanent", &prgPackages[iPackage].fPermanent); ExitOnFailure(hr, "Failed to get permanent setting for package."); hr = XmlGetYesNoAttribute(pNode, L"Vital", &prgPackages[iPackage].fVital); ExitOnFailure(hr, "Failed to get vital setting for package."); hr = XmlGetYesNoAttribute(pNode, L"DisplayInternalUI", &prgPackages[iPackage].fDisplayInternalUI); ExitOnFailure(hr, "Failed to get DisplayInternalUI setting for package."); ++iPackage; ReleaseNullObject(pNode); } ExitOnFailure(hr, "Failed to parse all package property elements."); if (S_FALSE == hr) { hr = S_OK; } pPackages->cPackages = cPackages; pPackages->rgPackages = prgPackages; prgPackages = NULL; LExit: ReleaseStr(sczType); ReleaseMem(prgPackages); ReleaseObject(pNode); ReleaseObject(pNodeList); return hr; }
extern "C" HRESULT ApprovedExesParseFromXml( __in BURN_APPROVED_EXES* pApprovedExes, __in IXMLDOMNode* pixnBundle ) { HRESULT hr = S_OK; IXMLDOMNodeList* pixnNodes = NULL; IXMLDOMNode* pixnNode = NULL; DWORD cNodes = 0; LPWSTR scz = NULL; // select approved exe nodes hr = XmlSelectNodes(pixnBundle, L"ApprovedExeForElevation", &pixnNodes); ExitOnFailure(hr, "Failed to select approved exe nodes."); // get approved exe node count hr = pixnNodes->get_length((long*)&cNodes); ExitOnFailure(hr, "Failed to get approved exe node count."); if (!cNodes) { ExitFunction(); } // allocate memory for approved exes pApprovedExes->rgApprovedExes = (BURN_APPROVED_EXE*)MemAlloc(sizeof(BURN_APPROVED_EXE) * cNodes, TRUE); ExitOnNull(pApprovedExes->rgApprovedExes, hr, E_OUTOFMEMORY, "Failed to allocate memory for approved exe structs."); pApprovedExes->cApprovedExes = cNodes; // parse approved exe elements for (DWORD i = 0; i < cNodes; ++i) { BURN_APPROVED_EXE* pApprovedExe = &pApprovedExes->rgApprovedExes[i]; hr = XmlNextElement(pixnNodes, &pixnNode, NULL); ExitOnFailure(hr, "Failed to get next node."); // @Id hr = XmlGetAttributeEx(pixnNode, L"Id", &pApprovedExe->sczId); ExitOnFailure(hr, "Failed to get @Id."); // @Key hr = XmlGetAttributeEx(pixnNode, L"Key", &pApprovedExe->sczKey); ExitOnFailure(hr, "Failed to get @Key."); // @ValueName hr = XmlGetAttributeEx(pixnNode, L"ValueName", &pApprovedExe->sczValueName); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get @ValueName."); } // @Win64 hr = XmlGetYesNoAttribute(pixnNode, L"Win64", &pApprovedExe->fWin64); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get @Win64."); } // prepare next iteration ReleaseNullObject(pixnNode); ReleaseNullStr(scz); } hr = S_OK; LExit: ReleaseObject(pixnNodes); ReleaseObject(pixnNode); ReleaseStr(scz); return hr; }
extern "C" HRESULT PayloadsParseFromXml( __in BURN_PAYLOADS* pPayloads, __in_opt BURN_CONTAINERS* pContainers, __in_opt BURN_CATALOGS* pCatalogs, __in IXMLDOMNode* pixnBundle ) { HRESULT hr = S_OK; IXMLDOMNodeList* pixnNodes = NULL; IXMLDOMNode* pixnNode = NULL; DWORD cNodes = 0; LPWSTR scz = NULL; // select payload nodes hr = XmlSelectNodes(pixnBundle, L"Payload", &pixnNodes); ExitOnFailure(hr, "Failed to select payload nodes."); // get payload node count hr = pixnNodes->get_length((long*)&cNodes); ExitOnFailure(hr, "Failed to get payload node count."); if (!cNodes) { ExitFunction(); } // allocate memory for payloads pPayloads->rgPayloads = (BURN_PAYLOAD*)MemAlloc(sizeof(BURN_PAYLOAD) * cNodes, TRUE); ExitOnNull(pPayloads->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate memory for payload structs."); pPayloads->cPayloads = cNodes; // parse search elements for (DWORD i = 0; i < cNodes; ++i) { BURN_PAYLOAD* pPayload = &pPayloads->rgPayloads[i]; hr = XmlNextElement(pixnNodes, &pixnNode, NULL); ExitOnFailure(hr, "Failed to get next node."); // @Id hr = XmlGetAttributeEx(pixnNode, L"Id", &pPayload->sczKey); ExitOnFailure(hr, "Failed to get @Id."); // @FilePath hr = XmlGetAttributeEx(pixnNode, L"FilePath", &pPayload->sczFilePath); ExitOnFailure(hr, "Failed to get @FilePath."); // @Packaging hr = XmlGetAttributeEx(pixnNode, L"Packaging", &scz); ExitOnFailure(hr, "Failed to get @Packaging."); if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"download", -1)) { pPayload->packaging = BURN_PAYLOAD_PACKAGING_DOWNLOAD; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"embedded", -1)) { pPayload->packaging = BURN_PAYLOAD_PACKAGING_EMBEDDED; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"external", -1)) { pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL; } else { hr = E_INVALIDARG; ExitOnFailure(hr, "Invalid value for @Packaging: %ls", scz); } // @Container if (pContainers) { hr = XmlGetAttributeEx(pixnNode, L"Container", &scz); if (E_NOTFOUND != hr || BURN_PAYLOAD_PACKAGING_EMBEDDED == pPayload->packaging) { ExitOnFailure(hr, "Failed to get @Container."); // find container hr = ContainerFindById(pContainers, scz, &pPayload->pContainer); ExitOnFailure(hr, "Failed to to find container: %ls", scz); } } // @LayoutOnly hr = XmlGetYesNoAttribute(pixnNode, L"LayoutOnly", &pPayload->fLayoutOnly); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get @LayoutOnly."); } // @SourcePath hr = XmlGetAttributeEx(pixnNode, L"SourcePath", &pPayload->sczSourcePath); if (E_NOTFOUND != hr || BURN_PAYLOAD_PACKAGING_DOWNLOAD != pPayload->packaging) { ExitOnFailure(hr, "Failed to get @SourcePath."); } // @DownloadUrl hr = XmlGetAttributeEx(pixnNode, L"DownloadUrl", &pPayload->downloadSource.sczUrl); if (E_NOTFOUND != hr || BURN_PAYLOAD_PACKAGING_DOWNLOAD == pPayload->packaging) { ExitOnFailure(hr, "Failed to get @DownloadUrl."); } // @FileSize hr = XmlGetAttributeEx(pixnNode, L"FileSize", &scz); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get @FileSize."); hr = StrStringToUInt64(scz, 0, &pPayload->qwFileSize); ExitOnFailure(hr, "Failed to parse @FileSize."); } // @CertificateAuthorityKeyIdentifier hr = XmlGetAttributeEx(pixnNode, L"CertificateRootPublicKeyIdentifier", &scz); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get @CertificateRootPublicKeyIdentifier."); hr = StrAllocHexDecode(scz, &pPayload->pbCertificateRootPublicKeyIdentifier, &pPayload->cbCertificateRootPublicKeyIdentifier); ExitOnFailure(hr, "Failed to hex decode @CertificateRootPublicKeyIdentifier."); } // @CertificateThumbprint hr = XmlGetAttributeEx(pixnNode, L"CertificateRootThumbprint", &scz); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get @CertificateRootThumbprint."); hr = StrAllocHexDecode(scz, &pPayload->pbCertificateRootThumbprint, &pPayload->cbCertificateRootThumbprint); ExitOnFailure(hr, "Failed to hex decode @CertificateRootThumbprint."); } // @Hash hr = XmlGetAttributeEx(pixnNode, L"Hash", &scz); ExitOnFailure(hr, "Failed to get @Hash."); hr = StrAllocHexDecode(scz, &pPayload->pbHash, &pPayload->cbHash); ExitOnFailure(hr, "Failed to hex decode the Payload/@Hash."); // @Catalog hr = XmlGetAttributeEx(pixnNode, L"Catalog", &scz); if (E_NOTFOUND != hr) { ExitOnFailure(hr, "Failed to get @Catalog."); hr = CatalogFindById(pCatalogs, scz, &pPayload->pCatalog); ExitOnFailure(hr, "Failed to find catalog."); } // prepare next iteration ReleaseNullObject(pixnNode); } hr = S_OK; LExit: ReleaseObject(pixnNodes); ReleaseObject(pixnNode); ReleaseStr(scz); return hr; }