From 9010bd828e70e91523ed74733cc371eec09f58bb Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Fri, 15 May 2020 17:18:36 +1000 Subject: WIXFEAT:6164 Update BAL_INFO_PACKAGE with bal specific data. --- src/WixToolset.Mba.Core/BundleInfo.cs | 8 +-- src/WixToolset.Mba.Core/IBundleInfo.cs | 2 +- src/WixToolset.Mba.Core/IPackageInfo.cs | 6 +- src/WixToolset.Mba.Core/PackageInfo.cs | 64 ++++++++++++++++++--- src/balutil/balinfo.cpp | 99 ++++++++++++++++++++++++++++++--- src/balutil/balutil.vcxproj | 4 +- src/balutil/inc/balinfo.h | 9 ++- src/balutil/inc/balutil.h | 3 + src/balutil/packages.config | 2 +- src/bextutil/bextutil.vcxproj | 4 +- src/bextutil/packages.config | 2 +- src/mbanative/mbanative.vcxproj | 4 +- src/mbanative/packages.config | 2 +- 13 files changed, 177 insertions(+), 32 deletions(-) diff --git a/src/WixToolset.Mba.Core/BundleInfo.cs b/src/WixToolset.Mba.Core/BundleInfo.cs index e6d2f6e6..e1a56878 100644 --- a/src/WixToolset.Mba.Core/BundleInfo.cs +++ b/src/WixToolset.Mba.Core/BundleInfo.cs @@ -20,10 +20,11 @@ namespace WixToolset.Mba.Core this.Packages = new Dictionary(); } - public void AddRelatedBundleAsPackage(DetectRelatedBundleEventArgs e) + public IPackageInfo AddRelatedBundleAsPackage(DetectRelatedBundleEventArgs e) { var package = PackageInfo.GetRelatedBundleAsPackage(e.ProductCode, e.RelationType, e.PerMachine, e.Version); this.Packages.Add(package.Id, package); + return package; } public static IBundleInfo ParseBundleFromStream(Stream stream) @@ -56,10 +57,7 @@ namespace WixToolset.Mba.Core bundle.LogVariable = BootstrapperApplicationData.GetAttribute(bundleNode, "LogPathVariable"); - foreach (var package in PackageInfo.ParsePackagesFromXml(root)) - { - bundle.Packages.Add(package.Id, package); - } + bundle.Packages = PackageInfo.ParsePackagesFromXml(root); return bundle; } diff --git a/src/WixToolset.Mba.Core/IBundleInfo.cs b/src/WixToolset.Mba.Core/IBundleInfo.cs index 3d5b067e..d471c677 100644 --- a/src/WixToolset.Mba.Core/IBundleInfo.cs +++ b/src/WixToolset.Mba.Core/IBundleInfo.cs @@ -11,6 +11,6 @@ namespace WixToolset.Mba.Core IDictionary Packages { get; } bool PerMachine { get; } - void AddRelatedBundleAsPackage(DetectRelatedBundleEventArgs e); + IPackageInfo AddRelatedBundleAsPackage(DetectRelatedBundleEventArgs e); } } \ No newline at end of file diff --git a/src/WixToolset.Mba.Core/IPackageInfo.cs b/src/WixToolset.Mba.Core/IPackageInfo.cs index 5afe4b38..a82e81ea 100644 --- a/src/WixToolset.Mba.Core/IPackageInfo.cs +++ b/src/WixToolset.Mba.Core/IPackageInfo.cs @@ -5,12 +5,16 @@ namespace WixToolset.Mba.Core public interface IPackageInfo { CacheType CacheType { get; } + object CustomData { get; set; } string Description { get; } - bool DisplayInternalUI { get; } + string DisplayInternalUICondition { get; } string DisplayName { get; } string Id { get; } string InstallCondition { get; } bool Permanent { get; } + bool PrereqPackage { get; } + string PrereqLicenseFile { get; } + string PrereqLicenseUrl { get; } string ProductCode { get; } PackageType Type { get; } string UpgradeCode { get; } diff --git a/src/WixToolset.Mba.Core/PackageInfo.cs b/src/WixToolset.Mba.Core/PackageInfo.cs index 46894d2e..d3199c08 100644 --- a/src/WixToolset.Mba.Core/PackageInfo.cs +++ b/src/WixToolset.Mba.Core/PackageInfo.cs @@ -34,17 +34,22 @@ namespace WixToolset.Mba.Core public PackageType Type { get; internal set; } public bool Permanent { get; internal set; } public bool Vital { get; internal set; } - public bool DisplayInternalUI { get; internal set; } + public string DisplayInternalUICondition { get; internal set; } public string ProductCode { get; internal set; } public string UpgradeCode { get; internal set; } public string Version { get; internal set; } public string InstallCondition { get; internal set; } public CacheType CacheType { get; internal set; } + public bool PrereqPackage { get; internal set; } + public string PrereqLicenseFile { get; internal set; } + public string PrereqLicenseUrl { get; internal set; } + public object CustomData { get; set; } internal PackageInfo() { } - public static IEnumerable ParsePackagesFromXml(XPathNavigator root) + public static IDictionary ParsePackagesFromXml(XPathNavigator root) { + var packagesById = new Dictionary(); XmlNamespaceManager namespaceManager = new XmlNamespaceManager(root.NameTable); namespaceManager.AddNamespace("p", BootstrapperApplicationData.XMLNamespace); XPathNodeIterator nodes = root.Select("/p:BootstrapperApplicationData/p:WixPackageProperties", namespaceManager); @@ -85,9 +90,6 @@ namespace WixToolset.Mba.Core } package.Vital = vital.Value; - bool? displayInternalUI = BootstrapperApplicationData.GetYesNoAttribute(node, "DisplayInternalUI"); - package.DisplayInternalUI = displayInternalUI.HasValue && displayInternalUI.Value; - package.ProductCode = BootstrapperApplicationData.GetAttribute(node, "ProductCode"); package.UpgradeCode = BootstrapperApplicationData.GetAttribute(node, "UpgradeCode"); @@ -96,8 +98,11 @@ namespace WixToolset.Mba.Core package.InstallCondition = BootstrapperApplicationData.GetAttribute(node, "InstallCondition"); - yield return package; + packagesById.Add(package.Id, package); } + + ParseBalPackageInfoFromXml(root, namespaceManager, packagesById); + return packagesById; } public static CacheType? GetCacheTypeAttribute(XPathNavigator node, string attributeName) @@ -154,7 +159,7 @@ namespace WixToolset.Mba.Core } } - public static PackageInfo GetRelatedBundleAsPackage(string id, RelationType relationType, bool perMachine, Version version) + public static IPackageInfo GetRelatedBundleAsPackage(string id, RelationType relationType, bool perMachine, Version version) { PackageInfo package = new PackageInfo(); package.Id = id; @@ -177,5 +182,50 @@ namespace WixToolset.Mba.Core return package; } + + internal static void ParseBalPackageInfoFromXml(XPathNavigator root, XmlNamespaceManager namespaceManager, Dictionary packagesById) + { + XPathNodeIterator nodes = root.Select("/p:BootstrapperApplicationData/p:WixBalPackageInfo", namespaceManager); + + foreach (XPathNavigator node in nodes) + { + string id = BootstrapperApplicationData.GetAttribute(node, "PackageId"); + if (id == null) + { + throw new Exception("Failed to get package identifier for WixBalPackageInfo."); + } + + if (!packagesById.TryGetValue(id, out var ipackage)) + { + throw new Exception(string.Format("Failed to find package specified in WixBalPackageInfo: {0}", id)); + } + + var package = (PackageInfo)ipackage; + + package.DisplayInternalUICondition = BootstrapperApplicationData.GetAttribute(node, "DisplayInternalUICondition"); + } + + nodes = root.Select("/p:BootstrapperApplicationData/p:WixMbaPrereqInformation", namespaceManager); + + foreach (XPathNavigator node in nodes) + { + string id = BootstrapperApplicationData.GetAttribute(node, "PackageId"); + if (id == null) + { + throw new Exception("Failed to get package identifier for WixMbaPrereqInformation."); + } + + if (!packagesById.TryGetValue(id, out var ipackage)) + { + throw new Exception(string.Format("Failed to find package specified in WixMbaPrereqInformation: {0}", id)); + } + + var package = (PackageInfo)ipackage; + + package.PrereqPackage = true; + package.PrereqLicenseFile = BootstrapperApplicationData.GetAttribute(node, "LicenseFile"); + package.PrereqLicenseUrl = BootstrapperApplicationData.GetAttribute(node, "LicenseUrl"); + } + } } } diff --git a/src/balutil/balinfo.cpp b/src/balutil/balinfo.cpp index b36e3741..492c8e08 100644 --- a/src/balutil/balinfo.cpp +++ b/src/balutil/balinfo.cpp @@ -7,6 +7,10 @@ static HRESULT ParsePackagesFromXml( __in BAL_INFO_PACKAGES* pPackages, __in IXMLDOMDocument* pixdManifest ); +static HRESULT ParseBalPackageInfoFromXml( + __in BAL_INFO_PACKAGES* pPackages, + __in IXMLDOMDocument* pixdManifest + ); DAPI_(HRESULT) BalInfoParseFromXml( @@ -44,6 +48,9 @@ DAPI_(HRESULT) BalInfoParseFromXml( hr = ParsePackagesFromXml(&pBundle->packages, pixdManifest); BalExitOnFailure(hr, "Failed to parse package information from bootstrapper application data."); + hr = ParseBalPackageInfoFromXml(&pBundle->packages, pixdManifest); + BalExitOnFailure(hr, "Failed to parse bal package information from bootstrapper application data."); + LExit: ReleaseObject(pNode); @@ -55,7 +62,8 @@ DAPI_(HRESULT) BalInfoAddRelatedBundleAsPackage( __in BAL_INFO_PACKAGES* pPackages, __in LPCWSTR wzId, __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in BOOL /*fPerMachine*/ + __in BOOL /*fPerMachine*/, + __out_opt BAL_INFO_PACKAGE** ppPackage ) { HRESULT hr = S_OK; @@ -104,6 +112,11 @@ DAPI_(HRESULT) BalInfoAddRelatedBundleAsPackage( // TODO: try to look up the DisplayName and Description in Add/Remove Programs with the wzId. + if (ppPackage) + { + *ppPackage = pPackage; + } + LExit: return hr; } @@ -139,10 +152,13 @@ DAPI_(void) BalInfoUninitialize( ReleaseStr(pBundle->packages.rgPackages[i].sczDisplayName); ReleaseStr(pBundle->packages.rgPackages[i].sczDescription); ReleaseStr(pBundle->packages.rgPackages[i].sczId); + ReleaseStr(pBundle->packages.rgPackages[i].sczDisplayInternalUICondition); ReleaseStr(pBundle->packages.rgPackages[i].sczProductCode); ReleaseStr(pBundle->packages.rgPackages[i].sczUpgradeCode); ReleaseStr(pBundle->packages.rgPackages[i].sczVersion); ReleaseStr(pBundle->packages.rgPackages[i].sczInstallCondition); + ReleaseStr(pBundle->packages.rgPackages[i].sczPrereqLicenseFile); + ReleaseStr(pBundle->packages.rgPackages[i].sczPrereqLicenseUrl); } ReleaseMem(pBundle->packages.rgPackages); @@ -218,12 +234,6 @@ static HRESULT ParsePackagesFromXml( 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); - if (E_NOTFOUND != hr) - { - ExitOnFailure(hr, "Failed to get DisplayInternalUI setting for package."); - } - hr = XmlGetAttributeEx(pNode, L"ProductCode", &prgPackages[iPackage].sczProductCode); if (E_NOTFOUND != hr) { @@ -286,3 +296,78 @@ LExit: return hr; } + + +static HRESULT ParseBalPackageInfoFromXml( + __in BAL_INFO_PACKAGES* pPackages, + __in IXMLDOMDocument* pixdManifest + ) +{ + HRESULT hr = S_OK; + IXMLDOMNodeList* pNodeList = NULL; + IXMLDOMNode* pNode = NULL; + LPWSTR scz = NULL; + BAL_INFO_PACKAGE* pPackage = NULL; + + hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixBalPackageInfo", &pNodeList); + ExitOnFailure(hr, "Failed to select all packages."); + + while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, NULL))) + { + hr = XmlGetAttributeEx(pNode, L"PackageId", &scz); + ExitOnFailure(hr, "Failed to get package identifier for WixBalPackageInfo."); + + hr = BalInfoFindPackageById(pPackages, scz, &pPackage); + ExitOnFailure(hr, "Failed to find package specified in WixBalPackageInfo: %ls", scz); + + hr = XmlGetAttributeEx(pNode, L"DisplayInternalUICondition", &pPackage->sczDisplayInternalUICondition); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to get DisplayInternalUICondition setting for package."); + } + + ReleaseNullObject(pNode); + } + ExitOnFailure(hr, "Failed to parse all WixBalPackageInfo elements."); + + hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixMbaPrereqInformation", &pNodeList); + ExitOnFailure(hr, "Failed to select all packages."); + + while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, NULL))) + { + hr = XmlGetAttributeEx(pNode, L"PackageId", &scz); + ExitOnFailure(hr, "Failed to get package identifier for WixMbaPrereqInformation."); + + hr = BalInfoFindPackageById(pPackages, scz, &pPackage); + ExitOnFailure(hr, "Failed to find package specified in WixMbaPrereqInformation: %ls", scz); + + pPackage->fPrereqPackage = TRUE; + + hr = XmlGetAttributeEx(pNode, L"LicenseFile", &pPackage->sczPrereqLicenseFile); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to get LicenseFile setting for prereq package."); + } + + hr = XmlGetAttributeEx(pNode, L"LicenseUrl", &pPackage->sczPrereqLicenseUrl); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to get LicenseUrl setting for prereq package."); + } + + ReleaseNullObject(pNode); + } + ExitOnFailure(hr, "Failed to parse all WixMbaPrereqInformation elements."); + + if (S_FALSE == hr) + { + hr = S_OK; + } + +LExit: + ReleaseStr(scz); + ReleaseObject(pNode); + ReleaseObject(pNodeList); + + return hr; +} diff --git a/src/balutil/balutil.vcxproj b/src/balutil/balutil.vcxproj index f37fde17..31f0a9f7 100644 --- a/src/balutil/balutil.vcxproj +++ b/src/balutil/balutil.vcxproj @@ -3,7 +3,7 @@ - + @@ -91,7 +91,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/balutil/inc/balinfo.h b/src/balutil/inc/balinfo.h index be4b75d0..0d838ae3 100644 --- a/src/balutil/inc/balinfo.h +++ b/src/balutil/inc/balinfo.h @@ -34,12 +34,16 @@ typedef struct _BAL_INFO_PACKAGE BAL_INFO_PACKAGE_TYPE type; BOOL fPermanent; BOOL fVital; - BOOL fDisplayInternalUI; + LPWSTR sczDisplayInternalUICondition; LPWSTR sczProductCode; LPWSTR sczUpgradeCode; LPWSTR sczVersion; LPWSTR sczInstallCondition; BAL_INFO_CACHE_TYPE cacheType; + BOOL fPrereqPackage; + LPWSTR sczPrereqLicenseFile; + LPWSTR sczPrereqLicenseUrl; + LPVOID pvCustomData; } BAL_INFO_PACKAGE; @@ -78,7 +82,8 @@ DAPI_(HRESULT) BalInfoAddRelatedBundleAsPackage( __in BAL_INFO_PACKAGES* pPackages, __in LPCWSTR wzId, __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in BOOL fPerMachine + __in BOOL fPerMachine, + __out_opt BAL_INFO_PACKAGE** ppPackage ); diff --git a/src/balutil/inc/balutil.h b/src/balutil/inc/balutil.h index b2d50752..bbfb16a2 100644 --- a/src/balutil/inc/balutil.h +++ b/src/balutil/inc/balutil.h @@ -11,7 +11,10 @@ extern "C" { #define BalExitOnFailure(x, f, ...) if (FAILED(x)) { BalLogError(x, f, __VA_ARGS__); ExitTrace(x, f, __VA_ARGS__); goto LExit; } #define BalExitOnRootFailure(x, f, ...) if (FAILED(x)) { BalLogError(x, f, __VA_ARGS__); Dutil_RootFailure(__FILE__, __LINE__, x); ExitTrace(x, f, __VA_ARGS__); goto LExit; } +#define BalExitOnLastError(x, f, ...) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { BalLogError(x, f, __VA_ARGS__); ExitTrace(x, f, __VA_ARGS__); goto LExit; } } +#define BalExitOnNull(p, x, e, f, ...) if (NULL == p) { x = e; BalLogError(x, f, __VA_ARGS__); ExitTrace(x, f, __VA_ARGS__); goto LExit; } #define BalExitOnNullWithLastError(p, x, f, ...) if (NULL == p) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } BalLogError(x, f, __VA_ARGS__); ExitTrace(x, f, __VA_ARGS__); goto LExit; } +#define BalExitWithLastError(x, f, ...) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } BalLogError(x, f, __VA_ARGS__); ExitTrace(x, f, __VA_ARGS__); goto LExit; } #ifndef FACILITY_WIX #define FACILITY_WIX 500 diff --git a/src/balutil/packages.config b/src/balutil/packages.config index 7fb53719..251df9d0 100644 --- a/src/balutil/packages.config +++ b/src/balutil/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/src/bextutil/bextutil.vcxproj b/src/bextutil/bextutil.vcxproj index 50c6c7d2..d6fa3816 100644 --- a/src/bextutil/bextutil.vcxproj +++ b/src/bextutil/bextutil.vcxproj @@ -3,7 +3,7 @@ - + @@ -80,7 +80,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/bextutil/packages.config b/src/bextutil/packages.config index 7fb53719..251df9d0 100644 --- a/src/bextutil/packages.config +++ b/src/bextutil/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/src/mbanative/mbanative.vcxproj b/src/mbanative/mbanative.vcxproj index 5a998182..f86c7fef 100644 --- a/src/mbanative/mbanative.vcxproj +++ b/src/mbanative/mbanative.vcxproj @@ -3,7 +3,7 @@ - + @@ -70,7 +70,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/mbanative/packages.config b/src/mbanative/packages.config index 7fb53719..251df9d0 100644 --- a/src/mbanative/packages.config +++ b/src/mbanative/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file -- cgit v1.2.3-55-g6feb