aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs12
-rw-r--r--src/WixToolset.Core.Burn/Bind/ProvidesDependency.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bind/WixComponentSearchInfo.cs3
-rw-r--r--src/WixToolset.Core.Burn/Bind/WixFileSearchInfo.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bind/WixProductSearchInfo.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bind/WixRegistrySearchInfo.cs3
-rw-r--r--src/WixToolset.Core.Burn/Bind/WixSearchInfo.cs2
-rw-r--r--src/WixToolset.Core.Burn/BundleBackend.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/CreateContainerCommand.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/PackageFacade.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/ProcessExePackageCommand.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/ProcessMsuPackageCommand.cs4
-rw-r--r--src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/VerifyPayloadsWithCatalogCommand.cs2
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs10
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs11
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/CreateDeltaPatchesCommand.cs3
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs31
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/GenerateDatabaseCommand.cs2
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs7
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs22
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs41
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Decompiler.cs (renamed from src/WixToolset.Core/Decompiler.cs)5
-rw-r--r--src/WixToolset.Core.WindowsInstaller/DecompilerCore.cs (renamed from src/WixToolset.Core/DecompilerCore.cs)2
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs4
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Melter.cs (renamed from src/WixToolset.Core/Melter.cs)2
-rw-r--r--src/WixToolset.Core.WindowsInstaller/MelterCore.cs (renamed from src/WixToolset.Core/MelterCore.cs)0
-rw-r--r--src/WixToolset.Core.WindowsInstaller/MsiBackend.cs2
-rw-r--r--src/WixToolset.Core.WindowsInstaller/MsmBackend.cs2
-rw-r--r--src/WixToolset.Core.WindowsInstaller/MspBackend.cs7
-rw-r--r--src/WixToolset.Core.WindowsInstaller/MstBackend.cs5
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Patch.cs3
-rw-r--r--src/WixToolset.Core.WindowsInstaller/PatchTransform.cs (renamed from src/WixToolset.Core/PatchTransform.cs)9
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs4
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Unbind/UnbindMsiOrMsmCommand.cs5
-rw-r--r--src/WixToolset.Core.WindowsInstaller/UnbindContext.cs (renamed from src/WixToolset.Core/UnbindContext.cs)0
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Unbinder.cs (renamed from src/WixToolset.Core/Unbinder.cs)46
-rw-r--r--src/WixToolset.Core.WindowsInstaller/WixToolset.Core.WindowsInstaller.csproj2
-rw-r--r--src/WixToolset.Core/Bind/DelayedField.cs6
-rw-r--r--src/WixToolset.Core/Bind/FileFacade.cs17
-rw-r--r--src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs15
-rw-r--r--src/WixToolset.Core/Bind/ResolveFieldsCommand.cs67
-rw-r--r--src/WixToolset.Core/BindContext.cs2
-rw-r--r--src/WixToolset.Core/Binder.cs54
-rw-r--r--src/WixToolset.Core/BinderCore.cs14
-rw-r--r--src/WixToolset.Core/BinderFileManagerCore.cs4
-rw-r--r--src/WixToolset.Core/CommandLine/BuildCommand.cs92
-rw-r--r--src/WixToolset.Core/CommandLine/CommandLine.cs2
-rw-r--r--src/WixToolset.Core/CommandLine/CompileCommand.cs27
-rw-r--r--src/WixToolset.Core/CompileContext.cs32
-rw-r--r--src/WixToolset.Core/Compiler.cs7157
-rw-r--r--src/WixToolset.Core/CompilerCore.cs134
-rw-r--r--src/WixToolset.Core/Inscriber.cs8
-rw-r--r--src/WixToolset.Core/Librarian.cs70
-rw-r--r--src/WixToolset.Core/LibraryContext.cs9
-rw-r--r--src/WixToolset.Core/Link/ConnectToFeature.cs50
-rw-r--r--src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs81
-rw-r--r--src/WixToolset.Core/Link/IntermediateTupleExtensions.cs26
-rw-r--r--src/WixToolset.Core/Link/ReportConflictingSymbolsCommand.cs20
-rw-r--r--src/WixToolset.Core/Link/ResolveReferencesCommand.cs99
-rw-r--r--src/WixToolset.Core/Link/WixComplexReferenceTupleExtensions.cs73
-rw-r--r--src/WixToolset.Core/Link/WixGroupingOrdering.cs140
-rw-r--r--src/WixToolset.Core/LinkContext.cs28
-rw-r--r--src/WixToolset.Core/Linker.cs1164
-rw-r--r--src/WixToolset.Core/Localizer.cs35
-rw-r--r--src/WixToolset.Core/Preprocessor.cs24
-rw-r--r--src/WixToolset.Core/TupleDefinitionCreator.cs52
-rw-r--r--src/WixToolset.Core/WindowsInstallerStandard.cs260
-rw-r--r--src/WixToolset.Core/WixToolsetServiceProvider.cs19
-rw-r--r--src/WixToolset.Core/WixVariableResolver.cs8
-rw-r--r--src/WixToolset.Data.WindowsInstaller/ColumnDefinition.cs1032
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Common.cs25
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Data/actions.xml76
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Data/tables.xml1962
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Field.cs266
-rw-r--r--src/WixToolset.Data.WindowsInstaller/ObjectField.cs183
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Output.cs342
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Pdb.cs163
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Row.cs620
-rw-r--r--src/WixToolset.Data.WindowsInstaller/RowDictionary.cs84
-rw-r--r--src/WixToolset.Data.WindowsInstaller/RowIndexedList.cs301
-rw-r--r--src/WixToolset.Data.WindowsInstaller/RowOperation.cs30
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/BBControlRow.cs113
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/ComponentRow.cs245
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/ContainerType.cs13
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/ControlRow.cs143
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/FileRow.cs640
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/MediaRow.cs80
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/PropertyRow.cs42
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/SummaryInfoRowCollection.cs42
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/SymbolPathType.cs17
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/UpgradeRow.cs90
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixActionRow.cs374
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixActionRowCollection.cs222
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixApprovedExeForElevationRow.cs79
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleCatalogRow.cs50
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleContainerRow.cs78
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleExePackageRow.cs103
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiFeatureRow.cs93
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiPackageRow.cs138
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiPropertyRow.cs58
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMspPackageRow.cs101
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsuPackageRow.cs57
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageCommandLineRow.cs82
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageExitCodeRow.cs53
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageRow.cs228
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePatchTargetCodeRow.cs81
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePayloadRow.cs185
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRelatedPackageRow.cs87
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRollbackBoundaryRow.cs59
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRow.cs228
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleSlipstreamMspRow.cs48
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleUpdateRow.cs38
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixBundleVariableRow.cs80
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixChainItemRow.cs39
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixChainRow.cs65
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixComplexReferenceRow.cs204
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixDeltaPatchFileRow.cs142
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixDeltaPatchSymbolPathsRow.cs58
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixFileRow.cs163
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixGroupRow.cs62
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixMediaRow.cs60
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixMediaTemplateRow.cs81
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixMergeRow.cs149
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixPayloadPropertiesRow.cs81
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixPropertyRow.cs118
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixRelatedBundleRow.cs52
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixSimpleReferenceRow.cs63
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixUpdateRegistrationRow.cs62
-rw-r--r--src/WixToolset.Data.WindowsInstaller/SubStorage.cs109
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Table.cs435
-rw-r--r--src/WixToolset.Data.WindowsInstaller/TableDefinition.cs334
-rw-r--r--src/WixToolset.Data.WindowsInstaller/TableDefinitionCollection.cs229
-rw-r--r--src/WixToolset.Data.WindowsInstaller/TableExtensions.cs23
-rw-r--r--src/WixToolset.Data.WindowsInstaller/TableIndexedCollection.cs153
-rw-r--r--src/WixToolset.Data.WindowsInstaller/TableOperation.cs25
-rw-r--r--src/WixToolset.Data.WindowsInstaller/WindowsInstallerStandard.cs442
-rw-r--r--src/WixToolset.Data.WindowsInstaller/WixInvalidIdtException.cs32
-rw-r--r--src/WixToolset.Data.WindowsInstaller/WixMissingTableDefinitionException.cs22
-rw-r--r--src/WixToolset.Data.WindowsInstaller/WixToolset.Data.WindowsInstaller.csproj27
-rw-r--r--src/test/WixToolsetTest.CoreIntegrationFixture/ProgramFixture.cs12
148 files changed, 17532 insertions, 4811 deletions
diff --git a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
index c9bd85b6..5e04e722 100644
--- a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+++ b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
@@ -69,7 +69,7 @@ namespace WixToolset.Core.Burn
69 { 69 {
70 public BindBundleCommand(IBindContext context) 70 public BindBundleCommand(IBindContext context)
71 { 71 {
72 this.TableDefinitions = WindowsInstallerStandard.GetTableDefinitions(); 72 //this.TableDefinitions = WindowsInstallerStandard.GetTableDefinitions();
73 73
74 this.DelayedFields = context.DelayedFields; 74 this.DelayedFields = context.DelayedFields;
75 this.ExpectedEmbeddedFiles = context.ExpectedEmbeddedFiles; 75 this.ExpectedEmbeddedFiles = context.ExpectedEmbeddedFiles;
@@ -87,13 +87,13 @@ namespace WixToolset.Core.Burn
87 87
88 public IEnumerable<IBinderExtension> Extensions { private get; set; } 88 public IEnumerable<IBinderExtension> Extensions { private get; set; }
89 89
90 public Output Output { private get; set; } 90 public Intermediate Output { private get; set; }
91 91
92 public string OutputPath { private get; set; } 92 public string OutputPath { private get; set; }
93 93
94 public string PdbFile { private get; set; } 94 public string PdbFile { private get; set; }
95 95
96 public TableDefinitionCollection TableDefinitions { private get; set; } 96 //public TableDefinitionCollection TableDefinitions { private get; set; }
97 97
98 public string IntermediateFolder { private get; set; } 98 public string IntermediateFolder { private get; set; }
99 99
@@ -105,6 +105,8 @@ namespace WixToolset.Core.Burn
105 105
106 public void Execute() 106 public void Execute()
107 { 107 {
108 throw new NotImplementedException();
109#if TODO
108 this.FileTransfers = Enumerable.Empty<FileTransfer>(); 110 this.FileTransfers = Enumerable.Empty<FileTransfer>();
109 this.ContentFilePaths = Enumerable.Empty<string>(); 111 this.ContentFilePaths = Enumerable.Empty<string>();
110 112
@@ -822,7 +824,7 @@ namespace WixToolset.Core.Burn
822 resources.Save(bundleTempPath); 824 resources.Save(bundleTempPath);
823 } 825 }
824 826
825 #region DependencyExtension 827//#region DependencyExtension
826 /// <summary> 828 /// <summary>
827 /// Imports authored dependency providers for each package in the manifest, 829 /// Imports authored dependency providers for each package in the manifest,
828 /// and generates dependency providers for certain package types that do not 830 /// and generates dependency providers for certain package types that do not
@@ -936,7 +938,7 @@ namespace WixToolset.Core.Burn
936 } 938 }
937 939
938 // Defaults to the bundle ID as the provider key. 940 // Defaults to the bundle ID as the provider key.
941#endif
939 } 942 }
940 #endregion
941 } 943 }
942} 944}
diff --git a/src/WixToolset.Core.Burn/Bind/ProvidesDependency.cs b/src/WixToolset.Core.Burn/Bind/ProvidesDependency.cs
index e64773b4..c7eba01c 100644
--- a/src/WixToolset.Core.Burn/Bind/ProvidesDependency.cs
+++ b/src/WixToolset.Core.Burn/Bind/ProvidesDependency.cs
@@ -11,6 +11,7 @@ namespace WixToolset.Core.Burn
11 /// </summary> 11 /// </summary>
12 internal sealed class ProvidesDependency 12 internal sealed class ProvidesDependency
13 { 13 {
14#if TODO
14 /// <summary> 15 /// <summary>
15 /// Creates a new instance of the <see cref="ProviderDependency"/> class from a <see cref="Row"/>. 16 /// Creates a new instance of the <see cref="ProviderDependency"/> class from a <see cref="Row"/>.
16 /// </summary> 17 /// </summary>
@@ -19,6 +20,7 @@ namespace WixToolset.Core.Burn
19 : this((string)row[2], (string)row[3], (string)row[4], (int?)row[5]) 20 : this((string)row[2], (string)row[3], (string)row[4], (int?)row[5])
20 { 21 {
21 } 22 }
23#endif
22 24
23 /// <summary> 25 /// <summary>
24 /// Creates a new instance of the <see cref="ProviderDependency"/> class. 26 /// Creates a new instance of the <see cref="ProviderDependency"/> class.
diff --git a/src/WixToolset.Core.Burn/Bind/WixComponentSearchInfo.cs b/src/WixToolset.Core.Burn/Bind/WixComponentSearchInfo.cs
index f605d7c7..b9c29df0 100644
--- a/src/WixToolset.Core.Burn/Bind/WixComponentSearchInfo.cs
+++ b/src/WixToolset.Core.Burn/Bind/WixComponentSearchInfo.cs
@@ -11,10 +11,12 @@ namespace WixToolset.Core.Burn
11 /// </summary> 11 /// </summary>
12 internal class WixComponentSearchInfo : WixSearchInfo 12 internal class WixComponentSearchInfo : WixSearchInfo
13 { 13 {
14#if TODO
14 public WixComponentSearchInfo(Row row) 15 public WixComponentSearchInfo(Row row)
15 : this((string)row[0], (string)row[1], (string)row[2], (int)row[3]) 16 : this((string)row[0], (string)row[1], (string)row[2], (int)row[3])
16 { 17 {
17 } 18 }
19#endif
18 20
19 public WixComponentSearchInfo(string id, string guid, string productCode, int attributes) 21 public WixComponentSearchInfo(string id, string guid, string productCode, int attributes)
20 : base(id) 22 : base(id)
@@ -60,5 +62,4 @@ namespace WixToolset.Core.Burn
60 writer.WriteEndElement(); 62 writer.WriteEndElement();
61 } 63 }
62 } 64 }
63
64} 65}
diff --git a/src/WixToolset.Core.Burn/Bind/WixFileSearchInfo.cs b/src/WixToolset.Core.Burn/Bind/WixFileSearchInfo.cs
index ea955db4..41393f6b 100644
--- a/src/WixToolset.Core.Burn/Bind/WixFileSearchInfo.cs
+++ b/src/WixToolset.Core.Burn/Bind/WixFileSearchInfo.cs
@@ -11,10 +11,12 @@ namespace WixToolset.Core.Burn
11 /// </summary> 11 /// </summary>
12 internal class WixFileSearchInfo : WixSearchInfo 12 internal class WixFileSearchInfo : WixSearchInfo
13 { 13 {
14#if TODO
14 public WixFileSearchInfo(Row row) 15 public WixFileSearchInfo(Row row)
15 : this((string)row[0], (string)row[1], (int)row[9]) 16 : this((string)row[0], (string)row[1], (int)row[9])
16 { 17 {
17 } 18 }
19#endif
18 20
19 public WixFileSearchInfo(string id, string path, int attributes) 21 public WixFileSearchInfo(string id, string path, int attributes)
20 : base(id) 22 : base(id)
diff --git a/src/WixToolset.Core.Burn/Bind/WixProductSearchInfo.cs b/src/WixToolset.Core.Burn/Bind/WixProductSearchInfo.cs
index b3bf5fee..cd4a70b3 100644
--- a/src/WixToolset.Core.Burn/Bind/WixProductSearchInfo.cs
+++ b/src/WixToolset.Core.Burn/Bind/WixProductSearchInfo.cs
@@ -11,10 +11,12 @@ namespace WixToolset.Core.Burn
11 /// </summary> 11 /// </summary>
12 internal class WixProductSearchInfo : WixSearchInfo 12 internal class WixProductSearchInfo : WixSearchInfo
13 { 13 {
14#if TODO
14 public WixProductSearchInfo(Row row) 15 public WixProductSearchInfo(Row row)
15 : this((string)row[0], (string)row[1], (int)row[2]) 16 : this((string)row[0], (string)row[1], (int)row[2])
16 { 17 {
17 } 18 }
19#endif
18 20
19 public WixProductSearchInfo(string id, string guid, int attributes) 21 public WixProductSearchInfo(string id, string guid, int attributes)
20 : base(id) 22 : base(id)
diff --git a/src/WixToolset.Core.Burn/Bind/WixRegistrySearchInfo.cs b/src/WixToolset.Core.Burn/Bind/WixRegistrySearchInfo.cs
index e25f25f4..e5227be5 100644
--- a/src/WixToolset.Core.Burn/Bind/WixRegistrySearchInfo.cs
+++ b/src/WixToolset.Core.Burn/Bind/WixRegistrySearchInfo.cs
@@ -11,10 +11,12 @@ namespace WixToolset.Core.Burn
11 /// </summary> 11 /// </summary>
12 internal class WixRegistrySearchInfo : WixSearchInfo 12 internal class WixRegistrySearchInfo : WixSearchInfo
13 { 13 {
14#if TODO
14 public WixRegistrySearchInfo(Row row) 15 public WixRegistrySearchInfo(Row row)
15 : this((string)row[0], (int)row[1], (string)row[2], (string)row[3], (int)row[4]) 16 : this((string)row[0], (int)row[1], (string)row[2], (string)row[3], (int)row[4])
16 { 17 {
17 } 18 }
19#endif
18 20
19 public WixRegistrySearchInfo(string id, int root, string key, string value, int attributes) 21 public WixRegistrySearchInfo(string id, int root, string key, string value, int attributes)
20 : base(id) 22 : base(id)
@@ -88,5 +90,4 @@ namespace WixToolset.Core.Burn
88 writer.WriteEndElement(); 90 writer.WriteEndElement();
89 } 91 }
90 } 92 }
91
92} 93}
diff --git a/src/WixToolset.Core.Burn/Bind/WixSearchInfo.cs b/src/WixToolset.Core.Burn/Bind/WixSearchInfo.cs
index 9ebca4ae..04347583 100644
--- a/src/WixToolset.Core.Burn/Bind/WixSearchInfo.cs
+++ b/src/WixToolset.Core.Burn/Bind/WixSearchInfo.cs
@@ -17,12 +17,14 @@ namespace WixToolset.Core.Burn
17 this.Id = id; 17 this.Id = id;
18 } 18 }
19 19
20#if TODO
20 public void AddWixSearchRowInfo(Row row) 21 public void AddWixSearchRowInfo(Row row)
21 { 22 {
22 Debug.Assert((string)row[0] == Id); 23 Debug.Assert((string)row[0] == Id);
23 Variable = (string)row[1]; 24 Variable = (string)row[1];
24 Condition = (string)row[2]; 25 Condition = (string)row[2];
25 } 26 }
27#endif
26 28
27 public string Id { get; private set; } 29 public string Id { get; private set; }
28 public string Variable { get; private set; } 30 public string Variable { get; private set; }
diff --git a/src/WixToolset.Core.Burn/BundleBackend.cs b/src/WixToolset.Core.Burn/BundleBackend.cs
index 0c7f2e8b..f66a3fbe 100644
--- a/src/WixToolset.Core.Burn/BundleBackend.cs
+++ b/src/WixToolset.Core.Burn/BundleBackend.cs
@@ -42,7 +42,7 @@ namespace WixToolset.Core.Burn
42 } 42 }
43 } 43 }
44 44
45 public Output Unbind(IUnbindContext context) 45 public Intermediate Unbind(IUnbindContext context)
46 { 46 {
47 string uxExtractPath = Path.Combine(context.ExportBasePath, "UX"); 47 string uxExtractPath = Path.Combine(context.ExportBasePath, "UX");
48 string acExtractPath = Path.Combine(context.ExportBasePath, "AttachedContainer"); 48 string acExtractPath = Path.Combine(context.ExportBasePath, "AttachedContainer");
diff --git a/src/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs b/src/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs
index bac8633b..d06cf4a8 100644
--- a/src/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs
@@ -11,6 +11,7 @@ namespace WixToolset.Core.Burn.Bundles
11 11
12 internal class AutomaticallySlipstreamPatchesCommand 12 internal class AutomaticallySlipstreamPatchesCommand
13 { 13 {
14#if TODO
14 public IEnumerable<PackageFacade> PackageFacades { private get; set; } 15 public IEnumerable<PackageFacade> PackageFacades { private get; set; }
15 16
16 public Table WixBundlePatchTargetCodeTable { private get; set; } 17 public Table WixBundlePatchTargetCodeTable { private get; set; }
@@ -108,5 +109,6 @@ namespace WixToolset.Core.Burn.Bundles
108 } 109 }
109 } 110 }
110 } 111 }
112#endif
111 } 113 }
112} 114}
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
index 58814efc..b1f1f0cd 100644
--- a/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
@@ -14,6 +14,7 @@ namespace WixToolset.Core.Burn.Bundles
14 14
15 internal class CreateBootstrapperApplicationManifestCommand 15 internal class CreateBootstrapperApplicationManifestCommand
16 { 16 {
17#if TODO
17 public WixBundleRow BundleRow { private get; set; } 18 public WixBundleRow BundleRow { private get; set; }
18 19
19 public IEnumerable<PackageFacade> ChainPackages { private get; set; } 20 public IEnumerable<PackageFacade> ChainPackages { private get; set; }
@@ -237,5 +238,6 @@ namespace WixToolset.Core.Burn.Bundles
237 238
238 return row; 239 return row;
239 } 240 }
241#endif
240 } 242 }
241} 243}
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
index 772265a0..788c7296 100644
--- a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
@@ -15,6 +15,7 @@ namespace WixToolset.Core.Burn.Bundles
15 15
16 internal class CreateBurnManifestCommand 16 internal class CreateBurnManifestCommand
17 { 17 {
18#if TODO
18 public IEnumerable<IBurnBackendExtension> BackendExtensions { private get; set; } 19 public IEnumerable<IBurnBackendExtension> BackendExtensions { private get; set; }
19 20
20 public Output Output { private get; set; } 21 public Output Output { private get; set; }
@@ -682,5 +683,6 @@ namespace WixToolset.Core.Burn.Bundles
682 683
683 return resolved; 684 return resolved;
684 } 685 }
686#endif
685 } 687 }
686} 688}
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateContainerCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateContainerCommand.cs
index 75379713..cde6d8f3 100644
--- a/src/WixToolset.Core.Burn/Bundles/CreateContainerCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/CreateContainerCommand.cs
@@ -16,6 +16,7 @@ namespace WixToolset.Core.Burn.Bundles
16 /// </summary> 16 /// </summary>
17 internal class CreateContainerCommand 17 internal class CreateContainerCommand
18 { 18 {
19#if TODO
19 public CompressionLevel DefaultCompressionLevel { private get; set; } 20 public CompressionLevel DefaultCompressionLevel { private get; set; }
20 21
21 public IEnumerable<WixBundlePayloadRow> Payloads { private get; set; } 22 public IEnumerable<WixBundlePayloadRow> Payloads { private get; set; }
@@ -64,5 +65,6 @@ namespace WixToolset.Core.Burn.Bundles
64 65
65 this.Size = fileInfo.Length; 66 this.Size = fileInfo.Length;
66 } 67 }
68#endif
67 } 69 }
68} 70}
diff --git a/src/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs b/src/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs
index 7485758c..056f6eb7 100644
--- a/src/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs
@@ -8,6 +8,7 @@ namespace WixToolset.Core.Burn.Bundles
8 8
9 internal class GetPackageFacadesCommand 9 internal class GetPackageFacadesCommand
10 { 10 {
11#if TODO
11 public Table PackageTable { private get; set; } 12 public Table PackageTable { private get; set; }
12 13
13 public Table ExePackageTable { private get; set; } 14 public Table ExePackageTable { private get; set; }
@@ -58,5 +59,6 @@ namespace WixToolset.Core.Burn.Bundles
58 59
59 this.PackageFacades = facades; 60 this.PackageFacades = facades;
60 } 61 }
62#endif
61 } 63 }
62} 64}
diff --git a/src/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs b/src/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs
index cb6e2748..4266ca40 100644
--- a/src/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs
@@ -9,6 +9,7 @@ namespace WixToolset.Core.Burn.Bundles
9 9
10 internal class OrderPackagesAndRollbackBoundariesCommand 10 internal class OrderPackagesAndRollbackBoundariesCommand
11 { 11 {
12#if TODO
12 public Table WixGroupTable { private get; set; } 13 public Table WixGroupTable { private get; set; }
13 14
14 public RowDictionary<WixBundleRollbackBoundaryRow> Boundaries { private get; set; } 15 public RowDictionary<WixBundleRollbackBoundaryRow> Boundaries { private get; set; }
@@ -141,5 +142,6 @@ namespace WixToolset.Core.Burn.Bundles
141 this.OrderedPackageFacades = orderedFacades; 142 this.OrderedPackageFacades = orderedFacades;
142 this.UsedRollbackBoundaries = usedBoundaries; 143 this.UsedRollbackBoundaries = usedBoundaries;
143 } 144 }
145#endif
144 } 146 }
145} 147}
diff --git a/src/WixToolset.Core.Burn/Bundles/PackageFacade.cs b/src/WixToolset.Core.Burn/Bundles/PackageFacade.cs
index 3f2e184d..ff5c2e2e 100644
--- a/src/WixToolset.Core.Burn/Bundles/PackageFacade.cs
+++ b/src/WixToolset.Core.Burn/Bundles/PackageFacade.cs
@@ -6,6 +6,7 @@ namespace WixToolset.Core.Burn.Bundles
6 6
7 internal class PackageFacade 7 internal class PackageFacade
8 { 8 {
9#if TODO
9 private PackageFacade(WixBundlePackageRow package) 10 private PackageFacade(WixBundlePackageRow package)
10 { 11 {
11 this.Package = package; 12 this.Package = package;
@@ -54,5 +55,6 @@ namespace WixToolset.Core.Burn.Bundles
54 /// the relationship with the extension makes it much trickier to pull off. 55 /// the relationship with the extension makes it much trickier to pull off.
55 /// </remarks> 56 /// </remarks>
56 public ProvidesDependencyCollection Provides { get; private set; } 57 public ProvidesDependencyCollection Provides { get; private set; }
58#endif
57 } 59 }
58} 60}
diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessExePackageCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessExePackageCommand.cs
index 11512c39..75bb5bb1 100644
--- a/src/WixToolset.Core.Burn/Bundles/ProcessExePackageCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/ProcessExePackageCommand.cs
@@ -11,6 +11,7 @@ namespace WixToolset.Core.Burn.Bundles
11 /// </summary> 11 /// </summary>
12 internal class ProcessExePackageCommand 12 internal class ProcessExePackageCommand
13 { 13 {
14#if TODO
14 public RowDictionary<WixBundlePayloadRow> AuthoredPayloads { private get; set; } 15 public RowDictionary<WixBundlePayloadRow> AuthoredPayloads { private get; set; }
15 16
16 public PackageFacade Facade { private get; set; } 17 public PackageFacade Facade { private get; set; }
@@ -29,5 +30,6 @@ namespace WixToolset.Core.Burn.Bundles
29 30
30 this.Facade.Package.Version = packagePayload.Version; 31 this.Facade.Package.Version = packagePayload.Version;
31 } 32 }
33#endif
32 } 34 }
33} 35}
diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
index 322187f9..2ee58514 100644
--- a/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
@@ -22,6 +22,7 @@ namespace WixToolset.Core.Burn.Bundles
22 /// </summary> 22 /// </summary>
23 internal class ProcessMsiPackageCommand 23 internal class ProcessMsiPackageCommand
24 { 24 {
25#if TODO
25 private const string PropertySqlFormat = "SELECT `Value` FROM `Property` WHERE `Property` = '{0}'"; 26 private const string PropertySqlFormat = "SELECT `Value` FROM `Property` WHERE `Property` = '{0}'";
26 27
27 public RowDictionary<WixBundlePayloadRow> AuthoredPayloads { private get; set; } 28 public RowDictionary<WixBundlePayloadRow> AuthoredPayloads { private get; set; }
@@ -572,5 +573,6 @@ namespace WixToolset.Core.Burn.Bundles
572 573
573 return String.Format(CultureInfo.InvariantCulture, ProcessMsiPackageCommand.PropertySqlFormat, property); 574 return String.Format(CultureInfo.InvariantCulture, ProcessMsiPackageCommand.PropertySqlFormat, property);
574 } 575 }
576#endif
575 } 577 }
576} 578}
diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs
index 2d849d03..37e08634 100644
--- a/src/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs
@@ -18,6 +18,7 @@ namespace WixToolset.Core.Burn.Bundles
18 /// </summary> 18 /// </summary>
19 internal class ProcessMspPackageCommand 19 internal class ProcessMspPackageCommand
20 { 20 {
21#if TODO
21 private const string PatchMetadataFormat = "SELECT `Value` FROM `MsiPatchMetadata` WHERE `Property` = '{0}'"; 22 private const string PatchMetadataFormat = "SELECT `Value` FROM `MsiPatchMetadata` WHERE `Property` = '{0}'";
22 private static readonly Encoding XmlOutputEncoding = new UTF8Encoding(false); 23 private static readonly Encoding XmlOutputEncoding = new UTF8Encoding(false);
23 24
@@ -185,5 +186,6 @@ namespace WixToolset.Core.Burn.Bundles
185 186
186 return false; 187 return false;
187 } 188 }
189#endif
188 } 190 }
189} 191}
diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessMsuPackageCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessMsuPackageCommand.cs
index fcfc780c..1380385d 100644
--- a/src/WixToolset.Core.Burn/Bundles/ProcessMsuPackageCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/ProcessMsuPackageCommand.cs
@@ -11,7 +11,8 @@ namespace WixToolset.Core.Burn.Bundles
11 /// </summary> 11 /// </summary>
12 internal class ProcessMsuPackageCommand 12 internal class ProcessMsuPackageCommand
13 { 13 {
14 public RowDictionary<WixBundlePayloadRow> AuthoredPayloads { private get; set; } 14#if TODO
15 public RowDictionary<WixBundlePayload> AuthoredPayloads { private get; set; }
15 16
16 public PackageFacade Facade { private get; set; } 17 public PackageFacade Facade { private get; set; }
17 18
@@ -26,5 +27,6 @@ namespace WixToolset.Core.Burn.Bundles
26 27
27 this.Facade.Package.PerMachine = YesNoDefaultType.Yes; // MSUs are always per-machine. 28 this.Facade.Package.PerMachine = YesNoDefaultType.Yes; // MSUs are always per-machine.
28 } 29 }
30#endif
29 } 31 }
30} 32}
diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs
index 5dbd6aaa..7900fcd1 100644
--- a/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs
@@ -16,6 +16,7 @@ namespace WixToolset.Core.Burn.Bundles
16 16
17 internal class ProcessPayloadsCommand 17 internal class ProcessPayloadsCommand
18 { 18 {
19#if TODO
19 private static readonly Version EmptyVersion = new Version(0, 0, 0, 0); 20 private static readonly Version EmptyVersion = new Version(0, 0, 0, 0);
20 21
21 public IEnumerable<WixBundlePayloadRow> Payloads { private get; set; } 22 public IEnumerable<WixBundlePayloadRow> Payloads { private get; set; }
@@ -157,5 +158,6 @@ namespace WixToolset.Core.Burn.Bundles
157 payload.DisplayName = versionInfo.ProductName; 158 payload.DisplayName = versionInfo.ProductName;
158 } 159 }
159 } 160 }
161#endif
160 } 162 }
161} 163}
diff --git a/src/WixToolset.Core.Burn/Bundles/VerifyPayloadsWithCatalogCommand.cs b/src/WixToolset.Core.Burn/Bundles/VerifyPayloadsWithCatalogCommand.cs
index 9919f777..f22a8f2b 100644
--- a/src/WixToolset.Core.Burn/Bundles/VerifyPayloadsWithCatalogCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/VerifyPayloadsWithCatalogCommand.cs
@@ -13,6 +13,7 @@ namespace WixToolset.Core.Burn.Bundles
13 13
14 internal class VerifyPayloadsWithCatalogCommand 14 internal class VerifyPayloadsWithCatalogCommand
15 { 15 {
16#if TODO
16 public IEnumerable<WixBundleCatalogRow> Catalogs { private get; set; } 17 public IEnumerable<WixBundleCatalogRow> Catalogs { private get; set; }
17 18
18 public IEnumerable<WixBundlePayloadRow> Payloads { private get; set; } 19 public IEnumerable<WixBundlePayloadRow> Payloads { private get; set; }
@@ -144,5 +145,6 @@ namespace WixToolset.Core.Burn.Bundles
144 145
145 public string FullPath { get; set; } 146 public string FullPath { get; set; }
146 } 147 }
148#endif
147 } 149 }
148} 150}
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs
index 23c481b7..74e2cdb5 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs
@@ -66,7 +66,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
66 // When building merge module, all the files go to "#MergeModule.CABinet". 66 // When building merge module, all the files go to "#MergeModule.CABinet".
67 if (OutputType.Module == this.Output.Type) 67 if (OutputType.Module == this.Output.Type)
68 { 68 {
69 Table mergeModuleMediaTable = new Table(null, this.TableDefinitions["Media"]); 69 Table mergeModuleMediaTable = new Table(this.TableDefinitions["Media"]);
70 mergeModuleMediaRow = (MediaRow)mergeModuleMediaTable.CreateRow(null); 70 mergeModuleMediaRow = (MediaRow)mergeModuleMediaTable.CreateRow(null);
71 mergeModuleMediaRow.Cabinet = "#MergeModule.CABinet"; 71 mergeModuleMediaRow.Cabinet = "#MergeModule.CABinet";
72 72
@@ -150,8 +150,8 @@ namespace WixToolset.Core.WindowsInstaller.Databases
150 // When building a product, if the current file is not to be compressed or if 150 // When building a product, if the current file is not to be compressed or if
151 // the package set not to be compressed, don't cab it. 151 // the package set not to be compressed, don't cab it.
152 if (OutputType.Product == this.Output.Type && 152 if (OutputType.Product == this.Output.Type &&
153 (YesNoType.No == facade.File.Compressed || 153 (!facade.File.Compressed.Value ||
154 (YesNoType.NotSet == facade.File.Compressed && !this.FilesCompressed))) 154 (!facade.File.Compressed.HasValue && !this.FilesCompressed)))
155 { 155 {
156 uncompressedFiles.Add(facade); 156 uncompressedFiles.Add(facade);
157 continue; 157 continue;
@@ -270,8 +270,8 @@ namespace WixToolset.Core.WindowsInstaller.Databases
270 // When building a product, if the current file is not to be compressed or if 270 // When building a product, if the current file is not to be compressed or if
271 // the package set not to be compressed, don't cab it. 271 // the package set not to be compressed, don't cab it.
272 if (OutputType.Product == this.Output.Type && 272 if (OutputType.Product == this.Output.Type &&
273 (YesNoType.No == facade.File.Compressed || 273 (!facade.File.Compressed.Value ||
274 (YesNoType.NotSet == facade.File.Compressed && !this.FilesCompressed))) 274 (!facade.File.Compressed.HasValue && !this.FilesCompressed)))
275 { 275 {
276 uncompressedFiles.Add(facade); 276 uncompressedFiles.Add(facade);
277 } 277 }
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
index 21fbb022..5a61b63c 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
@@ -39,7 +39,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
39 this.DelayedFields = context.DelayedFields; 39 this.DelayedFields = context.DelayedFields;
40 this.ExpectedEmbeddedFiles = context.ExpectedEmbeddedFiles; 40 this.ExpectedEmbeddedFiles = context.ExpectedEmbeddedFiles;
41 this.Extensions = context.Extensions; 41 this.Extensions = context.Extensions;
42 this.Output = context.IntermediateRepresentation; 42 this.Intermediate = context.IntermediateRepresentation;
43 this.OutputPath = context.OutputPath; 43 this.OutputPath = context.OutputPath;
44 this.PdbFile = context.OutputPdbPath; 44 this.PdbFile = context.OutputPdbPath;
45 this.IntermediateFolder = context.IntermediateFolder; 45 this.IntermediateFolder = context.IntermediateFolder;
@@ -69,10 +69,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
69 69
70 private IEnumerable<IBinderExtension> Extensions { get; } 70 private IEnumerable<IBinderExtension> Extensions { get; }
71 71
72 private IEnumerable<InspectorExtension> InspectorExtensions { get; }
73
74 private string PdbFile { get; } 72 private string PdbFile { get; }
75 73
74 private Intermediate Intermediate { get; }
75
76 private Output Output { get; } 76 private Output Output { get; }
77 77
78 private string OutputPath { get; } 78 private string OutputPath { get; }
@@ -95,6 +95,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
95 95
96 public void Execute() 96 public void Execute()
97 { 97 {
98 this.Intermediate.Save(this.OutputPath);
99#if FINISH
98 List<FileTransfer> fileTransfers = new List<FileTransfer>(); 100 List<FileTransfer> fileTransfers = new List<FileTransfer>();
99 101
100 HashSet<string> suppressedTableNames = new HashSet<string>(); 102 HashSet<string> suppressedTableNames = new HashSet<string>();
@@ -108,6 +110,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
108 110
109 this.LocalizeUI(this.Output.Tables); 111 this.LocalizeUI(this.Output.Tables);
110 112
113 this.Output = CreateOutputFromIR(this.Intermediate);
114
111 // Process the summary information table before the other tables. 115 // Process the summary information table before the other tables.
112 bool compressed; 116 bool compressed;
113 bool longNames; 117 bool longNames;
@@ -1278,6 +1282,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
1278 command.TempFilesLocation = this.IntermediateFolder; 1282 command.TempFilesLocation = this.IntermediateFolder;
1279 command.Codepage = this.Codepage; 1283 command.Codepage = this.Codepage;
1280 command.Execute(); 1284 command.Execute();
1285#endif
1281 } 1286 }
1282 } 1287 }
1283} 1288}
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateDeltaPatchesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateDeltaPatchesCommand.cs
index 767671b8..42a69310 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateDeltaPatchesCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateDeltaPatchesCommand.cs
@@ -23,6 +23,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
23 23
24 public void Execute() 24 public void Execute()
25 { 25 {
26#if REVISIT_FOR_PATCHING
26 bool optimizePatchSizeForLargeFiles = false; 27 bool optimizePatchSizeForLargeFiles = false;
27 PatchSymbolFlagsType apiPatchingSymbolFlags = 0; 28 PatchSymbolFlagsType apiPatchingSymbolFlags = 0;
28 29
@@ -82,6 +83,8 @@ namespace WixToolset.Core.WindowsInstaller.Databases
82 } 83 }
83 } 84 }
84 } 85 }
86#endif
87 throw new NotImplementedException();
85 } 88 }
86 } 89 }
87} 90}
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs
index ae76037d..0d3e7bd1 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs
@@ -16,6 +16,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
16 using WixToolset.Core.Native; 16 using WixToolset.Core.Native;
17 using WixToolset.Core.Bind; 17 using WixToolset.Core.Bind;
18 using WixToolset.Core.Cab; 18 using WixToolset.Core.Cab;
19 using WixToolset.Data.Tuples;
19 20
20 /// <summary> 21 /// <summary>
21 /// Retrieve files information and extract them from merge modules. 22 /// Retrieve files information and extract them from merge modules.
@@ -34,7 +35,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
34 35
35 public bool SuppressLayout { private get; set; } 36 public bool SuppressLayout { private get; set; }
36 37
37 public string TempFilesLocation { private get; set; } 38 public string IntermediateFolder { private get; set; }
38 39
39 public IEnumerable<FileFacade> MergeModulesFileFacades { get; private set; } 40 public IEnumerable<FileFacade> MergeModulesFileFacades { get; private set; }
40 41
@@ -95,22 +96,28 @@ namespace WixToolset.Core.WindowsInstaller.Databases
95 // NOTE: this is very tricky - the merge module file rows are not added to the 96 // NOTE: this is very tricky - the merge module file rows are not added to the
96 // file table because they should not be created via idt import. Instead, these 97 // file table because they should not be created via idt import. Instead, these
97 // rows are created by merging in the actual modules. 98 // rows are created by merging in the actual modules.
98 FileRow fileRow = (FileRow)this.FileTable.CreateRow(wixMergeRow.SourceLineNumbers, false); 99 var fileRow = new FileTuple(wixMergeRow.SourceLineNumbers, new Identifier(record[1], AccessModifier.Private));
99 fileRow.File = record[1]; 100 fileRow.File = record[1];
100 fileRow.Compressed = wixMergeRow.FileCompression; 101 fileRow.Compressed = (wixMergeRow.FileCompression == YesNoType.Yes) ? true : (wixMergeRow.FileCompression == YesNoType.No) ? (bool?)false : null;
102 //FileRow fileRow = (FileRow)this.FileTable.CreateRow(wixMergeRow.SourceLineNumbers, false);
103 //fileRow.File = record[1];
104 //fileRow.Compressed = wixMergeRow.FileCompression;
101 105
102 WixFileRow wixFileRow = (WixFileRow)this.WixFileTable.CreateRow(wixMergeRow.SourceLineNumbers, false); 106 var wixFileRow = new WixFileTuple(wixMergeRow.SourceLineNumbers);
103 wixFileRow.Directory = record[2]; 107 wixFileRow.Directory_ = record[2];
104 wixFileRow.DiskId = wixMergeRow.DiskId; 108 wixFileRow.DiskId = wixMergeRow.DiskId;
105 wixFileRow.PatchGroup = -1; 109 wixFileRow.PatchGroup = -1;
106 wixFileRow.Source = String.Concat(this.TempFilesLocation, Path.DirectorySeparatorChar, "MergeId.", wixMergeRow.Number.ToString(CultureInfo.InvariantCulture), Path.DirectorySeparatorChar, record[1]); 110 wixFileRow.Source = Path.Combine(this.IntermediateFolder, "MergeId.", wixMergeRow.Number.ToString(CultureInfo.InvariantCulture), record[1]);
111 //WixFileRow wixFileRow = (WixFileRow)this.WixFileTable.CreateRow(wixMergeRow.SourceLineNumbers, false);
112 //wixFileRow.Directory = record[2];
113 //wixFileRow.DiskId = wixMergeRow.DiskId;
114 //wixFileRow.PatchGroup = -1;
115 //wixFileRow.Source = Path.Combine(this.IntermediateFolder, "MergeId.", wixMergeRow.Number.ToString(CultureInfo.InvariantCulture), record[1]);
107 116
108 FileFacade mergeModuleFileFacade = new FileFacade(true, fileRow, wixFileRow); 117 var mergeModuleFileFacade = new FileFacade(true, fileRow, wixFileRow);
109
110 FileFacade collidingFacade;
111 118
112 // If case-sensitive collision with another merge module or a user-authored file identifier. 119 // If case-sensitive collision with another merge module or a user-authored file identifier.
113 if (indexedFileFacades.TryGetValue(mergeModuleFileFacade.File.File, out collidingFacade)) 120 if (indexedFileFacades.TryGetValue(mergeModuleFileFacade.File.File, out var collidingFacade))
114 { 121 {
115 Messaging.Instance.OnMessage(WixErrors.DuplicateModuleFileIdentifier(wixMergeRow.SourceLineNumbers, wixMergeRow.Id, collidingFacade.File.File)); 122 Messaging.Instance.OnMessage(WixErrors.DuplicateModuleFileIdentifier(wixMergeRow.SourceLineNumbers, wixMergeRow.Id, collidingFacade.File.File));
116 } 123 }
@@ -188,10 +195,10 @@ namespace WixToolset.Core.WindowsInstaller.Databases
188 string safeMergeId = wixMergeRow.Number.ToString(CultureInfo.InvariantCulture.NumberFormat); 195 string safeMergeId = wixMergeRow.Number.ToString(CultureInfo.InvariantCulture.NumberFormat);
189 196
190 // extract the module cabinet, then explode all of the files to a temp directory 197 // extract the module cabinet, then explode all of the files to a temp directory
191 string moduleCabPath = String.Concat(this.TempFilesLocation, Path.DirectorySeparatorChar, safeMergeId, ".module.cab"); 198 string moduleCabPath = String.Concat(this.IntermediateFolder, Path.DirectorySeparatorChar, safeMergeId, ".module.cab");
192 merge.ExtractCAB(moduleCabPath); 199 merge.ExtractCAB(moduleCabPath);
193 200
194 string mergeIdPath = String.Concat(this.TempFilesLocation, Path.DirectorySeparatorChar, "MergeId.", safeMergeId); 201 string mergeIdPath = String.Concat(this.IntermediateFolder, Path.DirectorySeparatorChar, "MergeId.", safeMergeId);
195 Directory.CreateDirectory(mergeIdPath); 202 Directory.CreateDirectory(mergeIdPath);
196 203
197 using (var extractCab = new WixExtractCab()) 204 using (var extractCab = new WixExtractCab())
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/GenerateDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/GenerateDatabaseCommand.cs
index 26d254f2..47b58058 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/GenerateDatabaseCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/GenerateDatabaseCommand.cs
@@ -122,7 +122,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
122 { 122 {
123 if (ColumnType.Object == columnDefinition.Type) 123 if (ColumnType.Object == columnDefinition.Type)
124 { 124 {
125 importTable = new Table(table.Section, table.Definition); 125 importTable = new Table(table.Definition);
126 hasBinaryColumn = true; 126 hasBinaryColumn = true;
127 break; 127 break;
128 } 128 }
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs
index caf8b7a7..9bbb4763 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs
@@ -24,6 +24,8 @@ namespace WixToolset.Core.WindowsInstaller.Databases
24 24
25 public void Execute() 25 public void Execute()
26 { 26 {
27 throw new NotImplementedException();
28#if TODO
27 List<FileFacade> facades = new List<FileFacade>(this.FileTable.Rows.Count); 29 List<FileFacade> facades = new List<FileFacade>(this.FileTable.Rows.Count);
28 30
29 RowDictionary<WixFileRow> wixFiles = new RowDictionary<WixFileRow>(this.WixFileTable); 31 RowDictionary<WixFileRow> wixFiles = new RowDictionary<WixFileRow>(this.WixFileTable);
@@ -44,6 +46,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
44 } 46 }
45 47
46 this.FileFacades = facades; 48 this.FileFacades = facades;
49#endif
47 } 50 }
48 51
49 /// <summary> 52 /// <summary>
@@ -66,7 +69,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
66 case SymbolPathType.Component: 69 case SymbolPathType.Component:
67 if (null == filesByComponent) 70 if (null == filesByComponent)
68 { 71 {
69 filesByComponent = facades.ToLookup(f => f.File.Component); 72 filesByComponent = facades.ToLookup(f => f.File.Component_);
70 } 73 }
71 74
72 foreach (FileFacade facade in filesByComponent[row.Id]) 75 foreach (FileFacade facade in filesByComponent[row.Id])
@@ -78,7 +81,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
78 case SymbolPathType.Directory: 81 case SymbolPathType.Directory:
79 if (null == filesByDirectory) 82 if (null == filesByDirectory)
80 { 83 {
81 filesByDirectory = facades.ToLookup(f => f.WixFile.Directory); 84 filesByDirectory = facades.ToLookup(f => f.WixFile.Directory_);
82 } 85 }
83 86
84 foreach (FileFacade facade in filesByDirectory[row.Id]) 87 foreach (FileFacade facade in filesByDirectory[row.Id])
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
index 624cbb43..f1605eca 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
@@ -304,7 +304,8 @@ namespace WixToolset.Core.WindowsInstaller.Databases
304 throw new InvalidOperationException("Failed to fetch a File row from the database that was merged in from a module."); 304 throw new InvalidOperationException("Failed to fetch a File row from the database that was merged in from a module.");
305 } 305 }
306 306
307 recordUpdate.SetInteger(1, file.File.Sequence); 307 //recordUpdate.SetInteger(1, file.File.Sequence);
308 throw new NotImplementedException();
308 309
309 // update the file attributes to match the compression specified 310 // update the file attributes to match the compression specified
310 // on the Merge element or on the Package element 311 // on the Merge element or on the Package element
@@ -316,26 +317,25 @@ namespace WixToolset.Core.WindowsInstaller.Databases
316 attributes = recordUpdate.GetInteger(2); 317 attributes = recordUpdate.GetInteger(2);
317 } 318 }
318 319
319 if (YesNoType.Yes == file.File.Compressed) 320 // not specified
321 if (!file.File.Compressed.HasValue)
322 {
323 // clear any compression bits
324 attributes &= ~MsiInterop.MsidbFileAttributesCompressed;
325 attributes &= ~MsiInterop.MsidbFileAttributesNoncompressed;
326 }
327 else if (file.File.Compressed.Value)
320 { 328 {
321 // these are mutually exclusive 329 // these are mutually exclusive
322 attributes |= MsiInterop.MsidbFileAttributesCompressed; 330 attributes |= MsiInterop.MsidbFileAttributesCompressed;
323 attributes &= ~MsiInterop.MsidbFileAttributesNoncompressed; 331 attributes &= ~MsiInterop.MsidbFileAttributesNoncompressed;
324 } 332 }
325 else if (YesNoType.No == file.File.Compressed) 333 else if (!file.File.Compressed.Value)
326 { 334 {
327 // these are mutually exclusive 335 // these are mutually exclusive
328 attributes |= MsiInterop.MsidbFileAttributesNoncompressed; 336 attributes |= MsiInterop.MsidbFileAttributesNoncompressed;
329 attributes &= ~MsiInterop.MsidbFileAttributesCompressed; 337 attributes &= ~MsiInterop.MsidbFileAttributesCompressed;
330 } 338 }
331 else // not specified
332 {
333 Debug.Assert(YesNoType.NotSet == file.File.Compressed);
334
335 // clear any compression bits
336 attributes &= ~MsiInterop.MsidbFileAttributesCompressed;
337 attributes &= ~MsiInterop.MsidbFileAttributesNoncompressed;
338 }
339 339
340 recordUpdate.SetInteger(2, attributes); 340 recordUpdate.SetInteger(2, attributes);
341 341
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
index cd9444ee..20058597 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
@@ -15,6 +15,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
15 using WixToolset.Core.Bind; 15 using WixToolset.Core.Bind;
16 using WixToolset.Data; 16 using WixToolset.Data;
17 using WixToolset.Data.Rows; 17 using WixToolset.Data.Rows;
18 using WixToolset.Data.Tuples;
18 using WixToolset.Msi; 19 using WixToolset.Msi;
19 20
20 /// <summary> 21 /// <summary>
@@ -69,7 +70,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
69 70
70 if (!fileInfo.Exists) 71 if (!fileInfo.Exists)
71 { 72 {
72 Messaging.Instance.OnMessage(WixErrors.CannotFindFile(file.File.SourceLineNumbers, file.File.File, file.File.FileName, file.WixFile.Source)); 73 Messaging.Instance.OnMessage(WixErrors.CannotFindFile(file.File.SourceLineNumbers, file.File.File, file.File.LongFileName, file.WixFile.Source));
73 return; 74 return;
74 } 75 }
75 76
@@ -148,16 +149,17 @@ namespace WixToolset.Core.WindowsInstaller.Databases
148 149
149 if (null == file.Hash) 150 if (null == file.Hash)
150 { 151 {
151 Table msiFileHashTable = this.Output.EnsureTable(this.TableDefinitions["MsiFileHash"]); 152 //Table msiFileHashTable = this.Output.EnsureTable(this.TableDefinitions["MsiFileHash"]);
152 file.Hash = msiFileHashTable.CreateRow(file.File.SourceLineNumbers); 153 //file.Hash = msiFileHashTable.CreateRow(file.File.SourceLineNumbers);
154 throw new NotImplementedException();
153 } 155 }
154 156
155 file.Hash[0] = file.File.File; 157 file.Hash.File_ = file.File.File;
156 file.Hash[1] = 0; 158 file.Hash.Options = 0;
157 file.Hash[2] = hash[0]; 159 file.Hash.HashPart1 = hash[0];
158 file.Hash[3] = hash[1]; 160 file.Hash.HashPart2 = hash[1];
159 file.Hash[4] = hash[2]; 161 file.Hash.HashPart3 = hash[2];
160 file.Hash[5] = hash[3]; 162 file.Hash.HashPart4 = hash[3];
161 } 163 }
162 } 164 }
163 else // update the file row with the version and language information. 165 else // update the file row with the version and language information.
@@ -250,9 +252,9 @@ namespace WixToolset.Core.WindowsInstaller.Databases
250 assemblyNameValues.Add("publicKeyToken", publicKeyIsNeutral ? "null" : publicKeyToken.ToUpperInvariant()); 252 assemblyNameValues.Add("publicKeyToken", publicKeyIsNeutral ? "null" : publicKeyToken.ToUpperInvariant());
251 assemblyNameValues.Add("publicKeyTokenPreservedCase", publicKeyIsNeutral ? "null" : publicKeyToken); 253 assemblyNameValues.Add("publicKeyTokenPreservedCase", publicKeyIsNeutral ? "null" : publicKeyToken);
252 } 254 }
253 else if (file.WixFile.AssemblyApplication == null) 255 else if (file.WixFile.File_AssemblyApplication == null)
254 { 256 {
255 throw new WixException(WixErrors.GacAssemblyNoStrongName(file.File.SourceLineNumbers, fileInfo.FullName, file.File.Component)); 257 throw new WixException(WixErrors.GacAssemblyNoStrongName(file.File.SourceLineNumbers, fileInfo.FullName, file.File.Component_));
256 } 258 }
257 259
258 string assemblyVersion = referenceIdentity.GetAttribute(null, "Version"); 260 string assemblyVersion = referenceIdentity.GetAttribute(null, "Version");
@@ -350,10 +352,10 @@ namespace WixToolset.Core.WindowsInstaller.Databases
350 // TODO: Consider passing in the this.FileFacades as an indexed collection instead of searching through 352 // TODO: Consider passing in the this.FileFacades as an indexed collection instead of searching through
351 // all files like this. Even though this is a rare case it looks like we might be able to index the 353 // all files like this. Even though this is a rare case it looks like we might be able to index the
352 // file earlier. 354 // file earlier.
353 FileFacade fileManifest = this.FileFacades.SingleOrDefault(r => r.File.File.Equals(file.WixFile.AssemblyManifest, StringComparison.Ordinal)); 355 FileFacade fileManifest = this.FileFacades.SingleOrDefault(r => r.File.File.Equals(file.WixFile.File_AssemblyManifest, StringComparison.Ordinal));
354 if (null == fileManifest) 356 if (null == fileManifest)
355 { 357 {
356 Messaging.Instance.OnMessage(WixErrors.MissingManifestForWin32Assembly(file.File.SourceLineNumbers, file.File.File, file.WixFile.AssemblyManifest)); 358 Messaging.Instance.OnMessage(WixErrors.MissingManifestForWin32Assembly(file.File.SourceLineNumbers, file.File.File, file.WixFile.File_AssemblyManifest));
357 } 359 }
358 360
359 string win32Type = null; 361 string win32Type = null;
@@ -476,7 +478,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
476 // check for null value (this can occur when grabbing the file version from an assembly without one) 478 // check for null value (this can occur when grabbing the file version from an assembly without one)
477 if (String.IsNullOrEmpty(value)) 479 if (String.IsNullOrEmpty(value))
478 { 480 {
479 Messaging.Instance.OnMessage(WixWarnings.NullMsiAssemblyNameValue(file.File.SourceLineNumbers, file.File.Component, name)); 481 Messaging.Instance.OnMessage(WixWarnings.NullMsiAssemblyNameValue(file.File.SourceLineNumbers, file.File.Component_, name));
480 } 482 }
481 else 483 else
482 { 484 {
@@ -485,7 +487,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
485 // override directly authored value 487 // override directly authored value
486 foreach (Row row in assemblyNameTable.Rows) 488 foreach (Row row in assemblyNameTable.Rows)
487 { 489 {
488 if ((string)row[0] == file.File.Component && (string)row[1] == name) 490 if ((string)row[0] == file.File.Component_ && (string)row[1] == name)
489 { 491 {
490 assemblyNameRow = row; 492 assemblyNameRow = row;
491 break; 493 break;
@@ -494,7 +496,7 @@ namespace WixToolset.Core.WindowsInstaller.Databases
494 496
495 // if the assembly will be GAC'd and the name in the file table doesn't match the name in the MsiAssemblyName table, error because the install will fail. 497 // if the assembly will be GAC'd and the name in the file table doesn't match the name in the MsiAssemblyName table, error because the install will fail.
496 if ("name" == name && FileAssemblyType.DotNetAssembly == file.WixFile.AssemblyType && 498 if ("name" == name && FileAssemblyType.DotNetAssembly == file.WixFile.AssemblyType &&
497 String.IsNullOrEmpty(file.WixFile.AssemblyApplication) && 499 String.IsNullOrEmpty(file.WixFile.File_AssemblyApplication) &&
498 !String.Equals(Path.GetFileNameWithoutExtension(file.File.LongFileName), value, StringComparison.OrdinalIgnoreCase)) 500 !String.Equals(Path.GetFileNameWithoutExtension(file.File.LongFileName), value, StringComparison.OrdinalIgnoreCase))
499 { 501 {
500 Messaging.Instance.OnMessage(WixErrors.GACAssemblyIdentityWarning(file.File.SourceLineNumbers, Path.GetFileNameWithoutExtension(file.File.LongFileName), value)); 502 Messaging.Instance.OnMessage(WixErrors.GACAssemblyIdentityWarning(file.File.SourceLineNumbers, Path.GetFileNameWithoutExtension(file.File.LongFileName), value));
@@ -502,8 +504,10 @@ namespace WixToolset.Core.WindowsInstaller.Databases
502 504
503 if (null == assemblyNameRow) 505 if (null == assemblyNameRow)
504 { 506 {
507 throw new NotImplementedException();
508#if TODO
505 assemblyNameRow = assemblyNameTable.CreateRow(file.File.SourceLineNumbers); 509 assemblyNameRow = assemblyNameTable.CreateRow(file.File.SourceLineNumbers);
506 assemblyNameRow[0] = file.File.Component; 510 assemblyNameRow[0] = file.File.Component_;
507 assemblyNameRow[1] = name; 511 assemblyNameRow[1] = name;
508 assemblyNameRow[2] = value; 512 assemblyNameRow[2] = value;
509 513
@@ -512,10 +516,11 @@ namespace WixToolset.Core.WindowsInstaller.Databases
512 516
513 if (null == file.AssemblyNames) 517 if (null == file.AssemblyNames)
514 { 518 {
515 file.AssemblyNames = new List<Row>(); 519 file.AssemblyNames = new List<MsiAssemblyNameTuple>();
516 } 520 }
517 521
518 file.AssemblyNames.Add(assemblyNameRow); 522 file.AssemblyNames.Add(assemblyNameRow);
523#endif
519 } 524 }
520 else 525 else
521 { 526 {
diff --git a/src/WixToolset.Core/Decompiler.cs b/src/WixToolset.Core.WindowsInstaller/Decompiler.cs
index e72b0104..d353cc16 100644
--- a/src/WixToolset.Core/Decompiler.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Decompiler.cs
@@ -24,7 +24,7 @@ namespace WixToolset
24 public class Decompiler 24 public class Decompiler
25 { 25 {
26 private static readonly Regex NullSplitter = new Regex(@"\[~]"); 26 private static readonly Regex NullSplitter = new Regex(@"\[~]");
27 27#if TODO
28 private int codepage; 28 private int codepage;
29 private bool compressed; 29 private bool compressed;
30 private bool shortNames; 30 private bool shortNames;
@@ -334,7 +334,7 @@ namespace WixToolset
334 334
335 return deleted; 335 return deleted;
336 } 336 }
337#endif 337#endif
338 return true; 338 return true;
339 } 339 }
340 340
@@ -9352,5 +9352,6 @@ namespace WixToolset
9352 return Wix.MajorUpgrade.ScheduleType.afterInstallFinalize; 9352 return Wix.MajorUpgrade.ScheduleType.afterInstallFinalize;
9353 } 9353 }
9354 } 9354 }
9355#endif
9355 } 9356 }
9356} 9357}
diff --git a/src/WixToolset.Core/DecompilerCore.cs b/src/WixToolset.Core.WindowsInstaller/DecompilerCore.cs
index 203f2bc4..2be986fc 100644
--- a/src/WixToolset.Core/DecompilerCore.cs
+++ b/src/WixToolset.Core.WindowsInstaller/DecompilerCore.cs
@@ -8,6 +8,7 @@ namespace WixToolset
8 using WixToolset.Extensibility; 8 using WixToolset.Extensibility;
9 using Wix = WixToolset.Data.Serialize; 9 using Wix = WixToolset.Data.Serialize;
10 10
11#if TODO
11 /// <summary> 12 /// <summary>
12 /// The base of the decompiler. Holds some variables used by the decompiler and extensions, 13 /// The base of the decompiler. Holds some variables used by the decompiler and extensions,
13 /// as well as some utility methods. 14 /// as well as some utility methods.
@@ -149,4 +150,5 @@ namespace WixToolset
149 Messaging.Instance.OnMessage(e); 150 Messaging.Instance.OnMessage(e);
150 } 151 }
151 } 152 }
153#endif
152} 154}
diff --git a/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs b/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs
index 40901d7c..72c876e0 100644
--- a/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs
@@ -47,8 +47,8 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe
47 Dictionary<string, string> certificates = new Dictionary<string, string>(); 47 Dictionary<string, string> certificates = new Dictionary<string, string>();
48 48
49 // Reset the in-memory tables for this new database 49 // Reset the in-memory tables for this new database
50 Table digitalSignatureTable = new Table(null, this.TableDefinitions["MsiDigitalSignature"]); 50 Table digitalSignatureTable = new Table(this.TableDefinitions["MsiDigitalSignature"]);
51 Table digitalCertificateTable = new Table(null, this.TableDefinitions["MsiDigitalCertificate"]); 51 Table digitalCertificateTable = new Table(this.TableDefinitions["MsiDigitalCertificate"]);
52 52
53 // If any digital signature records exist that are not of the media type, preserve them 53 // If any digital signature records exist that are not of the media type, preserve them
54 if (database.TableExists("MsiDigitalSignature")) 54 if (database.TableExists("MsiDigitalSignature"))
diff --git a/src/WixToolset.Core/Melter.cs b/src/WixToolset.Core.WindowsInstaller/Melter.cs
index ccc0cb6f..a57f73a5 100644
--- a/src/WixToolset.Core/Melter.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Melter.cs
@@ -19,6 +19,7 @@ namespace WixToolset
19 /// </summary> 19 /// </summary>
20 public sealed class Melter 20 public sealed class Melter
21 { 21 {
22#if TODO
22 private MelterCore core; 23 private MelterCore core;
23 private Decompiler decompiler; 24 private Decompiler decompiler;
24 25
@@ -394,5 +395,6 @@ namespace WixToolset
394 } 395 }
395 } 396 }
396 } 397 }
398#endif
397 } 399 }
398} 400}
diff --git a/src/WixToolset.Core/MelterCore.cs b/src/WixToolset.Core.WindowsInstaller/MelterCore.cs
index 75d43619..75d43619 100644
--- a/src/WixToolset.Core/MelterCore.cs
+++ b/src/WixToolset.Core.WindowsInstaller/MelterCore.cs
diff --git a/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs b/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs
index bf7b4579..2590c14f 100644
--- a/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs
+++ b/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs
@@ -28,7 +28,7 @@ namespace WixToolset.Core.WindowsInstaller
28 return command.Execute(); 28 return command.Execute();
29 } 29 }
30 30
31 public Output Unbind(IUnbindContext context) 31 public Intermediate Unbind(IUnbindContext context)
32 { 32 {
33 var command = new UnbindMsiOrMsmCommand(context); 33 var command = new UnbindMsiOrMsmCommand(context);
34 return command.Execute(); 34 return command.Execute();
diff --git a/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs b/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs
index 69d7ada0..e39eb883 100644
--- a/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs
+++ b/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs
@@ -26,7 +26,7 @@ namespace WixToolset.Core.WindowsInstaller
26 return false; 26 return false;
27 } 27 }
28 28
29 public Output Unbind(IUnbindContext context) 29 public Intermediate Unbind(IUnbindContext context)
30 { 30 {
31 var command = new UnbindMsiOrMsmCommand(context); 31 var command = new UnbindMsiOrMsmCommand(context);
32 return command.Execute(); 32 return command.Execute();
diff --git a/src/WixToolset.Core.WindowsInstaller/MspBackend.cs b/src/WixToolset.Core.WindowsInstaller/MspBackend.cs
index ea16a570..8fb63665 100644
--- a/src/WixToolset.Core.WindowsInstaller/MspBackend.cs
+++ b/src/WixToolset.Core.WindowsInstaller/MspBackend.cs
@@ -26,8 +26,9 @@ namespace WixToolset.Core.WindowsInstaller
26 throw new NotImplementedException(); 26 throw new NotImplementedException();
27 } 27 }
28 28
29 public Output Unbind(IUnbindContext context) 29 public Intermediate Unbind(IUnbindContext context)
30 { 30 {
31#if REVISIT_FOR_PATCHING
31 Output patch; 32 Output patch;
32 33
33 // patch files are essentially database files (use a special flag to let the API know its a patch file) 34 // patch files are essentially database files (use a special flag to let the API know its a patch file)
@@ -65,7 +66,7 @@ namespace WixToolset.Core.WindowsInstaller
65 string transformFile = Path.Combine(context.IntermediateFolder, String.Concat("Transform", Path.DirectorySeparatorChar, subStorageName, ".mst")); 66 string transformFile = Path.Combine(context.IntermediateFolder, String.Concat("Transform", Path.DirectorySeparatorChar, subStorageName, ".mst"));
66 67
67 // ensure the parent directory exists 68 // ensure the parent directory exists
68 System.IO.Directory.CreateDirectory(Path.GetDirectoryName(transformFile)); 69 Directory.CreateDirectory(Path.GetDirectoryName(transformFile));
69 70
70 // copy the substorage to a new storage for the transform file 71 // copy the substorage to a new storage for the transform file
71 using (Storage subStorage = storage.OpenStorage(subStorageName)) 72 using (Storage subStorage = storage.OpenStorage(subStorageName))
@@ -107,6 +108,8 @@ namespace WixToolset.Core.WindowsInstaller
107 } 108 }
108 109
109 return patch; 110 return patch;
111#endif
112 throw new NotImplementedException();
110 } 113 }
111 } 114 }
112} \ No newline at end of file 115} \ No newline at end of file
diff --git a/src/WixToolset.Core.WindowsInstaller/MstBackend.cs b/src/WixToolset.Core.WindowsInstaller/MstBackend.cs
index 66bc57ae..3e40a51f 100644
--- a/src/WixToolset.Core.WindowsInstaller/MstBackend.cs
+++ b/src/WixToolset.Core.WindowsInstaller/MstBackend.cs
@@ -14,6 +14,7 @@ namespace WixToolset.Core.WindowsInstaller
14 { 14 {
15 public BindResult Bind(IBindContext context) 15 public BindResult Bind(IBindContext context)
16 { 16 {
17#if REVISIT_FOR_PATCHING
17 var command = new BindTransformCommand(); 18 var command = new BindTransformCommand();
18 command.Extensions = context.Extensions; 19 command.Extensions = context.Extensions;
19 command.TempFilesLocation = context.IntermediateFolder; 20 command.TempFilesLocation = context.IntermediateFolder;
@@ -22,6 +23,8 @@ namespace WixToolset.Core.WindowsInstaller
22 command.Execute(); 23 command.Execute();
23 24
24 return new BindResult(Array.Empty<FileTransfer>(), Array.Empty<string>()); 25 return new BindResult(Array.Empty<FileTransfer>(), Array.Empty<string>());
26#endif
27 throw new NotImplementedException();
25 } 28 }
26 29
27 public bool Inscribe(IInscribeContext context) 30 public bool Inscribe(IInscribeContext context)
@@ -29,7 +32,7 @@ namespace WixToolset.Core.WindowsInstaller
29 throw new NotImplementedException(); 32 throw new NotImplementedException();
30 } 33 }
31 34
32 public Output Unbind(IUnbindContext context) 35 public Intermediate Unbind(IUnbindContext context)
33 { 36 {
34 var command = new UnbindMsiOrMsmCommand(context); 37 var command = new UnbindMsiOrMsmCommand(context);
35 return command.Execute(); 38 return command.Execute();
diff --git a/src/WixToolset.Core.WindowsInstaller/Patch.cs b/src/WixToolset.Core.WindowsInstaller/Patch.cs
index 67150e32..f4dac6e6 100644
--- a/src/WixToolset.Core.WindowsInstaller/Patch.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Patch.cs
@@ -53,6 +53,7 @@ namespace WixToolset.Data
53 [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.InvalidOperationException.#ctor(System.String)")] 53 [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.InvalidOperationException.#ctor(System.String)")]
54 public void AttachTransforms(List<PatchTransform> transforms) 54 public void AttachTransforms(List<PatchTransform> transforms)
55 { 55 {
56#if REVISIT_FOR_PATCHING
56 // Track if at least one transform gets attached. 57 // Track if at least one transform gets attached.
57 bool attachedTransform = false; 58 bool attachedTransform = false;
58 59
@@ -1231,6 +1232,8 @@ namespace WixToolset.Data
1231 } 1232 }
1232 1233
1233 return pairedTransform; 1234 return pairedTransform;
1235#endif
1236 throw new NotImplementedException();
1234 } 1237 }
1235 1238
1236 /// <summary> 1239 /// <summary>
diff --git a/src/WixToolset.Core/PatchTransform.cs b/src/WixToolset.Core.WindowsInstaller/PatchTransform.cs
index 46e4e6d7..9ba14843 100644
--- a/src/WixToolset.Core/PatchTransform.cs
+++ b/src/WixToolset.Core.WindowsInstaller/PatchTransform.cs
@@ -13,7 +13,7 @@ namespace WixToolset
13 public class PatchTransform : IMessageHandler 13 public class PatchTransform : IMessageHandler
14 { 14 {
15 private string baseline; 15 private string baseline;
16 private Output transform; 16 private Intermediate transform;
17 private string transformPath; 17 private string transformPath;
18 18
19 public string Baseline 19 public string Baseline
@@ -21,13 +21,13 @@ namespace WixToolset
21 get { return this.baseline; } 21 get { return this.baseline; }
22 } 22 }
23 23
24 public Output Transform 24 public Intermediate Transform
25 { 25 {
26 get 26 get
27 { 27 {
28 if (null == this.transform) 28 if (null == this.transform)
29 { 29 {
30 this.transform = Output.Load(this.transformPath, false); 30 this.transform = Intermediate.Load(this.transformPath, false);
31 } 31 }
32 32
33 return this.transform; 33 return this.transform;
@@ -50,6 +50,7 @@ namespace WixToolset
50 /// </summary> 50 /// </summary>
51 public void Validate() 51 public void Validate()
52 { 52 {
53#if REVISIT_FOR_PATCHING
53 // Changing the ProdocutCode in a patch transform is not recommended. 54 // Changing the ProdocutCode in a patch transform is not recommended.
54 Table propertyTable = this.Transform.Tables["Property"]; 55 Table propertyTable = this.Transform.Tables["Property"];
55 if (null != propertyTable) 56 if (null != propertyTable)
@@ -260,6 +261,8 @@ namespace WixToolset
260 } 261 }
261 } 262 }
262 } 263 }
264#endif
265 throw new NotImplementedException();
263 } 266 }
264 267
265 /// <summary> 268 /// <summary>
diff --git a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
index 208be874..15445bc8 100644
--- a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
@@ -83,7 +83,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
83 { 83 {
84 using (SummaryInformation summaryInformation = new SummaryInformation(this.Database)) 84 using (SummaryInformation summaryInformation = new SummaryInformation(this.Database))
85 { 85 {
86 Table table = new Table(null, this.TableDefinitions["_SummaryInformation"]); 86 Table table = new Table(this.TableDefinitions["_SummaryInformation"]);
87 87
88 for (int i = 1; 19 >= i; i++) 88 for (int i = 1; 19 >= i; i++)
89 { 89 {
@@ -277,7 +277,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
277 tableDefinition = this.TableDefinitions[tableName]; 277 tableDefinition = this.TableDefinitions[tableName];
278 } 278 }
279 279
280 Table table = new Table(null, tableDefinition); 280 Table table = new Table(tableDefinition);
281 281
282 while (true) 282 while (true)
283 { 283 {
diff --git a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindMsiOrMsmCommand.cs b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindMsiOrMsmCommand.cs
index f04dcefe..ce3f1ff6 100644
--- a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindMsiOrMsmCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindMsiOrMsmCommand.cs
@@ -18,8 +18,9 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
18 18
19 public IUnbindContext Context { get; } 19 public IUnbindContext Context { get; }
20 20
21 public Output Execute() 21 public Intermediate Execute()
22 { 22 {
23#if REVISIT_FOR_PATCHING
23 Output output; 24 Output output;
24 25
25 try 26 try
@@ -48,6 +49,8 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
48 } 49 }
49 50
50 return output; 51 return output;
52#endif
53 throw new NotImplementedException();
51 } 54 }
52 } 55 }
53} 56}
diff --git a/src/WixToolset.Core/UnbindContext.cs b/src/WixToolset.Core.WindowsInstaller/UnbindContext.cs
index ed55f312..ed55f312 100644
--- a/src/WixToolset.Core/UnbindContext.cs
+++ b/src/WixToolset.Core.WindowsInstaller/UnbindContext.cs
diff --git a/src/WixToolset.Core/Unbinder.cs b/src/WixToolset.Core.WindowsInstaller/Unbinder.cs
index 2ff51997..d2d27d45 100644
--- a/src/WixToolset.Core/Unbinder.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Unbinder.cs
@@ -13,19 +13,6 @@ namespace WixToolset.Core
13 /// </summary> 13 /// </summary>
14 public sealed class Unbinder 14 public sealed class Unbinder
15 { 15 {
16 private TableDefinitionCollection tableDefinitions;
17 private ArrayList unbinderExtensions;
18 // private TempFileCollection tempFiles;
19
20 /// <summary>
21 /// Creates a new unbinder object with a default set of table definitions.
22 /// </summary>
23 public Unbinder()
24 {
25 this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions());
26 this.unbinderExtensions = new ArrayList();
27 }
28
29 public IEnumerable<IBackendFactory> BackendFactories { get; } 16 public IEnumerable<IBackendFactory> BackendFactories { get; }
30 17
31 /// <summary> 18 /// <summary>
@@ -54,44 +41,13 @@ namespace WixToolset.Core
54 public string TempFilesLocation => Path.GetTempPath(); 41 public string TempFilesLocation => Path.GetTempPath();
55 42
56 /// <summary> 43 /// <summary>
57 /// Adds extension data.
58 /// </summary>
59 /// <param name="data">The extension data to add.</param>
60 public void AddExtensionData(IExtensionData data)
61 {
62 if (null != data.TableDefinitions)
63 {
64 foreach (TableDefinition tableDefinition in data.TableDefinitions)
65 {
66 if (!this.tableDefinitions.Contains(tableDefinition.Name))
67 {
68 this.tableDefinitions.Add(tableDefinition);
69 }
70 else
71 {
72 Messaging.Instance.OnMessage(WixErrors.DuplicateExtensionTable(data.GetType().ToString(), tableDefinition.Name));
73 }
74 }
75 }
76 }
77
78 /// <summary>
79 /// Adds an extension.
80 /// </summary>
81 /// <param name="extension">The extension to add.</param>
82 public void AddExtension(IUnbinderExtension extension)
83 {
84 this.unbinderExtensions.Add(extension);
85 }
86
87 /// <summary>
88 /// Unbind a Windows Installer file. 44 /// Unbind a Windows Installer file.
89 /// </summary> 45 /// </summary>
90 /// <param name="file">The Windows Installer file.</param> 46 /// <param name="file">The Windows Installer file.</param>
91 /// <param name="outputType">The type of output to create.</param> 47 /// <param name="outputType">The type of output to create.</param>
92 /// <param name="exportBasePath">The path where files should be exported.</param> 48 /// <param name="exportBasePath">The path where files should be exported.</param>
93 /// <returns>The output representing the database.</returns> 49 /// <returns>The output representing the database.</returns>
94 public Output Unbind(string file, OutputType outputType, string exportBasePath) 50 public Intermediate Unbind(string file, OutputType outputType, string exportBasePath)
95 { 51 {
96 if (!File.Exists(file)) 52 if (!File.Exists(file))
97 { 53 {
diff --git a/src/WixToolset.Core.WindowsInstaller/WixToolset.Core.WindowsInstaller.csproj b/src/WixToolset.Core.WindowsInstaller/WixToolset.Core.WindowsInstaller.csproj
index d74cb1e8..da49f31c 100644
--- a/src/WixToolset.Core.WindowsInstaller/WixToolset.Core.WindowsInstaller.csproj
+++ b/src/WixToolset.Core.WindowsInstaller/WixToolset.Core.WindowsInstaller.csproj
@@ -22,6 +22,8 @@
22 <ProjectReference Include="$(WixToolsetRootFolder)\Core.Native\src\WixToolset.Core.Native\WixToolset.Core.Native.csproj" Condition=" '$(Configuration)' == 'Debug' And Exists('$(WixToolsetRootFolder)\Core.Native\src\WixToolset.Core.Native\WixToolset.Core.Native.csproj') " /> 22 <ProjectReference Include="$(WixToolsetRootFolder)\Core.Native\src\WixToolset.Core.Native\WixToolset.Core.Native.csproj" Condition=" '$(Configuration)' == 'Debug' And Exists('$(WixToolsetRootFolder)\Core.Native\src\WixToolset.Core.Native\WixToolset.Core.Native.csproj') " />
23 23
24 <ProjectReference Include="..\WixToolset.Core\WixToolset.Core.csproj" /> 24 <ProjectReference Include="..\WixToolset.Core\WixToolset.Core.csproj" />
25
26 <ProjectReference Include="..\WixToolset.Data.WindowsInstaller\WixToolset.Data.WindowsInstaller.csproj" />
25 <PackageReference Include="WixToolset.Core.Native" Version="4.0.*" Condition=" '$(Configuration)' == 'Release' Or !Exists('$(WixToolsetRootFolder)\Core.Native\src\WixToolset.Core.Native\WixToolset.Core.Native.csproj') " /> 27 <PackageReference Include="WixToolset.Core.Native" Version="4.0.*" Condition=" '$(Configuration)' == 'Release' Or !Exists('$(WixToolsetRootFolder)\Core.Native\src\WixToolset.Core.Native\WixToolset.Core.Native.csproj') " />
26 </ItemGroup> 28 </ItemGroup>
27 29
diff --git a/src/WixToolset.Core/Bind/DelayedField.cs b/src/WixToolset.Core/Bind/DelayedField.cs
index 6c56f27c..8b761b94 100644
--- a/src/WixToolset.Core/Bind/DelayedField.cs
+++ b/src/WixToolset.Core/Bind/DelayedField.cs
@@ -16,7 +16,7 @@ namespace WixToolset.Core.Bind
16 /// </summary> 16 /// </summary>
17 /// <param name="row">Row for the field.</param> 17 /// <param name="row">Row for the field.</param>
18 /// <param name="field">Field needing further resolution.</param> 18 /// <param name="field">Field needing further resolution.</param>
19 public DelayedField(Row row, Field field) 19 public DelayedField(IntermediateTuple row, IntermediateField field)
20 { 20 {
21 this.Row = row; 21 this.Row = row;
22 this.Field = field; 22 this.Field = field;
@@ -25,11 +25,11 @@ namespace WixToolset.Core.Bind
25 /// <summary> 25 /// <summary>
26 /// The row containing the field. 26 /// The row containing the field.
27 /// </summary> 27 /// </summary>
28 public Row Row { get; } 28 public IntermediateTuple Row { get; }
29 29
30 /// <summary> 30 /// <summary>
31 /// The field needing further resolving. 31 /// The field needing further resolving.
32 /// </summary> 32 /// </summary>
33 public Field Field { get; } 33 public IntermediateField Field { get; }
34 } 34 }
35} 35}
diff --git a/src/WixToolset.Core/Bind/FileFacade.cs b/src/WixToolset.Core/Bind/FileFacade.cs
index aaa6b7d3..ebca9cff 100644
--- a/src/WixToolset.Core/Bind/FileFacade.cs
+++ b/src/WixToolset.Core/Bind/FileFacade.cs
@@ -3,19 +3,18 @@
3namespace WixToolset.Core.Bind 3namespace WixToolset.Core.Bind
4{ 4{
5 using System.Collections.Generic; 5 using System.Collections.Generic;
6 using WixToolset.Data; 6 using WixToolset.Data.Tuples;
7 using WixToolset.Data.Rows;
8 7
9 public class FileFacade 8 public class FileFacade
10 { 9 {
11 public FileFacade(FileRow file, WixFileRow wixFile, WixDeltaPatchFileRow deltaPatchFile) 10 public FileFacade(FileTuple file, WixFileTuple wixFile, WixDeltaPatchFileTuple deltaPatchFile)
12 { 11 {
13 this.File = file; 12 this.File = file;
14 this.WixFile = wixFile; 13 this.WixFile = wixFile;
15 this.DeltaPatchFile = deltaPatchFile; 14 this.DeltaPatchFile = deltaPatchFile;
16 } 15 }
17 16
18 public FileFacade(bool fromModule, FileRow file, WixFileRow wixFile) 17 public FileFacade(bool fromModule, FileTuple file, WixFileTuple wixFile)
19 { 18 {
20 this.FromModule = fromModule; 19 this.FromModule = fromModule;
21 this.File = file; 20 this.File = file;
@@ -24,21 +23,21 @@ namespace WixToolset.Core.Bind
24 23
25 public bool FromModule { get; private set; } 24 public bool FromModule { get; private set; }
26 25
27 public FileRow File { get; private set; } 26 public FileTuple File { get; private set; }
28 27
29 public WixFileRow WixFile { get; private set; } 28 public WixFileTuple WixFile { get; private set; }
30 29
31 public WixDeltaPatchFileRow DeltaPatchFile { get; private set; } 30 public WixDeltaPatchFileTuple DeltaPatchFile { get; private set; }
32 31
33 /// <summary> 32 /// <summary>
34 /// Gets the set of MsiAssemblyName rows created for this file. 33 /// Gets the set of MsiAssemblyName rows created for this file.
35 /// </summary> 34 /// </summary>
36 /// <value>RowCollection of MsiAssemblyName table.</value> 35 /// <value>RowCollection of MsiAssemblyName table.</value>
37 public List<Row> AssemblyNames { get; set; } 36 public List<MsiAssemblyNameTuple> AssemblyNames { get; set; }
38 37
39 /// <summary> 38 /// <summary>
40 /// Gets or sets the MsiFileHash row for this file. 39 /// Gets or sets the MsiFileHash row for this file.
41 /// </summary> 40 /// </summary>
42 public Row Hash { get; set; } 41 public MsiFileHashTuple Hash { get; set; }
43 } 42 }
44} 43}
diff --git a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
index 15365c2a..d05135cf 100644
--- a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
+++ b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
@@ -34,19 +34,19 @@ namespace WixToolset.Core.Bind
34 { 34 {
35 try 35 try
36 { 36 {
37 Row propertyRow = delayedField.Row; 37 var propertyRow = delayedField.Row;
38 38
39 // process properties first in case they refer to other binder variables 39 // process properties first in case they refer to other binder variables
40 if ("Property" == propertyRow.Table.Name) 40 if (delayedField.Row.Definition.Type == TupleDefinitionType.Property)
41 { 41 {
42 string value = WixVariableResolver.ResolveDelayedVariables(propertyRow.SourceLineNumbers, (string)delayedField.Field.Data, this.VariableCache); 42 var value = WixVariableResolver.ResolveDelayedVariables(propertyRow.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache);
43 43
44 // update the variable cache with the new value 44 // update the variable cache with the new value
45 string key = String.Concat("property.", Common.Demodularize(this.OutputType, this.ModularizationGuid, (string)propertyRow[0])); 45 var key = String.Concat("property.", Common.Demodularize(this.OutputType, this.ModularizationGuid, (string)propertyRow[0]));
46 this.VariableCache[key] = value; 46 this.VariableCache[key] = value;
47 47
48 // update the field data 48 // update the field data
49 delayedField.Field.Data = value; 49 delayedField.Field.Set(value);
50 } 50 }
51 else 51 else
52 { 52 {
@@ -103,11 +103,12 @@ namespace WixToolset.Core.Bind
103 } 103 }
104 104
105 // process the remaining fields in case they refer to property binder variables 105 // process the remaining fields in case they refer to property binder variables
106 foreach (DelayedField delayedField in deferredFields) 106 foreach (var delayedField in deferredFields)
107 { 107 {
108 try 108 try
109 { 109 {
110 delayedField.Field.Data = WixVariableResolver.ResolveDelayedVariables(delayedField.Row.SourceLineNumbers, (string)delayedField.Field.Data, this.VariableCache); 110 var value = WixVariableResolver.ResolveDelayedVariables(delayedField.Row.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache);
111 delayedField.Field.Set(value);
111 } 112 }
112 catch (WixException we) 113 catch (WixException we)
113 { 114 {
diff --git a/src/WixToolset.Core/Bind/ResolveFieldsCommand.cs b/src/WixToolset.Core/Bind/ResolveFieldsCommand.cs
index f4f4f9e8..9253f352 100644
--- a/src/WixToolset.Core/Bind/ResolveFieldsCommand.cs
+++ b/src/WixToolset.Core/Bind/ResolveFieldsCommand.cs
@@ -2,6 +2,7 @@
2 2
3namespace WixToolset.Core.Bind 3namespace WixToolset.Core.Bind
4{ 4{
5 using System;
5 using System.Collections.Generic; 6 using System.Collections.Generic;
6 using WixToolset.Data; 7 using WixToolset.Data;
7 using WixToolset.Data.Bind; 8 using WixToolset.Data.Bind;
@@ -24,7 +25,7 @@ namespace WixToolset.Core.Bind
24 25
25 public string IntermediateFolder { private get; set; } 26 public string IntermediateFolder { private get; set; }
26 27
27 public TableIndexedCollection Tables { private get; set; } 28 public Intermediate Intermediate { private get; set; }
28 29
29 public bool SupportDelayedResolution { private get; set; } 30 public bool SupportDelayedResolution { private get; set; }
30 31
@@ -36,25 +37,39 @@ namespace WixToolset.Core.Bind
36 37
37 var fileResolver = new FileResolver(this.BindPaths, this.Extensions); 38 var fileResolver = new FileResolver(this.BindPaths, this.Extensions);
38 39
39 foreach (Table table in this.Tables) 40 foreach (var sections in this.Intermediate.Sections)
40 { 41 {
41 foreach (Row row in table.Rows) 42 foreach (var row in sections.Tuples)
42 { 43 {
43 foreach (Field field in row.Fields) 44 foreach (var field in row.Fields)
44 { 45 {
45 bool isDefault = true; 46 if (field == null)
46 bool delayedResolve = false; 47 {
48 continue;
49 }
50
51 var isDefault = true;
52 var delayedResolve = false;
47 53
48 // Check to make sure we're in a scenario where we can handle variable resolution. 54 // Check to make sure we're in a scenario where we can handle variable resolution.
49 if (null != delayedFields) 55 if (null != delayedFields)
50 { 56 {
51 // resolve localization and wix variables 57 // resolve localization and wix variables
52 if (field.Data is string) 58 if (field.Type == IntermediateFieldType.String)
53 { 59 {
54 field.Data = this.BindVariableResolver.ResolveVariables(row.SourceLineNumbers, field.AsString(), false, out isDefault, out delayedResolve); 60 var original = field.AsString();
55 if (delayedResolve) 61 if (!String.IsNullOrEmpty(original))
56 { 62 {
57 delayedFields.Add(new DelayedField(row, field)); 63 var value = this.BindVariableResolver.ResolveVariables(row.SourceLineNumbers, original, false, out isDefault, out delayedResolve);
64 if (original != value)
65 {
66 field.Set(value);
67 }
68
69 if (delayedResolve)
70 {
71 delayedFields.Add(new DelayedField(row, field));
72 }
58 } 73 }
59 } 74 }
60 } 75 }
@@ -66,44 +81,51 @@ namespace WixToolset.Core.Bind
66 } 81 }
67 82
68 // Resolve file paths 83 // Resolve file paths
69 if (ColumnType.Object == field.Column.Type) 84 if (field.Type == IntermediateFieldType.Path)
70 { 85 {
71 ObjectField objectField = (ObjectField)field; 86 var objectField = field.AsPath();
72 87
88#if REVISIT_FOR_PATCHING
73 // Skip file resolution if the file is to be deleted. 89 // Skip file resolution if the file is to be deleted.
74 if (RowOperation.Delete == row.Operation) 90 if (RowOperation.Delete == row.Operation)
75 { 91 {
76 continue; 92 continue;
77 } 93 }
94#endif
78 95
79 // File is embedded and path to it was not modified above. 96 // File is embedded and path to it was not modified above.
80 if (objectField.EmbeddedFileIndex.HasValue && isDefault) 97 if (objectField.EmbeddedFileIndex.HasValue && isDefault)
81 { 98 {
82 string extractPath = this.FilesWithEmbeddedFiles.AddEmbeddedFileIndex(objectField.BaseUri, objectField.EmbeddedFileIndex.Value, this.IntermediateFolder); 99 var extractPath = this.FilesWithEmbeddedFiles.AddEmbeddedFileIndex(objectField.BaseUri, objectField.EmbeddedFileIndex.Value, this.IntermediateFolder);
83 100
84 // Set the path to the embedded file once where it will be extracted. 101 // Set the path to the embedded file once where it will be extracted.
85 objectField.Data = extractPath; 102 field.Set(extractPath);
86 } 103 }
87 else if (null != objectField.Data) // non-compressed file (or localized value) 104 else if (null != objectField.Path) // non-compressed file (or localized value)
88 { 105 {
89 try 106 try
90 { 107 {
91 if (!this.BuildingPatch) // Normal binding for non-Patch scenario such as link (light.exe) 108 if (!this.BuildingPatch) // Normal binding for non-Patch scenario such as link (light.exe)
92 { 109 {
110#if REVISIT_FOR_PATCHING
93 // keep a copy of the un-resolved data for future replay. This will be saved into wixpdb file 111 // keep a copy of the un-resolved data for future replay. This will be saved into wixpdb file
94 if (null == objectField.UnresolvedData) 112 if (null == objectField.UnresolvedData)
95 { 113 {
96 objectField.UnresolvedData = (string)objectField.Data; 114 objectField.UnresolvedData = (string)objectField.Data;
97 } 115 }
116#endif
98 117
99 // resolve the path to the file 118 // resolve the path to the file
100 objectField.Data = fileResolver.ResolveFile((string)objectField.Data, table.Name, row.SourceLineNumbers, BindStage.Normal); 119 var value = fileResolver.ResolveFile(objectField.Path, row.Definition.Name, row.SourceLineNumbers, BindStage.Normal);
120 field.Set(value);
101 } 121 }
102 else if (!fileResolver.RebaseTarget && !fileResolver.RebaseUpdated) // Normal binding for Patch Scenario (normal patch, no re-basing logic) 122 else if (!fileResolver.RebaseTarget && !fileResolver.RebaseUpdated) // Normal binding for Patch Scenario (normal patch, no re-basing logic)
103 { 123 {
104 // resolve the path to the file 124 // resolve the path to the file
105 objectField.Data = fileResolver.ResolveFile((string)objectField.Data, table.Name, row.SourceLineNumbers, BindStage.Normal); 125 var value = fileResolver.ResolveFile(objectField.Path, row.Definition.Name, row.SourceLineNumbers, BindStage.Normal);
126 field.Set(value);
106 } 127 }
128#if REVISIT_FOR_PATCHING
107 else // Re-base binding path scenario caused by pyro.exe -bt -bu 129 else // Re-base binding path scenario caused by pyro.exe -bt -bu
108 { 130 {
109 // by default, use the resolved Data for file lookup 131 // by default, use the resolved Data for file lookup
@@ -122,16 +144,18 @@ namespace WixToolset.Core.Bind
122 } 144 }
123 } 145 }
124 146
125 objectField.Data = fileResolver.ResolveFile(filePathToResolve, table.Name, row.SourceLineNumbers, BindStage.Updated); 147 objectField.Data = fileResolver.ResolveFile(filePathToResolve, row.Definition.Name, row.SourceLineNumbers, BindStage.Updated);
126 } 148 }
149#endif
127 } 150 }
128 catch (WixFileNotFoundException) 151 catch (WixFileNotFoundException)
129 { 152 {
130 // display the error with source line information 153 // display the error with source line information
131 Messaging.Instance.OnMessage(WixErrors.FileNotFound(row.SourceLineNumbers, (string)objectField.Data)); 154 Messaging.Instance.OnMessage(WixErrors.FileNotFound(row.SourceLineNumbers, objectField.Path));
132 } 155 }
133 } 156 }
134 157
158#if REVISIT_FOR_PATCHING
135 if (null != objectField.PreviousData) 159 if (null != objectField.PreviousData)
136 { 160 {
137 objectField.PreviousData = this.BindVariableResolver.ResolveVariables(row.SourceLineNumbers, objectField.PreviousData, false, out isDefault); 161 objectField.PreviousData = this.BindVariableResolver.ResolveVariables(row.SourceLineNumbers, objectField.PreviousData, false, out isDefault);
@@ -159,7 +183,7 @@ namespace WixToolset.Core.Bind
159 if (!fileResolver.RebaseTarget && !fileResolver.RebaseUpdated) 183 if (!fileResolver.RebaseTarget && !fileResolver.RebaseUpdated)
160 { 184 {
161 // resolve the path to the file 185 // resolve the path to the file
162 objectField.PreviousData = fileResolver.ResolveFile((string)objectField.PreviousData, table.Name, row.SourceLineNumbers, BindStage.Normal); 186 objectField.PreviousData = fileResolver.ResolveFile((string)objectField.PreviousData, row.Definition.Name, row.SourceLineNumbers, BindStage.Normal);
163 } 187 }
164 else 188 else
165 { 189 {
@@ -177,7 +201,7 @@ namespace WixToolset.Core.Bind
177 } 201 }
178 202
179 // resolve the path to the file 203 // resolve the path to the file
180 objectField.PreviousData = fileResolver.ResolveFile((string)objectField.PreviousData, table.Name, row.SourceLineNumbers, BindStage.Target); 204 objectField.PreviousData = fileResolver.ResolveFile((string)objectField.PreviousData, row.Definition.Name, row.SourceLineNumbers, BindStage.Target);
181 205
182 } 206 }
183 } 207 }
@@ -189,6 +213,7 @@ namespace WixToolset.Core.Bind
189 } 213 }
190 } 214 }
191 } 215 }
216#endif
192 } 217 }
193 } 218 }
194 } 219 }
diff --git a/src/WixToolset.Core/BindContext.cs b/src/WixToolset.Core/BindContext.cs
index 7b1a1877..7ef7ddd4 100644
--- a/src/WixToolset.Core/BindContext.cs
+++ b/src/WixToolset.Core/BindContext.cs
@@ -41,7 +41,7 @@ namespace WixToolset.Core
41 41
42 public string IntermediateFolder { get; set; } 42 public string IntermediateFolder { get; set; }
43 43
44 public Output IntermediateRepresentation { get; set; } 44 public Intermediate IntermediateRepresentation { get; set; }
45 45
46 public string OutputPath { get; set; } 46 public string OutputPath { get; set; }
47 47
diff --git a/src/WixToolset.Core/Binder.cs b/src/WixToolset.Core/Binder.cs
index 34bf0dee..07a92d02 100644
--- a/src/WixToolset.Core/Binder.cs
+++ b/src/WixToolset.Core/Binder.cs
@@ -14,7 +14,7 @@ namespace WixToolset.Core
14 using WixToolset.Core.Bind; 14 using WixToolset.Core.Bind;
15 using WixToolset.Data; 15 using WixToolset.Data;
16 using WixToolset.Data.Bind; 16 using WixToolset.Data.Bind;
17 using WixToolset.Data.Rows; 17 using WixToolset.Data.Tuples;
18 using WixToolset.Extensibility; 18 using WixToolset.Extensibility;
19 using WixToolset.Extensibility.Services; 19 using WixToolset.Extensibility.Services;
20 20
@@ -43,16 +43,9 @@ namespace WixToolset.Core
43 //this.SuppressIces = new List<string>(); 43 //this.SuppressIces = new List<string>();
44 } 44 }
45 45
46 public Binder(IBindContext context) 46 private IBindContext Context { get; set; }
47 {
48 this.Context = context;
49
50 this.TableDefinitions = WindowsInstallerStandard.GetTableDefinitions();
51 }
52
53 private IBindContext Context { get; }
54 47
55 private TableDefinitionCollection TableDefinitions { get; } 48 //private TableDefinitionCollection TableDefinitions { get; }
56 49
57 //public IEnumerable<IBackendFactory> BackendFactories { get; set; } 50 //public IEnumerable<IBackendFactory> BackendFactories { get; set; }
58 51
@@ -173,8 +166,10 @@ namespace WixToolset.Core
173 // this.fileManagers.Add(extension); 166 // this.fileManagers.Add(extension);
174 //} 167 //}
175 168
176 public bool Bind() 169 public bool Bind(IBindContext context)
177 { 170 {
171 this.Context = context;
172
178 //if (!String.IsNullOrEmpty(this.Context.FileManagerCore.CabCachePath)) 173 //if (!String.IsNullOrEmpty(this.Context.FileManagerCore.CabCachePath))
179 //{ 174 //{
180 // Directory.CreateDirectory(this.Context.FileManagerCore.CabCachePath); 175 // Directory.CreateDirectory(this.Context.FileManagerCore.CabCachePath);
@@ -225,7 +220,7 @@ namespace WixToolset.Core
225 220
226 private ResolveResult Resolve() 221 private ResolveResult Resolve()
227 { 222 {
228 var buildingPatch = (this.Context.IntermediateRepresentation.Type == OutputType.Patch); 223 var buildingPatch = this.Context.IntermediateRepresentation.Sections.Any(s => s.Type == SectionType.Patch);
229 224
230 var filesWithEmbeddedFiles = new ExtractEmbeddedFiles(); 225 var filesWithEmbeddedFiles = new ExtractEmbeddedFiles();
231 226
@@ -238,13 +233,14 @@ namespace WixToolset.Core
238 command.Extensions = this.Context.Extensions; 233 command.Extensions = this.Context.Extensions;
239 command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles; 234 command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles;
240 command.IntermediateFolder = this.Context.IntermediateFolder; 235 command.IntermediateFolder = this.Context.IntermediateFolder;
241 command.Tables = this.Context.IntermediateRepresentation.Tables; 236 command.Intermediate = this.Context.IntermediateRepresentation;
242 command.SupportDelayedResolution = true; 237 command.SupportDelayedResolution = true;
243 command.Execute(); 238 command.Execute();
244 239
245 delayedFields = command.DelayedFields; 240 delayedFields = command.DelayedFields;
246 } 241 }
247 242
243#if REVISIT_FOR_PATCHING
248 if (this.Context.IntermediateRepresentation.SubStorages != null) 244 if (this.Context.IntermediateRepresentation.SubStorages != null)
249 { 245 {
250 foreach (SubStorage transform in this.Context.IntermediateRepresentation.SubStorages) 246 foreach (SubStorage transform in this.Context.IntermediateRepresentation.SubStorages)
@@ -256,11 +252,12 @@ namespace WixToolset.Core
256 command.Extensions = this.Context.Extensions; 252 command.Extensions = this.Context.Extensions;
257 command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles; 253 command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles;
258 command.IntermediateFolder = this.Context.IntermediateFolder; 254 command.IntermediateFolder = this.Context.IntermediateFolder;
259 command.Tables = transform.Data.Tables; 255 command.Intermediate = this.Context.IntermediateRepresentation;
260 command.SupportDelayedResolution = false; 256 command.SupportDelayedResolution = false;
261 command.Execute(); 257 command.Execute();
262 } 258 }
263 } 259 }
260#endif
264 261
265 var expectedEmbeddedFiles = filesWithEmbeddedFiles.GetExpectedEmbeddedFiles(); 262 var expectedEmbeddedFiles = filesWithEmbeddedFiles.GetExpectedEmbeddedFiles();
266 263
@@ -275,9 +272,11 @@ namespace WixToolset.Core
275 { 272 {
276 var backendFactories = this.Context.ExtensionManager.Create<IBackendFactory>(); 273 var backendFactories = this.Context.ExtensionManager.Create<IBackendFactory>();
277 274
275 var entrySection = this.Context.IntermediateRepresentation.Sections[0];
276
278 foreach (var factory in backendFactories) 277 foreach (var factory in backendFactories)
279 { 278 {
280 if (factory.TryCreateBackend(this.Context.IntermediateRepresentation.Type.ToString(), this.Context.OutputPath, null, out var backend)) 279 if (factory.TryCreateBackend(entrySection.Type.ToString(), this.Context.OutputPath, null, out var backend))
281 { 280 {
282 var result = backend.Bind(this.Context); 281 var result = backend.Bind(this.Context);
283 return result; 282 return result;
@@ -288,6 +287,7 @@ namespace WixToolset.Core
288 287
289 return null; 288 return null;
290 } 289 }
290
291 private void Layout(BindResult result) 291 private void Layout(BindResult result)
292 { 292 {
293 try 293 try
@@ -461,25 +461,28 @@ namespace WixToolset.Core
461 /// </summary> 461 /// </summary>
462 /// <param name="output">The output.</param> 462 /// <param name="output">The output.</param>
463 /// <param name="databaseFile">The output file if OutputFile not set.</param> 463 /// <param name="databaseFile">The output file if OutputFile not set.</param>
464 private void WriteBuildInfoTable(Output output, string outputFile) 464 private void WriteBuildInfoTable(Intermediate output, string outputFile)
465 { 465 {
466 Table buildInfoTable = output.EnsureTable(this.TableDefinitions["WixBuildInfo"]); 466 var entrySection = output.Sections.First(s => s.Type != SectionType.Fragment);
467 Row buildInfoRow = buildInfoTable.CreateRow(null);
468 467
469 Assembly executingAssembly = Assembly.GetExecutingAssembly(); 468 Assembly executingAssembly = Assembly.GetExecutingAssembly();
470 FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(executingAssembly.Location); 469 FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(executingAssembly.Location);
471 buildInfoRow[0] = fileVersion.FileVersion; 470
472 buildInfoRow[1] = outputFile; 471 var buildInfoRow = new WixBuildInfoTuple();
472 buildInfoRow.WixVersion = fileVersion.FileVersion;
473 buildInfoRow.WixOutputFile = outputFile;
473 474
474 if (!String.IsNullOrEmpty(this.Context.WixprojectFile)) 475 if (!String.IsNullOrEmpty(this.Context.WixprojectFile))
475 { 476 {
476 buildInfoRow[2] = this.Context.WixprojectFile; 477 buildInfoRow.WixProjectFile = this.Context.WixprojectFile;
477 } 478 }
478 479
479 if (!String.IsNullOrEmpty(this.Context.OutputPdbPath)) 480 if (!String.IsNullOrEmpty(this.Context.OutputPdbPath))
480 { 481 {
481 buildInfoRow[3] = this.Context.OutputPdbPath; 482 buildInfoRow.WixPdbFile = this.Context.OutputPdbPath;
482 } 483 }
484
485 entrySection.Tuples.Add(buildInfoRow);
483 } 486 }
484 487
485#if DELETE_THIS_CODE 488#if DELETE_THIS_CODE
@@ -720,7 +723,7 @@ namespace WixToolset.Core
720 /// </summary> 723 /// </summary>
721 /// <param name="path">Path to write file.</param> 724 /// <param name="path">Path to write file.</param>
722 /// <param name="payloads">Collection of payloads whose source will be written to file.</param> 725 /// <param name="payloads">Collection of payloads whose source will be written to file.</param>
723 private void CreateContentsFile(string path, IEnumerable<WixBundlePayloadRow> payloads) 726 private void CreateContentsFile(string path, IEnumerable<WixBundlePayloadTuple> payloads)
724 { 727 {
725 string directory = Path.GetDirectoryName(path); 728 string directory = Path.GetDirectoryName(path);
726 if (!Directory.Exists(directory)) 729 if (!Directory.Exists(directory))
@@ -730,11 +733,12 @@ namespace WixToolset.Core
730 733
731 using (StreamWriter contents = new StreamWriter(path, false)) 734 using (StreamWriter contents = new StreamWriter(path, false))
732 { 735 {
733 foreach (WixBundlePayloadRow payload in payloads) 736 foreach (var payload in payloads)
734 { 737 {
735 if (payload.ContentFile) 738 if (payload.ContentFile)
736 { 739 {
737 contents.WriteLine(payload.FullFileName); 740 var fullPath = Path.GetFullPath(payload.SourceFile);
741 contents.WriteLine(fullPath);
738 } 742 }
739 } 743 }
740 } 744 }
diff --git a/src/WixToolset.Core/BinderCore.cs b/src/WixToolset.Core/BinderCore.cs
index 0feae0b2..84173b99 100644
--- a/src/WixToolset.Core/BinderCore.cs
+++ b/src/WixToolset.Core/BinderCore.cs
@@ -10,14 +10,6 @@ namespace WixToolset
10 /// </summary> 10 /// </summary>
11 internal class BinderCore : IBinderCore 11 internal class BinderCore : IBinderCore
12 { 12 {
13 /// <summary>
14 /// Constructor for binder core.
15 /// </summary>
16 internal BinderCore()
17 {
18 this.TableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions());
19 }
20
21 public IBinderFileManagerCore FileManagerCore { get; set; } 13 public IBinderFileManagerCore FileManagerCore { get; set; }
22 14
23 /// <summary> 15 /// <summary>
@@ -30,12 +22,6 @@ namespace WixToolset
30 } 22 }
31 23
32 /// <summary> 24 /// <summary>
33 /// Gets the table definitions used by the Binder.
34 /// </summary>
35 /// <value>Table definitions used by the binder.</value>
36 public TableDefinitionCollection TableDefinitions { get; private set; }
37
38 /// <summary>
39 /// Generate an identifier by hashing data from the row. 25 /// Generate an identifier by hashing data from the row.
40 /// </summary> 26 /// </summary>
41 /// <param name="prefix">Three letter or less prefix for generated row identifier.</param> 27 /// <param name="prefix">Three letter or less prefix for generated row identifier.</param>
diff --git a/src/WixToolset.Core/BinderFileManagerCore.cs b/src/WixToolset.Core/BinderFileManagerCore.cs
index f1a78880..5780983a 100644
--- a/src/WixToolset.Core/BinderFileManagerCore.cs
+++ b/src/WixToolset.Core/BinderFileManagerCore.cs
@@ -34,13 +34,13 @@ namespace WixToolset
34 /// Gets or sets the active subStorage used for binding. 34 /// Gets or sets the active subStorage used for binding.
35 /// </summary> 35 /// </summary>
36 /// <value>The subStorage object.</value> 36 /// <value>The subStorage object.</value>
37 public SubStorage ActiveSubStorage { get; set; } 37 //public SubStorage ActiveSubStorage { get; set; }
38 38
39 /// <summary> 39 /// <summary>
40 /// Gets or sets the output object used for binding. 40 /// Gets or sets the output object used for binding.
41 /// </summary> 41 /// </summary>
42 /// <value>The output object.</value> 42 /// <value>The output object.</value>
43 public Output Output { get; set; } 43 public Intermediate Intermediate { get; set; }
44 44
45 /// <summary> 45 /// <summary>
46 /// Gets or sets the path to the temp files location. 46 /// Gets or sets the path to the temp files location.
diff --git a/src/WixToolset.Core/CommandLine/BuildCommand.cs b/src/WixToolset.Core/CommandLine/BuildCommand.cs
index 4a1fc1ed..54bf688d 100644
--- a/src/WixToolset.Core/CommandLine/BuildCommand.cs
+++ b/src/WixToolset.Core/CommandLine/BuildCommand.cs
@@ -7,7 +7,7 @@ namespace WixToolset.Core
7 using System.IO; 7 using System.IO;
8 using System.Linq; 8 using System.Linq;
9 using WixToolset.Data; 9 using WixToolset.Data;
10 using WixToolset.Data.Rows; 10 using WixToolset.Data.Tuples;
11 using WixToolset.Extensibility; 11 using WixToolset.Extensibility;
12 using WixToolset.Extensibility.Services; 12 using WixToolset.Extensibility.Services;
13 13
@@ -79,21 +79,19 @@ namespace WixToolset.Core
79 return 1; 79 return 1;
80 } 80 }
81 81
82 var tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions());
83
84 if (this.OutputType == OutputType.Library) 82 if (this.OutputType == OutputType.Library)
85 { 83 {
86 var library = this.LibraryPhase(intermediates, tableDefinitions); 84 var library = this.LibraryPhase(intermediates);
87 85
88 library?.Save(this.OutputPath); 86 library?.Save(this.OutputPath);
89 } 87 }
90 else 88 else
91 { 89 {
92 var output = this.LinkPhase(intermediates, tableDefinitions); 90 var output = this.LinkPhase(intermediates);
93 91
94 if (!Messaging.Instance.EncounteredError) 92 if (!Messaging.Instance.EncounteredError)
95 { 93 {
96 this.BindPhase(output, tableDefinitions); 94 this.BindPhase(output);
97 } 95 }
98 } 96 }
99 97
@@ -104,15 +102,26 @@ namespace WixToolset.Core
104 { 102 {
105 var intermediates = new List<Intermediate>(); 103 var intermediates = new List<Intermediate>();
106 104
107 var preprocessor = new Preprocessor();
108
109 var compiler = new Compiler();
110 105
111 foreach (var sourceFile in this.SourceFiles) 106 foreach (var sourceFile in this.SourceFiles)
112 { 107 {
108 //var preprocessContext = this.ServiceProvider.GetService<IPreprocessContext>();
109 //preprocessContext.SourcePath = sourceFile.SourcePath;
110 //preprocessContext.Variables = this.PreprocessorVariables;
111
112 var preprocessor = new Preprocessor();
113 var document = preprocessor.Process(sourceFile.SourcePath, this.PreprocessorVariables); 113 var document = preprocessor.Process(sourceFile.SourcePath, this.PreprocessorVariables);
114 114
115 var intermediate = compiler.Compile(document); 115 var compileContext = this.ServiceProvider.GetService<ICompileContext>();
116 compileContext.Messaging = Messaging.Instance;
117 compileContext.CompilationId = Guid.NewGuid().ToString("N");
118 compileContext.Extensions = this.ExtensionManager.Create<ICompilerExtension>();
119 compileContext.OutputPath = sourceFile.OutputPath;
120 compileContext.Platform = Platform.X86; // TODO: set this correctly
121 compileContext.Source = document;
122
123 var compiler = new Compiler();
124 var intermediate = compiler.Compile(compileContext);
116 125
117 intermediates.Add(intermediate); 126 intermediates.Add(intermediate);
118 } 127 }
@@ -120,9 +129,9 @@ namespace WixToolset.Core
120 return intermediates; 129 return intermediates;
121 } 130 }
122 131
123 private Library LibraryPhase(IEnumerable<Intermediate> intermediates, TableDefinitionCollection tableDefinitions) 132 private Intermediate LibraryPhase(IEnumerable<Intermediate> intermediates)
124 { 133 {
125 var localizations = this.LoadLocalizationFiles(tableDefinitions).ToList(); 134 var localizations = this.LoadLocalizationFiles().ToList();
126 135
127 // If there was an error adding localization files, then bail. 136 // If there was an error adding localization files, then bail.
128 if (Messaging.Instance.EncounteredError) 137 if (Messaging.Instance.EncounteredError)
@@ -137,35 +146,34 @@ namespace WixToolset.Core
137 context.BindPaths = this.BindPaths; 146 context.BindPaths = this.BindPaths;
138 context.Extensions = this.ExtensionManager.Create<ILibrarianExtension>(); 147 context.Extensions = this.ExtensionManager.Create<ILibrarianExtension>();
139 context.Localizations = localizations; 148 context.Localizations = localizations;
140 context.Sections = intermediates.SelectMany(i => i.Sections).ToList(); 149 context.LibraryId = Guid.NewGuid().ToString("N");
150 context.Intermediates = intermediates;
141 context.WixVariableResolver = resolver; 151 context.WixVariableResolver = resolver;
142 152
143 var librarian = new Librarian(context); 153 var librarian = new Librarian();
144 154 return librarian.Combine(context);
145 return librarian.Combine();
146 } 155 }
147 156
148 private Output LinkPhase(IEnumerable<Intermediate> intermediates, TableDefinitionCollection tableDefinitions) 157 private Intermediate LinkPhase(IEnumerable<Intermediate> intermediates)
149 { 158 {
150 var sections = intermediates.SelectMany(i => i.Sections).ToList(); 159 var creator = this.ServiceProvider.GetService<ITupleDefinitionCreator>();
151
152 sections.AddRange(this.SectionsFromLibraries(tableDefinitions));
153 160
154 var linker = new Linker(); 161 var libraries = this.LoadLibraries(creator);
155
156 foreach (var data in this.ExtensionManager.Create<IExtensionData>())
157 {
158 linker.AddExtensionData(data);
159 }
160 162
161 var output = linker.Link(sections, this.OutputType); 163 var context = this.ServiceProvider.GetService<ILinkContext>();
164 context.Messaging = Messaging.Instance;
165 context.Extensions = this.ExtensionManager.Create<ILinkerExtension>();
166 context.Intermediates = intermediates.Union(libraries).ToList();
167 context.ExpectedOutputType = this.OutputType;
162 168
169 var linker = new Linker();
170 var output = linker.Link(context);
163 return output; 171 return output;
164 } 172 }
165 173
166 private void BindPhase(Output output, TableDefinitionCollection tableDefinitions) 174 private void BindPhase(Intermediate output)
167 { 175 {
168 var localizations = this.LoadLocalizationFiles(tableDefinitions).ToList(); 176 var localizations = this.LoadLocalizationFiles().ToList();
169 177
170 var localizer = new Localizer(localizations); 178 var localizer = new Localizer(localizations);
171 179
@@ -199,13 +207,13 @@ namespace WixToolset.Core
199 context.BuiltOutputsFile = this.BuiltOutputsFile; 207 context.BuiltOutputsFile = this.BuiltOutputsFile;
200 context.WixprojectFile = this.WixProjectFile; 208 context.WixprojectFile = this.WixProjectFile;
201 209
202 var binder = new Binder(context); 210 var binder = new Binder();
203 binder.Bind(); 211 binder.Bind(context);
204 } 212 }
205 213
206 private IEnumerable<Section> SectionsFromLibraries(TableDefinitionCollection tableDefinitions) 214 private IEnumerable<Intermediate> LoadLibraries(ITupleDefinitionCreator creator)
207 { 215 {
208 var sections = new List<Section>(); 216 var libraries = new List<Intermediate>();
209 217
210 if (this.LibraryFiles != null) 218 if (this.LibraryFiles != null)
211 { 219 {
@@ -213,9 +221,9 @@ namespace WixToolset.Core
213 { 221 {
214 try 222 try
215 { 223 {
216 var library = Library.Load(libraryFile, tableDefinitions, false); 224 var library = Intermediate.Load(libraryFile, creator);
217 225
218 sections.AddRange(library.Sections); 226 libraries.Add(library);
219 } 227 }
220 catch (WixCorruptFileException e) 228 catch (WixCorruptFileException e)
221 { 229 {
@@ -228,28 +236,28 @@ namespace WixToolset.Core
228 } 236 }
229 } 237 }
230 238
231 return sections; 239 return libraries;
232 } 240 }
233 241
234 private IEnumerable<Localization> LoadLocalizationFiles(TableDefinitionCollection tableDefinitions) 242 private IEnumerable<Localization> LoadLocalizationFiles()
235 { 243 {
236 foreach (var loc in this.LocFiles) 244 foreach (var loc in this.LocFiles)
237 { 245 {
238 var localization = Localizer.ParseLocalizationFile(loc, tableDefinitions); 246 var localization = Localizer.ParseLocalizationFile(loc);
239 247
240 yield return localization; 248 yield return localization;
241 } 249 }
242 } 250 }
243 251
244 private static WixVariableResolver CreateWixResolverWithVariables(Localizer localizer, Output output) 252 private static WixVariableResolver CreateWixResolverWithVariables(Localizer localizer, Intermediate output)
245 { 253 {
246 var resolver = new WixVariableResolver(localizer); 254 var resolver = new WixVariableResolver(localizer);
247 255
248 // Gather all the wix variables. 256 // Gather all the wix variables.
249 Table wixVariableTable = output?.Tables["WixVariable"]; 257 var wixVariables = output?.Sections.SelectMany(s => s.Tuples).OfType<WixVariableTuple>();
250 if (null != wixVariableTable) 258 if (wixVariables != null)
251 { 259 {
252 foreach (WixVariableRow wixVariableRow in wixVariableTable.Rows) 260 foreach (var wixVariableRow in wixVariables)
253 { 261 {
254 resolver.AddVariable(wixVariableRow); 262 resolver.AddVariable(wixVariableRow);
255 } 263 }
diff --git a/src/WixToolset.Core/CommandLine/CommandLine.cs b/src/WixToolset.Core/CommandLine/CommandLine.cs
index b0594348..c6fe11b7 100644
--- a/src/WixToolset.Core/CommandLine/CommandLine.cs
+++ b/src/WixToolset.Core/CommandLine/CommandLine.cs
@@ -218,7 +218,7 @@ namespace WixToolset.Core
218 { 218 {
219 var sourceFiles = GatherSourceFiles(files, outputFolder); 219 var sourceFiles = GatherSourceFiles(files, outputFolder);
220 var variables = GatherPreprocessorVariables(defines); 220 var variables = GatherPreprocessorVariables(defines);
221 return new CompileCommand(sourceFiles, variables); 221 return new CompileCommand(this.ServiceProvider, this.ExtensionManager, sourceFiles, variables);
222 } 222 }
223 } 223 }
224 224
diff --git a/src/WixToolset.Core/CommandLine/CompileCommand.cs b/src/WixToolset.Core/CommandLine/CompileCommand.cs
index 855e7c6a..58ba9d29 100644
--- a/src/WixToolset.Core/CommandLine/CompileCommand.cs
+++ b/src/WixToolset.Core/CommandLine/CompileCommand.cs
@@ -2,32 +2,47 @@
2 2
3namespace WixToolset.Core 3namespace WixToolset.Core
4{ 4{
5 using System;
5 using System.Collections.Generic; 6 using System.Collections.Generic;
7 using WixToolset.Data;
8 using WixToolset.Extensibility;
6 using WixToolset.Extensibility.Services; 9 using WixToolset.Extensibility.Services;
7 10
8 internal class CompileCommand : ICommandLineCommand 11 internal class CompileCommand : ICommandLineCommand
9 { 12 {
10 public CompileCommand(IEnumerable<SourceFile> sources, IDictionary<string, string> preprocessorVariables) 13 public CompileCommand(IServiceProvider serviceProvider, IExtensionManager extensions, IEnumerable<SourceFile> sources, IDictionary<string, string> preprocessorVariables)
11 { 14 {
12 this.PreprocessorVariables = preprocessorVariables; 15 this.PreprocessorVariables = preprocessorVariables;
16 this.ServiceProvider = serviceProvider;
17 this.ExtensionManager = extensions;
13 this.SourceFiles = sources; 18 this.SourceFiles = sources;
14 } 19 }
15 20
21 private IServiceProvider ServiceProvider { get; }
22
23 private IExtensionManager ExtensionManager { get; }
24
16 private IEnumerable<SourceFile> SourceFiles { get; } 25 private IEnumerable<SourceFile> SourceFiles { get; }
17 26
18 private IDictionary<string, string> PreprocessorVariables { get; } 27 private IDictionary<string, string> PreprocessorVariables { get; }
19 28
20 public int Execute() 29 public int Execute()
21 { 30 {
22 var preprocessor = new Preprocessor();
23
24 var compiler = new Compiler();
25
26 foreach (var sourceFile in this.SourceFiles) 31 foreach (var sourceFile in this.SourceFiles)
27 { 32 {
33 var preprocessor = new Preprocessor();
28 var document = preprocessor.Process(sourceFile.SourcePath, this.PreprocessorVariables); 34 var document = preprocessor.Process(sourceFile.SourcePath, this.PreprocessorVariables);
29 35
30 var intermediate = compiler.Compile(document); 36 var compileContext = this.ServiceProvider.GetService<ICompileContext>();
37 compileContext.Messaging = Messaging.Instance;
38 compileContext.CompilationId = Guid.NewGuid().ToString("N");
39 compileContext.Extensions = this.ExtensionManager.Create<ICompilerExtension>();
40 compileContext.OutputPath = sourceFile.OutputPath;
41 compileContext.Platform = Platform.X86; // TODO: set this correctly
42 compileContext.Source = document;
43
44 var compiler = new Compiler();
45 var intermediate = compiler.Compile(compileContext);
31 46
32 intermediate.Save(sourceFile.OutputPath); 47 intermediate.Save(sourceFile.OutputPath);
33 } 48 }
diff --git a/src/WixToolset.Core/CompileContext.cs b/src/WixToolset.Core/CompileContext.cs
new file mode 100644
index 00000000..85759ec9
--- /dev/null
+++ b/src/WixToolset.Core/CompileContext.cs
@@ -0,0 +1,32 @@
1// 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.
2
3namespace WixToolset.Core
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.Data;
9 using WixToolset.Extensibility;
10
11 public class CompileContext : ICompileContext
12 {
13 internal CompileContext(IServiceProvider serviceProvider)
14 {
15 this.ServiceProvider = serviceProvider;
16 }
17
18 public IServiceProvider ServiceProvider { get; }
19
20 public Messaging Messaging { get; set; }
21
22 public string CompilationId { get; set; }
23
24 public IEnumerable<ICompilerExtension> Extensions { get; set; }
25
26 public string OutputPath { get; set; }
27
28 public Platform Platform { get; set; }
29
30 public XDocument Source { get; set; }
31 }
32}
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs
index d085e788..e0475baa 100644
--- a/src/WixToolset.Core/Compiler.cs
+++ b/src/WixToolset.Core/Compiler.cs
@@ -14,8 +14,9 @@ namespace WixToolset
14 using WixToolset.Core; 14 using WixToolset.Core;
15 using WixToolset.Core.Native; 15 using WixToolset.Core.Native;
16 using WixToolset.Data; 16 using WixToolset.Data;
17 using WixToolset.Data.Rows; 17 using WixToolset.Data.Tuples;
18 using WixToolset.Extensibility; 18 using WixToolset.Extensibility;
19 using WixToolset.Extensibility.Services;
19 using Wix = WixToolset.Data.Serialize; 20 using Wix = WixToolset.Data.Serialize;
20 21
21 /// <summary> 22 /// <summary>
@@ -39,12 +40,6 @@ namespace WixToolset
39 private const string BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = "WixBundleOriginalSourceFolder"; 40 private const string BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = "WixBundleOriginalSourceFolder";
40 private const string BURN_BUNDLE_LAST_USED_SOURCE = "WixBundleLastUsedSource"; 41 private const string BURN_BUNDLE_LAST_USED_SOURCE = "WixBundleLastUsedSource";
41 42
42 private TableDefinitionCollection tableDefinitions;
43 private Dictionary<XNamespace, ICompilerExtension> extensions;
44 private List<InspectorExtension> inspectorExtensions;
45 private CompilerCore core;
46 private bool showPedanticMessages;
47
48 // if these are true you know you are building a module or product 43 // if these are true you know you are building a module or product
49 // but if they are false you cannot not be sure they will not end 44 // but if they are false you cannot not be sure they will not end
50 // up a product or module. Use these flags carefully. 45 // up a product or module. Use these flags carefully.
@@ -58,18 +53,6 @@ namespace WixToolset
58 private WixVariableResolver componentIdPlaceholdersResolver; 53 private WixVariableResolver componentIdPlaceholdersResolver;
59 54
60 /// <summary> 55 /// <summary>
61 /// Creates a new compiler object with a default set of table definitions.
62 /// </summary>
63 public Compiler()
64 {
65 this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions());
66 this.extensions = new Dictionary<XNamespace, ICompilerExtension>();
67 this.inspectorExtensions = new List<InspectorExtension>();
68
69 this.CurrentPlatform = Platform.X86;
70 }
71
72 /// <summary>
73 /// Type of RadioButton element in a group. 56 /// Type of RadioButton element in a group.
74 /// </summary> 57 /// </summary>
75 private enum RadioButtonType 58 private enum RadioButtonType
@@ -87,99 +70,68 @@ namespace WixToolset
87 Icon, 70 Icon,
88 } 71 }
89 72
73 private ICompileContext Context { get; set; }
74
75 private CompilerCore Core { get; set; }
76
90 /// <summary> 77 /// <summary>
91 /// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements. 78 /// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements.
92 /// </summary> 79 /// </summary>
93 /// <value>The platform which the compiler will use when defaulting 64-bit attributes and elements.</value> 80 /// <value>The platform which the compiler will use when defaulting 64-bit attributes and elements.</value>
94 public Platform CurrentPlatform { get; set; } 81 public Platform CurrentPlatform => this.Context.Platform;
95 82
96 /// <summary> 83 /// <summary>
97 /// Gets or sets the option to show pedantic messages. 84 /// Gets or sets the option to show pedantic messages.
98 /// </summary> 85 /// </summary>
99 /// <value>The option to show pedantic messages.</value> 86 /// <value>The option to show pedantic messages.</value>
100 public bool ShowPedanticMessages 87 public bool ShowPedanticMessages { get; set; }
101 {
102 get { return this.showPedanticMessages; }
103 set { this.showPedanticMessages = value; }
104 }
105 88
106 /// <summary> 89 /// <summary>
107 /// Adds a compiler extension. 90 /// Compiles the provided Xml document into an intermediate object
108 /// </summary> 91 /// </summary>
109 /// <param name="extension">The extension to add.</param> 92 /// <param name="context">Context for the compile. The BaseURI property
110 public void AddExtension(ICompilerExtension extension) 93 /// should be properly set to get messages containing source line information.</param>
94 /// <returns>Intermediate object representing compiled source document.</returns>
95 /// <remarks>This method is not thread-safe.</remarks>
96 public Intermediate Compile(ICompileContext context)
111 { 97 {
112 // Check if this extension is adding a schema namespace that already exists. 98 this.Context = context ?? throw new ArgumentNullException(nameof(context));
113 ICompilerExtension collidingExtension; 99
114 if (!this.extensions.TryGetValue(extension.Namespace, out collidingExtension)) 100 var target = new Intermediate();
115 { 101
116 this.extensions.Add(extension.Namespace, extension); 102 if (String.IsNullOrEmpty(context.CompilationId))
117 }
118 else
119 { 103 {
120 Messaging.Instance.OnMessage(WixErrors.DuplicateExtensionXmlSchemaNamespace(extension.GetType().ToString(), extension.Namespace.NamespaceName, collidingExtension.GetType().ToString())); 104 this.Context.CompilationId = target.Id;
121 } 105 }
122 106
123 //if (null != extension.InspectorExtension) 107 var extensionsByNamespace = new Dictionary<XNamespace, ICompilerExtension>();
124 //{
125 // this.inspectorExtensions.Add(extension.InspectorExtension);
126 //}
127 }
128 108
129 /// <summary> 109 foreach (var extension in this.Context.Extensions)
130 /// Adds table definitions from an extension
131 /// </summary>
132 /// <param name="extension">Extension with table definitions.</param>
133 public void AddExtensionData(IExtensionData extension)
134 {
135 if (null != extension.TableDefinitions)
136 { 110 {
137 foreach (TableDefinition tableDefinition in extension.TableDefinitions) 111 if (!extensionsByNamespace.TryGetValue(extension.Namespace, out var collidingExtension))
138 { 112 {
139 if (!this.tableDefinitions.Contains(tableDefinition.Name)) 113 extensionsByNamespace.Add(extension.Namespace, extension);
140 { 114 }
141 this.tableDefinitions.Add(tableDefinition); 115 else
142 } 116 {
143 else 117 Messaging.Instance.OnMessage(WixErrors.DuplicateExtensionXmlSchemaNamespace(extension.GetType().ToString(), extension.Namespace.NamespaceName, collidingExtension.GetType().ToString()));
144 {
145 Messaging.Instance.OnMessage(WixErrors.DuplicateExtensionTable(extension.GetType().ToString(), tableDefinition.Name));
146 }
147 } 118 }
148 }
149 }
150
151 /// <summary>
152 /// Compiles the provided Xml document into an intermediate object
153 /// </summary>
154 /// <param name="source">Source xml document to compile. The BaseURI property
155 /// should be properly set to get messages containing source line information.</param>
156 /// <returns>Intermediate object representing compiled source document.</returns>
157 /// <remarks>This method is not thread-safe.</remarks>
158 [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")]
159 public Intermediate Compile(XDocument source)
160 {
161 if (null == source) throw new ArgumentNullException(nameof(source));
162
163 bool encounteredError = false;
164 119
165 // create the intermediate 120 extension.PreCompile(context);
166 Intermediate target = new Intermediate(); 121 }
167 122
168 // try to compile it 123 // Try to compile it.
169 try 124 try
170 { 125 {
171 this.core = new CompilerCore(target, this.tableDefinitions, this.extensions); 126 var creator = context.ServiceProvider.GetService<ITupleDefinitionCreator>();
172 this.core.ShowPedanticMessages = this.showPedanticMessages;
173 this.core.CurrentPlatform = this.CurrentPlatform;
174 this.componentIdPlaceholdersResolver = new WixVariableResolver();
175 127
176 foreach (CompilerExtension extension in this.extensions.Values) 128 this.Core = new CompilerCore(target, creator, extensionsByNamespace);
177 { 129 this.Core.CurrentPlatform = this.Context.Platform;
178 extension.Core = this.core; 130 this.Core.ShowPedanticMessages = this.ShowPedanticMessages;
179 extension.Initialize(); 131 this.componentIdPlaceholdersResolver = new WixVariableResolver();
180 }
181 132
182 // parse the document 133 // parse the document
134 var source = context.Source;
183 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(source.Root); 135 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(source.Root);
184 if ("Wix" == source.Root.Name.LocalName) 136 if ("Wix" == source.Root.Name.LocalName)
185 { 137 {
@@ -191,17 +143,17 @@ namespace WixToolset
191 { 143 {
192 if (String.IsNullOrEmpty(source.Root.Name.NamespaceName)) 144 if (String.IsNullOrEmpty(source.Root.Name.NamespaceName))
193 { 145 {
194 this.core.OnMessage(WixErrors.InvalidWixXmlNamespace(sourceLineNumbers, "Wix", CompilerCore.WixNamespace.ToString())); 146 this.Core.OnMessage(WixErrors.InvalidWixXmlNamespace(sourceLineNumbers, "Wix", CompilerCore.WixNamespace.ToString()));
195 } 147 }
196 else 148 else
197 { 149 {
198 this.core.OnMessage(WixErrors.InvalidWixXmlNamespace(sourceLineNumbers, "Wix", source.Root.Name.NamespaceName, CompilerCore.WixNamespace.ToString())); 150 this.Core.OnMessage(WixErrors.InvalidWixXmlNamespace(sourceLineNumbers, "Wix", source.Root.Name.NamespaceName, CompilerCore.WixNamespace.ToString()));
199 } 151 }
200 } 152 }
201 } 153 }
202 else 154 else
203 { 155 {
204 this.core.OnMessage(WixErrors.InvalidDocumentElement(sourceLineNumbers, source.Root.Name.LocalName, "source", "Wix")); 156 this.Core.OnMessage(WixErrors.InvalidDocumentElement(sourceLineNumbers, source.Root.Name.LocalName, "source", "Wix"));
205 } 157 }
206 158
207 // Resolve any Component Id placeholders compiled into the intermediate. 159 // Resolve any Component Id placeholders compiled into the intermediate.
@@ -209,55 +161,38 @@ namespace WixToolset
209 { 161 {
210 foreach (var section in target.Sections) 162 foreach (var section in target.Sections)
211 { 163 {
212 foreach (Table table in section.Tables) 164 foreach (var tuple in section.Tuples)
213 { 165 {
214 foreach (Row row in table.Rows) 166 foreach (var field in tuple.Fields)
215 { 167 {
216 foreach (Field field in row.Fields) 168 if (field != null && field.Type == IntermediateFieldType.String)
217 { 169 {
218 if (field.Data is string) 170 var data = field.AsString();
171 if (!String.IsNullOrEmpty(data))
219 { 172 {
220 field.Data = this.componentIdPlaceholdersResolver.ResolveVariables(row.SourceLineNumbers, (string)field.Data, false, false, out var defaultIgnored, out var delayedIgnored); 173 var resolved = this.componentIdPlaceholdersResolver.ResolveVariables(tuple.SourceLineNumbers, data, false, false, out var defaultIgnored, out var delayedIgnored);
174 if (data != resolved)
175 {
176 field.Set(resolved);
177 }
221 } 178 }
222 } 179 }
223 } 180 }
224 } 181 }
225 } 182 }
226 } 183 }
227
228 // inspect the document
229 InspectorCore inspectorCore = new InspectorCore();
230 foreach (InspectorExtension inspectorExtension in this.inspectorExtensions)
231 {
232 inspectorExtension.Core = inspectorCore;
233 inspectorExtension.InspectIntermediate(target);
234
235 // reset
236 inspectorExtension.Core = null;
237 }
238
239 if (inspectorCore.EncounteredError)
240 {
241 encounteredError = true;
242 }
243 } 184 }
244 finally 185 finally
245 { 186 {
246 if (this.core.EncounteredError) 187 foreach (var extension in context.Extensions)
247 { 188 {
248 encounteredError = true; 189 extension.PostCompile(target);
249 } 190 }
250 191
251 foreach (CompilerExtension extension in this.extensions.Values) 192 this.Core = null;
252 {
253 extension.Finish();
254 extension.Core = null;
255 }
256 this.core = null;
257 } 193 }
258 194
259 // return the compiled intermediate only if it completed successfully 195 return Messaging.Instance.EncounteredError ? null : target;
260 return (encounteredError ? null : target);
261 } 196 }
262 197
263 /// <summary> 198 /// <summary>
@@ -299,7 +234,7 @@ namespace WixToolset
299 } 234 }
300 else 235 else
301 { 236 {
302 if (this.core.IsValidShortFilename(longName, false)) 237 if (this.Core.IsValidShortFilename(longName, false))
303 { 238 {
304 return longName; 239 return longName;
305 } 240 }
@@ -318,15 +253,15 @@ namespace WixToolset
318 /// <param name="signature">Signature for search.</param> 253 /// <param name="signature">Signature for search.</param>
319 private void AddAppSearch(SourceLineNumber sourceLineNumbers, Identifier property, string signature) 254 private void AddAppSearch(SourceLineNumber sourceLineNumbers, Identifier property, string signature)
320 { 255 {
321 if (!this.core.EncounteredError) 256 if (!this.Core.EncounteredError)
322 { 257 {
323 if (property.Id != property.Id.ToUpperInvariant()) 258 if (property.Id != property.Id.ToUpperInvariant())
324 { 259 {
325 this.core.OnMessage(WixErrors.SearchPropertyNotUppercase(sourceLineNumbers, "Property", "Id", property.Id)); 260 this.Core.OnMessage(WixErrors.SearchPropertyNotUppercase(sourceLineNumbers, "Property", "Id", property.Id));
326 } 261 }
327 262
328 Row row = this.core.CreateRow(sourceLineNumbers, "AppSearch", property); 263 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.AppSearch, property);
329 row[1] = signature; 264 row.Set(1, signature);
330 } 265 }
331 } 266 }
332 267
@@ -358,33 +293,33 @@ namespace WixToolset
358 Group group = match.Groups["identifier"]; 293 Group group = match.Groups["identifier"];
359 if (group.Success) 294 if (group.Success)
360 { 295 {
361 this.core.OnMessage(WixWarnings.PropertyValueContainsPropertyReference(sourceLineNumbers, property.Id, group.Value)); 296 this.Core.OnMessage(WixWarnings.PropertyValueContainsPropertyReference(sourceLineNumbers, property.Id, group.Value));
362 } 297 }
363 } 298 }
364 } 299 }
365 300
366 if (!this.core.EncounteredError) 301 if (!this.Core.EncounteredError)
367 { 302 {
368 Section section = this.core.ActiveSection; 303 var section = this.Core.ActiveSection;
369 304
370 // Add the row to a separate section if requested. 305 // Add the row to a separate section if requested.
371 if (fragment) 306 if (fragment)
372 { 307 {
373 string id = String.Concat(this.core.ActiveSection.Id, ".", property.Id); 308 string id = String.Concat(this.Core.ActiveSection.Id, ".", property.Id);
374 309
375 section = this.core.CreateSection(id, SectionType.Fragment, this.core.ActiveSection.Codepage); 310 section = this.Core.CreateSection(id, SectionType.Fragment, this.Core.ActiveSection.Codepage, this.Context.CompilationId);
376 311
377 // Reference the property in the active section. 312 // Reference the property in the active section.
378 this.core.CreateSimpleReference(sourceLineNumbers, "Property", property.Id); 313 this.Core.CreateSimpleReference(sourceLineNumbers, "Property", property.Id);
379 } 314 }
380 315
381 Row row = this.core.CreateRow(sourceLineNumbers, "Property", section, property); 316 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Property, section, property);
382 317
383 // Allow row to exist with no value so that PropertyRefs can be made for *Search elements 318 // Allow row to exist with no value so that PropertyRefs can be made for *Search elements
384 // the linker will remove these rows before the final output is created. 319 // the linker will remove these rows before the final output is created.
385 if (null != value) 320 if (null != value)
386 { 321 {
387 row[1] = value; 322 row.Set(1, value);
388 } 323 }
389 324
390 if (admin || hidden || secure) 325 if (admin || hidden || secure)
@@ -394,26 +329,24 @@ namespace WixToolset
394 } 329 }
395 } 330 }
396 331
397 private WixPropertyRow AddWixPropertyRow(SourceLineNumber sourceLineNumbers, Identifier property, bool admin, bool secure, bool hidden, Section section = null) 332 private void AddWixPropertyRow(SourceLineNumber sourceLineNumbers, Identifier property, bool admin, bool secure, bool hidden, IntermediateSection section = null)
398 { 333 {
399 if (secure && property.Id != property.Id.ToUpperInvariant()) 334 if (secure && property.Id != property.Id.ToUpperInvariant())
400 { 335 {
401 this.core.OnMessage(WixErrors.SecurePropertyNotUppercase(sourceLineNumbers, "Property", "Id", property.Id)); 336 this.Core.OnMessage(WixErrors.SecurePropertyNotUppercase(sourceLineNumbers, "Property", "Id", property.Id));
402 } 337 }
403 338
404 if (null == section) 339 if (null == section)
405 { 340 {
406 section = this.core.ActiveSection; 341 section = this.Core.ActiveSection;
407 342
408 this.core.EnsureTable(sourceLineNumbers, "Property"); // Property table is always required when using WixProperty table. 343 this.Core.EnsureTable(sourceLineNumbers, "Property"); // Property table is always required when using WixProperty table.
409 } 344 }
410 345
411 WixPropertyRow row = (WixPropertyRow)this.core.CreateRow(sourceLineNumbers, "WixProperty", section, property); 346 var row = (WixPropertyTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixProperty, section, property);
412 row.Admin = admin; 347 row.Admin = admin;
413 row.Hidden = hidden; 348 row.Hidden = hidden;
414 row.Secure = secure; 349 row.Secure = secure;
415
416 return row;
417 } 350 }
418 351
419 /// <summary> 352 /// <summary>
@@ -425,7 +358,7 @@ namespace WixToolset
425 /// <param name="componentId">Identifier of parent component.</param> 358 /// <param name="componentId">Identifier of parent component.</param>
426 private void RegisterImplementedCategories(SourceLineNumber sourceLineNumbers, string categoryId, string classId, string componentId) 359 private void RegisterImplementedCategories(SourceLineNumber sourceLineNumbers, string categoryId, string classId, string componentId)
427 { 360 {
428 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\Implemented Categories\\", categoryId), "*", null, componentId); 361 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\Implemented Categories\\", categoryId), "*", null, componentId);
429 } 362 }
430 363
431 /// <summary> 364 /// <summary>
@@ -457,51 +390,51 @@ namespace WixToolset
457 switch (attrib.Name.LocalName) 390 switch (attrib.Name.LocalName)
458 { 391 {
459 case "Id": 392 case "Id":
460 appId = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 393 appId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
461 break; 394 break;
462 case "ActivateAtStorage": 395 case "ActivateAtStorage":
463 activateAtStorage = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 396 activateAtStorage = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
464 break; 397 break;
465 case "Advertise": 398 case "Advertise":
466 appIdAdvertise = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 399 appIdAdvertise = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
467 break; 400 break;
468 case "Description": 401 case "Description":
469 description = this.core.GetAttributeValue(sourceLineNumbers, attrib); 402 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
470 break; 403 break;
471 case "DllSurrogate": 404 case "DllSurrogate":
472 dllSurrogate = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 405 dllSurrogate = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
473 break; 406 break;
474 case "LocalService": 407 case "LocalService":
475 localService = this.core.GetAttributeValue(sourceLineNumbers, attrib); 408 localService = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
476 break; 409 break;
477 case "RemoteServerName": 410 case "RemoteServerName":
478 remoteServerName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 411 remoteServerName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
479 break; 412 break;
480 case "RunAsInteractiveUser": 413 case "RunAsInteractiveUser":
481 runAsInteractiveUser = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 414 runAsInteractiveUser = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
482 break; 415 break;
483 case "ServiceParameters": 416 case "ServiceParameters":
484 serviceParameters = this.core.GetAttributeValue(sourceLineNumbers, attrib); 417 serviceParameters = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
485 break; 418 break;
486 default: 419 default:
487 this.core.UnexpectedAttribute(node, attrib); 420 this.Core.UnexpectedAttribute(node, attrib);
488 break; 421 break;
489 } 422 }
490 } 423 }
491 else 424 else
492 { 425 {
493 this.core.ParseExtensionAttribute(node, attrib); 426 this.Core.ParseExtensionAttribute(node, attrib);
494 } 427 }
495 } 428 }
496 429
497 if (null == appId) 430 if (null == appId)
498 { 431 {
499 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 432 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
500 } 433 }
501 434
502 if ((YesNoType.No == advertise && YesNoType.Yes == appIdAdvertise) || (YesNoType.Yes == advertise && YesNoType.No == appIdAdvertise)) 435 if ((YesNoType.No == advertise && YesNoType.Yes == appIdAdvertise) || (YesNoType.Yes == advertise && YesNoType.No == appIdAdvertise))
503 { 436 {
504 this.core.OnMessage(WixErrors.AppIdIncompatibleAdvertiseState(sourceLineNumbers, node.Name.LocalName, "Advertise", appIdAdvertise.ToString(), advertise.ToString())); 437 this.Core.OnMessage(WixErrors.AppIdIncompatibleAdvertiseState(sourceLineNumbers, node.Name.LocalName, "Advertise", appIdAdvertise.ToString(), advertise.ToString()));
505 } 438 }
506 else 439 else
507 { 440 {
@@ -524,13 +457,13 @@ namespace WixToolset
524 this.ParseClassElement(child, componentId, advertise, fileServer, typeLibId, typeLibVersion, appId); 457 this.ParseClassElement(child, componentId, advertise, fileServer, typeLibId, typeLibVersion, appId);
525 break; 458 break;
526 default: 459 default:
527 this.core.UnexpectedElement(node, child); 460 this.Core.UnexpectedElement(node, child);
528 break; 461 break;
529 } 462 }
530 } 463 }
531 else 464 else
532 { 465 {
533 this.core.ParseExtensionElement(node, child); 466 this.Core.ParseExtensionElement(node, child);
534 } 467 }
535 } 468 }
536 469
@@ -538,25 +471,25 @@ namespace WixToolset
538 { 471 {
539 if (null != description) 472 if (null != description)
540 { 473 {
541 this.core.OnMessage(WixErrors.IllegalAttributeWhenAdvertised(sourceLineNumbers, node.Name.LocalName, "Description")); 474 this.Core.OnMessage(WixErrors.IllegalAttributeWhenAdvertised(sourceLineNumbers, node.Name.LocalName, "Description"));
542 } 475 }
543 476
544 if (!this.core.EncounteredError) 477 if (!this.Core.EncounteredError)
545 { 478 {
546 Row row = this.core.CreateRow(sourceLineNumbers, "AppId"); 479 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.AppId);
547 row[0] = appId; 480 row.Set(0, appId);
548 row[1] = remoteServerName; 481 row.Set(1, remoteServerName);
549 row[2] = localService; 482 row.Set(2, localService);
550 row[3] = serviceParameters; 483 row.Set(3, serviceParameters);
551 row[4] = dllSurrogate; 484 row.Set(4, dllSurrogate);
552 if (YesNoType.Yes == activateAtStorage) 485 if (YesNoType.Yes == activateAtStorage)
553 { 486 {
554 row[5] = 1; 487 row.Set(5, 1);
555 } 488 }
556 489
557 if (YesNoType.Yes == runAsInteractiveUser) 490 if (YesNoType.Yes == runAsInteractiveUser)
558 { 491 {
559 row[6] = 1; 492 row.Set(6, 1);
560 } 493 }
561 } 494 }
562 } 495 }
@@ -564,41 +497,41 @@ namespace WixToolset
564 { 497 {
565 if (null != description) 498 if (null != description)
566 { 499 {
567 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), null, description, componentId); 500 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), null, description, componentId);
568 } 501 }
569 else 502 else
570 { 503 {
571 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "+", null, componentId); 504 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "+", null, componentId);
572 } 505 }
573 506
574 if (null != remoteServerName) 507 if (null != remoteServerName)
575 { 508 {
576 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "RemoteServerName", remoteServerName, componentId); 509 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "RemoteServerName", remoteServerName, componentId);
577 } 510 }
578 511
579 if (null != localService) 512 if (null != localService)
580 { 513 {
581 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "LocalService", localService, componentId); 514 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "LocalService", localService, componentId);
582 } 515 }
583 516
584 if (null != serviceParameters) 517 if (null != serviceParameters)
585 { 518 {
586 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "ServiceParameters", serviceParameters, componentId); 519 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "ServiceParameters", serviceParameters, componentId);
587 } 520 }
588 521
589 if (null != dllSurrogate) 522 if (null != dllSurrogate)
590 { 523 {
591 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "DllSurrogate", dllSurrogate, componentId); 524 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "DllSurrogate", dllSurrogate, componentId);
592 } 525 }
593 526
594 if (YesNoType.Yes == activateAtStorage) 527 if (YesNoType.Yes == activateAtStorage)
595 { 528 {
596 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "ActivateAtStorage", "Y", componentId); 529 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "ActivateAtStorage", "Y", componentId);
597 } 530 }
598 531
599 if (YesNoType.Yes == runAsInteractiveUser) 532 if (YesNoType.Yes == runAsInteractiveUser)
600 { 533 {
601 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "RunAs", "Interactive User", componentId); 534 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("AppID\\", appId), "RunAs", "Interactive User", componentId);
602 } 535 }
603 } 536 }
604 } 537 }
@@ -621,35 +554,35 @@ namespace WixToolset
621 switch (attrib.Name.LocalName) 554 switch (attrib.Name.LocalName)
622 { 555 {
623 case "Id": 556 case "Id":
624 id = this.core.GetAttributeValue(sourceLineNumbers, attrib); 557 id = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
625 break; 558 break;
626 case "Value": 559 case "Value":
627 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 560 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
628 break; 561 break;
629 default: 562 default:
630 this.core.UnexpectedAttribute(node, attrib); 563 this.Core.UnexpectedAttribute(node, attrib);
631 break; 564 break;
632 } 565 }
633 } 566 }
634 else 567 else
635 { 568 {
636 this.core.ParseExtensionAttribute(node, attrib); 569 this.Core.ParseExtensionAttribute(node, attrib);
637 } 570 }
638 } 571 }
639 572
640 if (null == id) 573 if (null == id)
641 { 574 {
642 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 575 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
643 } 576 }
644 577
645 this.core.ParseForExtensionElements(node); 578 this.Core.ParseForExtensionElements(node);
646 579
647 if (!this.core.EncounteredError) 580 if (!this.Core.EncounteredError)
648 { 581 {
649 Row row = this.core.CreateRow(sourceLineNumbers, "MsiAssemblyName"); 582 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiAssemblyName);
650 row[0] = componentId; 583 row.Set(0, componentId);
651 row[1] = id; 584 row.Set(1, id);
652 row[2] = value; 585 row.Set(2, value);
653 } 586 }
654 } 587 }
655 588
@@ -673,71 +606,71 @@ namespace WixToolset
673 switch (attrib.Name.LocalName) 606 switch (attrib.Name.LocalName)
674 { 607 {
675 case "Id": 608 case "Id":
676 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 609 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
677 break; 610 break;
678 case "SourceFile": 611 case "SourceFile":
679 case "src": 612 case "src":
680 if (null != sourceFile) 613 if (null != sourceFile)
681 { 614 {
682 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile", "src")); 615 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile", "src"));
683 } 616 }
684 617
685 if ("src" == attrib.Name.LocalName) 618 if ("src" == attrib.Name.LocalName)
686 { 619 {
687 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourceFile")); 620 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourceFile"));
688 } 621 }
689 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 622 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
690 break; 623 break;
691 case "SuppressModularization": 624 case "SuppressModularization":
692 suppressModularization = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 625 suppressModularization = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
693 break; 626 break;
694 default: 627 default:
695 this.core.UnexpectedAttribute(node, attrib); 628 this.Core.UnexpectedAttribute(node, attrib);
696 break; 629 break;
697 } 630 }
698 } 631 }
699 else 632 else
700 { 633 {
701 this.core.ParseExtensionAttribute(node, attrib); 634 this.Core.ParseExtensionAttribute(node, attrib);
702 } 635 }
703 } 636 }
704 637
705 if (null == id) 638 if (null == id)
706 { 639 {
707 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 640 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
708 id = Identifier.Invalid; 641 id = Identifier.Invalid;
709 } 642 }
710 else if (!String.IsNullOrEmpty(id.Id)) // only check legal values 643 else if (!String.IsNullOrEmpty(id.Id)) // only check legal values
711 { 644 {
712 if (55 < id.Id.Length) 645 if (55 < id.Id.Length)
713 { 646 {
714 this.core.OnMessage(WixErrors.StreamNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, id.Id.Length, 55)); 647 this.Core.OnMessage(WixErrors.StreamNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, id.Id.Length, 55));
715 } 648 }
716 else if (!this.compilingProduct) // if we're not doing a product then we can't be sure that a binary identifier will fit when modularized 649 else if (!this.compilingProduct) // if we're not doing a product then we can't be sure that a binary identifier will fit when modularized
717 { 650 {
718 if (18 < id.Id.Length) 651 if (18 < id.Id.Length)
719 { 652 {
720 this.core.OnMessage(WixWarnings.IdentifierCannotBeModularized(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, id.Id.Length, 18)); 653 this.Core.OnMessage(WixWarnings.IdentifierCannotBeModularized(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, id.Id.Length, 18));
721 } 654 }
722 } 655 }
723 } 656 }
724 657
725 if (null == sourceFile) 658 if (null == sourceFile)
726 { 659 {
727 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); 660 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
728 } 661 }
729 662
730 this.core.ParseForExtensionElements(node); 663 this.Core.ParseForExtensionElements(node);
731 664
732 if (!this.core.EncounteredError) 665 if (!this.Core.EncounteredError)
733 { 666 {
734 Row row = this.core.CreateRow(sourceLineNumbers, "Binary", id); 667 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Binary, id);
735 row[1] = sourceFile; 668 row.Set(1, sourceFile);
736 669
737 if (YesNoType.Yes == suppressModularization) 670 if (YesNoType.Yes == suppressModularization)
738 { 671 {
739 Row wixSuppressModularizationRow = this.core.CreateRow(sourceLineNumbers, "WixSuppressModularization"); 672 var wixSuppressModularizationRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSuppressModularization);
740 wixSuppressModularizationRow[0] = id; 673 wixSuppressModularizationRow.Set(0, id);
741 } 674 }
742 } 675 }
743 676
@@ -762,53 +695,53 @@ namespace WixToolset
762 switch (attrib.Name.LocalName) 695 switch (attrib.Name.LocalName)
763 { 696 {
764 case "Id": 697 case "Id":
765 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 698 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
766 break; 699 break;
767 case "SourceFile": 700 case "SourceFile":
768 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 701 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
769 break; 702 break;
770 default: 703 default:
771 this.core.UnexpectedAttribute(node, attrib); 704 this.Core.UnexpectedAttribute(node, attrib);
772 break; 705 break;
773 } 706 }
774 } 707 }
775 else 708 else
776 { 709 {
777 this.core.ParseExtensionAttribute(node, attrib); 710 this.Core.ParseExtensionAttribute(node, attrib);
778 } 711 }
779 } 712 }
780 713
781 if (null == id) 714 if (null == id)
782 { 715 {
783 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 716 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
784 id = Identifier.Invalid; 717 id = Identifier.Invalid;
785 } 718 }
786 else if (!String.IsNullOrEmpty(id.Id)) // only check legal values 719 else if (!String.IsNullOrEmpty(id.Id)) // only check legal values
787 { 720 {
788 if (57 < id.Id.Length) 721 if (57 < id.Id.Length)
789 { 722 {
790 this.core.OnMessage(WixErrors.StreamNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, id.Id.Length, 57)); 723 this.Core.OnMessage(WixErrors.StreamNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, id.Id.Length, 57));
791 } 724 }
792 else if (!this.compilingProduct) // if we're not doing a product then we can't be sure that a binary identifier will fit when modularized 725 else if (!this.compilingProduct) // if we're not doing a product then we can't be sure that a binary identifier will fit when modularized
793 { 726 {
794 if (20 < id.Id.Length) 727 if (20 < id.Id.Length)
795 { 728 {
796 this.core.OnMessage(WixWarnings.IdentifierCannotBeModularized(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, id.Id.Length, 20)); 729 this.Core.OnMessage(WixWarnings.IdentifierCannotBeModularized(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, id.Id.Length, 20));
797 } 730 }
798 } 731 }
799 } 732 }
800 733
801 if (null == sourceFile) 734 if (null == sourceFile)
802 { 735 {
803 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); 736 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
804 } 737 }
805 738
806 this.core.ParseForExtensionElements(node); 739 this.Core.ParseForExtensionElements(node);
807 740
808 if (!this.core.EncounteredError) 741 if (!this.Core.EncounteredError)
809 { 742 {
810 Row row = this.core.CreateRow(sourceLineNumbers, "Icon", id); 743 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Icon, id);
811 row[1] = sourceFile; 744 row.Set(1, sourceFile);
812 } 745 }
813 746
814 return id.Id; 747 return id.Id;
@@ -830,23 +763,23 @@ namespace WixToolset
830 switch (attrib.Name.LocalName) 763 switch (attrib.Name.LocalName)
831 { 764 {
832 case "Property": 765 case "Property":
833 property = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 766 property = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
834 this.core.CreateSimpleReference(sourceLineNumbers, "Property", property); 767 this.Core.CreateSimpleReference(sourceLineNumbers, "Property", property);
835 break; 768 break;
836 default: 769 default:
837 this.core.UnexpectedAttribute(node, attrib); 770 this.Core.UnexpectedAttribute(node, attrib);
838 break; 771 break;
839 } 772 }
840 } 773 }
841 else 774 else
842 { 775 {
843 this.core.ParseExtensionAttribute(node, attrib); 776 this.Core.ParseExtensionAttribute(node, attrib);
844 } 777 }
845 } 778 }
846 779
847 if (null == property) 780 if (null == property)
848 { 781 {
849 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property")); 782 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property"));
850 } 783 }
851 784
852 // find unexpected child elements 785 // find unexpected child elements
@@ -860,13 +793,13 @@ namespace WixToolset
860 ParseInstanceElement(child, property); 793 ParseInstanceElement(child, property);
861 break; 794 break;
862 default: 795 default:
863 this.core.UnexpectedElement(node, child); 796 this.Core.UnexpectedElement(node, child);
864 break; 797 break;
865 } 798 }
866 } 799 }
867 else 800 else
868 { 801 {
869 this.core.ParseExtensionElement(node, child); 802 this.Core.ParseExtensionElement(node, child);
870 } 803 }
871 } 804 }
872 } 805 }
@@ -891,53 +824,53 @@ namespace WixToolset
891 switch (attrib.Name.LocalName) 824 switch (attrib.Name.LocalName)
892 { 825 {
893 case "Id": 826 case "Id":
894 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 827 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
895 break; 828 break;
896 case "ProductCode": 829 case "ProductCode":
897 productCode = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, true); 830 productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true);
898 break; 831 break;
899 case "ProductName": 832 case "ProductName":
900 productName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 833 productName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
901 break; 834 break;
902 case "UpgradeCode": 835 case "UpgradeCode":
903 upgradeCode = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 836 upgradeCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
904 break; 837 break;
905 default: 838 default:
906 this.core.UnexpectedAttribute(node, attrib); 839 this.Core.UnexpectedAttribute(node, attrib);
907 break; 840 break;
908 } 841 }
909 } 842 }
910 else 843 else
911 { 844 {
912 this.core.ParseExtensionAttribute(node, attrib); 845 this.Core.ParseExtensionAttribute(node, attrib);
913 } 846 }
914 } 847 }
915 848
916 if (null == id) 849 if (null == id)
917 { 850 {
918 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 851 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
919 } 852 }
920 853
921 if (null == productCode) 854 if (null == productCode)
922 { 855 {
923 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ProductCode")); 856 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ProductCode"));
924 } 857 }
925 858
926 this.core.ParseForExtensionElements(node); 859 this.Core.ParseForExtensionElements(node);
927 860
928 if (!this.core.EncounteredError) 861 if (!this.Core.EncounteredError)
929 { 862 {
930 Row row = this.core.CreateRow(sourceLineNumbers, "WixInstanceTransforms"); 863 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixInstanceTransforms);
931 row[0] = id; 864 row.Set(0, id);
932 row[1] = propertyId; 865 row.Set(1, propertyId);
933 row[2] = productCode; 866 row.Set(2, productCode);
934 if (null != productName) 867 if (null != productName)
935 { 868 {
936 row[3] = productName; 869 row.Set(3, productName);
937 } 870 }
938 if (null != upgradeCode) 871 if (null != upgradeCode)
939 { 872 {
940 row[4] = upgradeCode; 873 row.Set(4, upgradeCode);
941 } 874 }
942 } 875 }
943 } 876 }
@@ -962,55 +895,55 @@ namespace WixToolset
962 switch (attrib.Name.LocalName) 895 switch (attrib.Name.LocalName)
963 { 896 {
964 case "Id": 897 case "Id":
965 id = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 898 id = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
966 break; 899 break;
967 case "AppData": 900 case "AppData":
968 appData = this.core.GetAttributeValue(sourceLineNumbers, attrib); 901 appData = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
969 break; 902 break;
970 case "Feature": 903 case "Feature":
971 feature = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 904 feature = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
972 this.core.CreateSimpleReference(sourceLineNumbers, "Feature", feature); 905 this.Core.CreateSimpleReference(sourceLineNumbers, "Feature", feature);
973 break; 906 break;
974 case "Qualifier": 907 case "Qualifier":
975 qualifier = this.core.GetAttributeValue(sourceLineNumbers, attrib); 908 qualifier = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
976 break; 909 break;
977 default: 910 default:
978 this.core.UnexpectedAttribute(node, attrib); 911 this.Core.UnexpectedAttribute(node, attrib);
979 break; 912 break;
980 } 913 }
981 } 914 }
982 else 915 else
983 { 916 {
984 this.core.ParseExtensionAttribute(node, attrib); 917 this.Core.ParseExtensionAttribute(node, attrib);
985 } 918 }
986 } 919 }
987 920
988 if (null == id) 921 if (null == id)
989 { 922 {
990 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 923 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
991 } 924 }
992 925
993 if (null == qualifier) 926 if (null == qualifier)
994 { 927 {
995 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Qualifier")); 928 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Qualifier"));
996 } 929 }
997 930
998 this.core.ParseForExtensionElements(node); 931 this.Core.ParseForExtensionElements(node);
999 932
1000 if (!this.core.EncounteredError) 933 if (!this.Core.EncounteredError)
1001 { 934 {
1002 Row row = this.core.CreateRow(sourceLineNumbers, "PublishComponent"); 935 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PublishComponent);
1003 row[0] = id; 936 row.Set(0, id);
1004 row[1] = qualifier; 937 row.Set(1, qualifier);
1005 row[2] = componentId; 938 row.Set(2, componentId);
1006 row[3] = appData; 939 row.Set(3, appData);
1007 if (null == feature) 940 if (null == feature)
1008 { 941 {
1009 row[4] = Guid.Empty.ToString("B"); 942 row.Set(4, Guid.Empty.ToString("B"));
1010 } 943 }
1011 else 944 else
1012 { 945 {
1013 row[4] = feature; 946 row.Set(4, feature);
1014 } 947 }
1015 } 948 }
1016 } 949 }
@@ -1062,81 +995,81 @@ namespace WixToolset
1062 switch (attrib.Name.LocalName) 995 switch (attrib.Name.LocalName)
1063 { 996 {
1064 case "Id": 997 case "Id":
1065 classId = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 998 classId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
1066 break; 999 break;
1067 case "Advertise": 1000 case "Advertise":
1068 classAdvertise = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 1001 classAdvertise = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1069 break; 1002 break;
1070 case "AppId": 1003 case "AppId":
1071 appId = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 1004 appId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
1072 break; 1005 break;
1073 case "Argument": 1006 case "Argument":
1074 argument = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1007 argument = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1075 break; 1008 break;
1076 case "Context": 1009 case "Context":
1077 contexts = this.core.GetAttributeValue(sourceLineNumbers, attrib).Split("\r\n\t ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 1010 contexts = this.Core.GetAttributeValue(sourceLineNumbers, attrib).Split("\r\n\t ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
1078 break; 1011 break;
1079 case "Control": 1012 case "Control":
1080 control = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 1013 control = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1081 break; 1014 break;
1082 case "Description": 1015 case "Description":
1083 description = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1016 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1084 break; 1017 break;
1085 case "Handler": 1018 case "Handler":
1086 defaultInprocHandler = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1019 defaultInprocHandler = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1087 break; 1020 break;
1088 case "Icon": 1021 case "Icon":
1089 icon = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 1022 icon = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1090 break; 1023 break;
1091 case "IconIndex": 1024 case "IconIndex":
1092 iconIndex = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, short.MinValue + 1, short.MaxValue); 1025 iconIndex = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, short.MinValue + 1, short.MaxValue);
1093 break; 1026 break;
1094 case "RelativePath": 1027 case "RelativePath":
1095 relativePath = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 1028 relativePath = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1096 break; 1029 break;
1097 1030
1098 // The following attributes result in rows always added to the Registry table rather than the Class table 1031 // The following attributes result in rows always added to the Registry table rather than the Class table
1099 case "Insertable": 1032 case "Insertable":
1100 insertable = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? "Insertable" : "NotInsertable"; 1033 insertable = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? "Insertable" : "NotInsertable";
1101 break; 1034 break;
1102 case "Programmable": 1035 case "Programmable":
1103 programmable = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 1036 programmable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1104 break; 1037 break;
1105 case "SafeForInitializing": 1038 case "SafeForInitializing":
1106 safeForInit = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 1039 safeForInit = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1107 break; 1040 break;
1108 case "SafeForScripting": 1041 case "SafeForScripting":
1109 safeForScripting = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 1042 safeForScripting = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1110 break; 1043 break;
1111 case "ForeignServer": 1044 case "ForeignServer":
1112 foreignServer = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1045 foreignServer = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1113 break; 1046 break;
1114 case "Server": 1047 case "Server":
1115 localFileServer = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1048 localFileServer = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1116 break; 1049 break;
1117 case "ShortPath": 1050 case "ShortPath":
1118 shortServerPath = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 1051 shortServerPath = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1119 break; 1052 break;
1120 case "ThreadingModel": 1053 case "ThreadingModel":
1121 threadingModel = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1054 threadingModel = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1122 break; 1055 break;
1123 case "Version": 1056 case "Version":
1124 version = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1057 version = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1125 break; 1058 break;
1126 default: 1059 default:
1127 this.core.UnexpectedAttribute(node, attrib); 1060 this.Core.UnexpectedAttribute(node, attrib);
1128 break; 1061 break;
1129 } 1062 }
1130 } 1063 }
1131 else 1064 else
1132 { 1065 {
1133 this.core.ParseExtensionAttribute(node, attrib); 1066 this.Core.ParseExtensionAttribute(node, attrib);
1134 } 1067 }
1135 } 1068 }
1136 1069
1137 if (null == classId) 1070 if (null == classId)
1138 { 1071 {
1139 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 1072 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
1140 } 1073 }
1141 1074
1142 HashSet<string> uniqueContexts = new HashSet<string>(); 1075 HashSet<string> uniqueContexts = new HashSet<string>();
@@ -1144,7 +1077,7 @@ namespace WixToolset
1144 { 1077 {
1145 if (uniqueContexts.Contains(context)) 1078 if (uniqueContexts.Contains(context))
1146 { 1079 {
1147 this.core.OnMessage(WixErrors.DuplicateContextValue(sourceLineNumbers, context)); 1080 this.Core.OnMessage(WixErrors.DuplicateContextValue(sourceLineNumbers, context));
1148 } 1081 }
1149 else 1082 else
1150 { 1083 {
@@ -1163,7 +1096,7 @@ namespace WixToolset
1163 1096
1164 if ((YesNoType.No == advertise && YesNoType.Yes == classAdvertise) || (YesNoType.Yes == advertise && YesNoType.No == classAdvertise)) 1097 if ((YesNoType.No == advertise && YesNoType.Yes == classAdvertise) || (YesNoType.Yes == advertise && YesNoType.No == classAdvertise))
1165 { 1098 {
1166 this.core.OnMessage(WixErrors.AdvertiseStateMustMatch(sourceLineNumbers, classAdvertise.ToString(), advertise.ToString())); 1099 this.Core.OnMessage(WixErrors.AdvertiseStateMustMatch(sourceLineNumbers, classAdvertise.ToString(), advertise.ToString()));
1167 } 1100 }
1168 else 1101 else
1169 { 1102 {
@@ -1178,17 +1111,17 @@ namespace WixToolset
1178 1111
1179 if (YesNoType.Yes == advertise && 0 == contexts.Length) 1112 if (YesNoType.Yes == advertise && 0 == contexts.Length)
1180 { 1113 {
1181 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Context", "Advertise", "yes")); 1114 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Context", "Advertise", "yes"));
1182 } 1115 }
1183 1116
1184 if (!String.IsNullOrEmpty(parentAppId) && !String.IsNullOrEmpty(appId)) 1117 if (!String.IsNullOrEmpty(parentAppId) && !String.IsNullOrEmpty(appId))
1185 { 1118 {
1186 this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "AppId", node.Parent.Name.LocalName)); 1119 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "AppId", node.Parent.Name.LocalName));
1187 } 1120 }
1188 1121
1189 if (!String.IsNullOrEmpty(localFileServer)) 1122 if (!String.IsNullOrEmpty(localFileServer))
1190 { 1123 {
1191 this.core.CreateSimpleReference(sourceLineNumbers, "File", localFileServer); 1124 this.Core.CreateSimpleReference(sourceLineNumbers, "File", localFileServer);
1192 } 1125 }
1193 1126
1194 // Local variables used strictly for child node processing. 1127 // Local variables used strictly for child node processing.
@@ -1209,7 +1142,7 @@ namespace WixToolset
1209 else if (YesNoType.No == advertise) 1142 else if (YesNoType.No == advertise)
1210 { 1143 {
1211 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); 1144 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
1212 this.core.CreateRegistryRow(childSourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("FileType\\", classId, "\\", fileTypeMaskIndex.ToString()), String.Empty, this.ParseFileTypeMaskElement(child), componentId); 1145 this.Core.CreateRegistryRow(childSourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("FileType\\", classId, "\\", fileTypeMaskIndex.ToString()), String.Empty, this.ParseFileTypeMaskElement(child), componentId);
1213 fileTypeMaskIndex++; 1146 fileTypeMaskIndex++;
1214 } 1147 }
1215 break; 1148 break;
@@ -1228,13 +1161,13 @@ namespace WixToolset
1228 } 1161 }
1229 break; 1162 break;
1230 default: 1163 default:
1231 this.core.UnexpectedElement(node, child); 1164 this.Core.UnexpectedElement(node, child);
1232 break; 1165 break;
1233 } 1166 }
1234 } 1167 }
1235 else 1168 else
1236 { 1169 {
1237 this.core.ParseExtensionElement(node, child); 1170 this.Core.ParseExtensionElement(node, child);
1238 } 1171 }
1239 } 1172 }
1240 1173
@@ -1243,12 +1176,12 @@ namespace WixToolset
1243 { 1176 {
1244 if (null != fileServer || null != localFileServer) 1177 if (null != fileServer || null != localFileServer)
1245 { 1178 {
1246 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Server", "Advertise", "yes")); 1179 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Server", "Advertise", "yes"));
1247 } 1180 }
1248 1181
1249 if (null != foreignServer) 1182 if (null != foreignServer)
1250 { 1183 {
1251 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "ForeignServer", "Advertise", "yes")); 1184 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "ForeignServer", "Advertise", "yes"));
1252 } 1185 }
1253 1186
1254 if (null == appId && null != parentAppId) 1187 if (null == appId && null != parentAppId)
@@ -1257,37 +1190,37 @@ namespace WixToolset
1257 } 1190 }
1258 1191
1259 // add a Class row for each context 1192 // add a Class row for each context
1260 if (!this.core.EncounteredError) 1193 if (!this.Core.EncounteredError)
1261 { 1194 {
1262 foreach (string context in contexts) 1195 foreach (string context in contexts)
1263 { 1196 {
1264 Row row = this.core.CreateRow(sourceLineNumbers, "Class"); 1197 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Class);
1265 row[0] = classId; 1198 row.Set(0, classId);
1266 row[1] = context; 1199 row.Set(1, context);
1267 row[2] = componentId; 1200 row.Set(2, componentId);
1268 row[3] = defaultProgId; 1201 row.Set(3, defaultProgId);
1269 row[4] = description; 1202 row.Set(4, description);
1270 if (null != appId) 1203 if (null != appId)
1271 { 1204 {
1272 row[5] = appId; 1205 row.Set(5, appId);
1273 this.core.CreateSimpleReference(sourceLineNumbers, "AppId", appId); 1206 this.Core.CreateSimpleReference(sourceLineNumbers, "AppId", appId);
1274 } 1207 }
1275 row[6] = fileTypeMask; 1208 row.Set(6, fileTypeMask);
1276 if (null != icon) 1209 if (null != icon)
1277 { 1210 {
1278 row[7] = icon; 1211 row.Set(7, icon);
1279 this.core.CreateSimpleReference(sourceLineNumbers, "Icon", icon); 1212 this.Core.CreateSimpleReference(sourceLineNumbers, "Icon", icon);
1280 } 1213 }
1281 if (CompilerConstants.IntegerNotSet != iconIndex) 1214 if (CompilerConstants.IntegerNotSet != iconIndex)
1282 { 1215 {
1283 row[8] = iconIndex; 1216 row.Set(8, iconIndex);
1284 } 1217 }
1285 row[9] = defaultInprocHandler; 1218 row.Set(9, defaultInprocHandler);
1286 row[10] = argument; 1219 row.Set(10, argument);
1287 row[11] = Guid.Empty.ToString("B"); 1220 row.Set(11, Guid.Empty.ToString("B"));
1288 if (YesNoType.Yes == relativePath) 1221 if (YesNoType.Yes == relativePath)
1289 { 1222 {
1290 row[12] = MsiInterop.MsidbClassAttributesRelativePath; 1223 row.Set(12, MsiInterop.MsidbClassAttributesRelativePath);
1291 } 1224 }
1292 } 1225 }
1293 } 1226 }
@@ -1296,16 +1229,16 @@ namespace WixToolset
1296 { 1229 {
1297 if (null == fileServer && null == localFileServer && null == foreignServer) 1230 if (null == fileServer && null == localFileServer && null == foreignServer)
1298 { 1231 {
1299 this.core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "ForeignServer", "Server")); 1232 this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "ForeignServer", "Server"));
1300 } 1233 }
1301 1234
1302 if (null != fileServer && null != foreignServer) 1235 if (null != fileServer && null != foreignServer)
1303 { 1236 {
1304 this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "ForeignServer", "File")); 1237 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "ForeignServer", "File"));
1305 } 1238 }
1306 else if (null != localFileServer && null != foreignServer) 1239 else if (null != localFileServer && null != foreignServer)
1307 { 1240 {
1308 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "ForeignServer", "Server")); 1241 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "ForeignServer", "Server"));
1309 } 1242 }
1310 else if (null == fileServer) 1243 else if (null == fileServer)
1311 { 1244 {
@@ -1314,7 +1247,7 @@ namespace WixToolset
1314 1247
1315 if (null != appId) // need to use nesting (not a reference) for the unadvertised Class elements 1248 if (null != appId) // need to use nesting (not a reference) for the unadvertised Class elements
1316 { 1249 {
1317 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "AppId", "Advertise", "no")); 1250 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "AppId", "Advertise", "no"));
1318 } 1251 }
1319 1252
1320 // add the core registry keys for each context in the class 1253 // add the core registry keys for each context in the class
@@ -1324,7 +1257,7 @@ namespace WixToolset
1324 { 1257 {
1325 if (null != argument) 1258 if (null != argument)
1326 { 1259 {
1327 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Arguments", "Context", context)); 1260 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Arguments", "Context", context));
1328 } 1261 }
1329 1262
1330 if (null != fileServer) 1263 if (null != fileServer)
@@ -1361,14 +1294,14 @@ namespace WixToolset
1361 } 1294 }
1362 else 1295 else
1363 { 1296 {
1364 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Context", context, "InprocServer", "InprocServer32", "LocalServer", "LocalServer32")); 1297 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Context", context, "InprocServer", "InprocServer32", "LocalServer", "LocalServer32"));
1365 } 1298 }
1366 1299
1367 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\", context), String.Empty, formattedContextString, componentId); // ClassId context 1300 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\", context), String.Empty, formattedContextString, componentId); // ClassId context
1368 1301
1369 if (null != icon) // ClassId default icon 1302 if (null != icon) // ClassId default icon
1370 { 1303 {
1371 this.core.CreateSimpleReference(sourceLineNumbers, "File", icon); 1304 this.Core.CreateSimpleReference(sourceLineNumbers, "File", icon);
1372 1305
1373 icon = String.Format(CultureInfo.InvariantCulture, "\"[#{0}]\"", icon); 1306 icon = String.Format(CultureInfo.InvariantCulture, "\"[#{0}]\"", icon);
1374 1307
@@ -1376,18 +1309,18 @@ namespace WixToolset
1376 { 1309 {
1377 icon = String.Concat(icon, ",", iconIndex); 1310 icon = String.Concat(icon, ",", iconIndex);
1378 } 1311 }
1379 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\", context, "\\DefaultIcon"), String.Empty, icon, componentId); 1312 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\", context, "\\DefaultIcon"), String.Empty, icon, componentId);
1380 } 1313 }
1381 } 1314 }
1382 1315
1383 if (null != parentAppId) // ClassId AppId (must be specified via nesting, not with the AppId attribute) 1316 if (null != parentAppId) // ClassId AppId (must be specified via nesting, not with the AppId attribute)
1384 { 1317 {
1385 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId), "AppID", parentAppId, componentId); 1318 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId), "AppID", parentAppId, componentId);
1386 } 1319 }
1387 1320
1388 if (null != description) // ClassId description 1321 if (null != description) // ClassId description
1389 { 1322 {
1390 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId), String.Empty, description, componentId); 1323 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId), String.Empty, description, componentId);
1391 } 1324 }
1392 1325
1393 if (null != defaultInprocHandler) 1326 if (null != defaultInprocHandler)
@@ -1395,24 +1328,24 @@ namespace WixToolset
1395 switch (defaultInprocHandler) // ClassId Default Inproc Handler 1328 switch (defaultInprocHandler) // ClassId Default Inproc Handler
1396 { 1329 {
1397 case "1": 1330 case "1":
1398 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler"), String.Empty, "ole.dll", componentId); 1331 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler"), String.Empty, "ole.dll", componentId);
1399 break; 1332 break;
1400 case "2": 1333 case "2":
1401 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, "ole32.dll", componentId); 1334 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, "ole32.dll", componentId);
1402 break; 1335 break;
1403 case "3": 1336 case "3":
1404 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler"), String.Empty, "ole.dll", componentId); 1337 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler"), String.Empty, "ole.dll", componentId);
1405 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, "ole32.dll", componentId); 1338 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, "ole32.dll", componentId);
1406 break; 1339 break;
1407 default: 1340 default:
1408 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, defaultInprocHandler, componentId); 1341 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\InprocHandler32"), String.Empty, defaultInprocHandler, componentId);
1409 break; 1342 break;
1410 } 1343 }
1411 } 1344 }
1412 1345
1413 if (YesNoType.NotSet != relativePath) // ClassId's RelativePath 1346 if (YesNoType.NotSet != relativePath) // ClassId's RelativePath
1414 { 1347 {
1415 this.core.OnMessage(WixErrors.RelativePathForRegistryElement(sourceLineNumbers)); 1348 this.Core.OnMessage(WixErrors.RelativePathForRegistryElement(sourceLineNumbers));
1416 } 1349 }
1417 } 1350 }
1418 1351
@@ -1423,36 +1356,36 @@ namespace WixToolset
1423 // add a threading model for each context in the class 1356 // add a threading model for each context in the class
1424 foreach (string context in contexts) 1357 foreach (string context in contexts)
1425 { 1358 {
1426 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\", context), "ThreadingModel", threadingModel, componentId); 1359 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\", context), "ThreadingModel", threadingModel, componentId);
1427 } 1360 }
1428 } 1361 }
1429 1362
1430 if (null != typeLibId) 1363 if (null != typeLibId)
1431 { 1364 {
1432 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\TypeLib"), null, typeLibId, componentId); 1365 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\TypeLib"), null, typeLibId, componentId);
1433 } 1366 }
1434 1367
1435 if (null != version) 1368 if (null != version)
1436 { 1369 {
1437 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\Version"), null, version, componentId); 1370 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\Version"), null, version, componentId);
1438 } 1371 }
1439 1372
1440 if (null != insertable) 1373 if (null != insertable)
1441 { 1374 {
1442 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall. 1375 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall.
1443 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\", insertable), "*", null, componentId); 1376 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\", insertable), "*", null, componentId);
1444 } 1377 }
1445 1378
1446 if (control) 1379 if (control)
1447 { 1380 {
1448 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall. 1381 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall.
1449 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\Control"), "*", null, componentId); 1382 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\Control"), "*", null, componentId);
1450 } 1383 }
1451 1384
1452 if (programmable) 1385 if (programmable)
1453 { 1386 {
1454 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall. 1387 // Add "*" for name so that any subkeys (shouldn't be any) are removed on uninstall.
1455 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\Programmable"), "*", null, componentId); 1388 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\Programmable"), "*", null, componentId);
1456 } 1389 }
1457 1390
1458 if (safeForInit) 1391 if (safeForInit)
@@ -1491,77 +1424,77 @@ namespace WixToolset
1491 switch (attrib.Name.LocalName) 1424 switch (attrib.Name.LocalName)
1492 { 1425 {
1493 case "Id": 1426 case "Id":
1494 interfaceId = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 1427 interfaceId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
1495 break; 1428 break;
1496 case "BaseInterface": 1429 case "BaseInterface":
1497 baseInterface = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 1430 baseInterface = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
1498 break; 1431 break;
1499 case "Name": 1432 case "Name":
1500 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1433 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1501 break; 1434 break;
1502 case "NumMethods": 1435 case "NumMethods":
1503 numMethods = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 1436 numMethods = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
1504 break; 1437 break;
1505 case "ProxyStubClassId": 1438 case "ProxyStubClassId":
1506 proxyId = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1439 proxyId = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1507 break; 1440 break;
1508 case "ProxyStubClassId32": 1441 case "ProxyStubClassId32":
1509 proxyId32 = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 1442 proxyId32 = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
1510 break; 1443 break;
1511 case "Versioned": 1444 case "Versioned":
1512 versioned = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 1445 versioned = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1513 break; 1446 break;
1514 default: 1447 default:
1515 this.core.UnexpectedAttribute(node, attrib); 1448 this.Core.UnexpectedAttribute(node, attrib);
1516 break; 1449 break;
1517 } 1450 }
1518 } 1451 }
1519 else 1452 else
1520 { 1453 {
1521 this.core.ParseExtensionAttribute(node, attrib); 1454 this.Core.ParseExtensionAttribute(node, attrib);
1522 } 1455 }
1523 } 1456 }
1524 1457
1525 if (null == interfaceId) 1458 if (null == interfaceId)
1526 { 1459 {
1527 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 1460 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
1528 } 1461 }
1529 1462
1530 if (null == name) 1463 if (null == name)
1531 { 1464 {
1532 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 1465 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
1533 } 1466 }
1534 1467
1535 this.core.ParseForExtensionElements(node); 1468 this.Core.ParseForExtensionElements(node);
1536 1469
1537 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId), null, name, componentId); 1470 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId), null, name, componentId);
1538 if (null != typeLibId) 1471 if (null != typeLibId)
1539 { 1472 {
1540 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\TypeLib"), null, typeLibId, componentId); 1473 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\TypeLib"), null, typeLibId, componentId);
1541 if (versioned) 1474 if (versioned)
1542 { 1475 {
1543 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\TypeLib"), "Version", typelibVersion, componentId); 1476 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\TypeLib"), "Version", typelibVersion, componentId);
1544 } 1477 }
1545 } 1478 }
1546 1479
1547 if (null != baseInterface) 1480 if (null != baseInterface)
1548 { 1481 {
1549 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\BaseInterface"), null, baseInterface, componentId); 1482 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\BaseInterface"), null, baseInterface, componentId);
1550 } 1483 }
1551 1484
1552 if (CompilerConstants.IntegerNotSet != numMethods) 1485 if (CompilerConstants.IntegerNotSet != numMethods)
1553 { 1486 {
1554 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\NumMethods"), null, numMethods.ToString(), componentId); 1487 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\NumMethods"), null, numMethods.ToString(), componentId);
1555 } 1488 }
1556 1489
1557 if (null != proxyId) 1490 if (null != proxyId)
1558 { 1491 {
1559 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\ProxyStubClsid"), null, proxyId, componentId); 1492 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\ProxyStubClsid"), null, proxyId, componentId);
1560 } 1493 }
1561 1494
1562 if (null != proxyId32) 1495 if (null != proxyId32)
1563 { 1496 {
1564 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\ProxyStubClsid32"), null, proxyId32, componentId); 1497 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("Interface\\", interfaceId, "\\ProxyStubClsid32"), null, proxyId32, componentId);
1565 } 1498 }
1566 } 1499 }
1567 1500
@@ -1585,48 +1518,48 @@ namespace WixToolset
1585 switch (attrib.Name.LocalName) 1518 switch (attrib.Name.LocalName)
1586 { 1519 {
1587 case "Mask": 1520 case "Mask":
1588 mask = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1521 mask = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1589 break; 1522 break;
1590 case "Offset": 1523 case "Offset":
1591 offset = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 1524 offset = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
1592 break; 1525 break;
1593 case "Value": 1526 case "Value":
1594 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1527 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1595 break; 1528 break;
1596 default: 1529 default:
1597 this.core.UnexpectedAttribute(node, attrib); 1530 this.Core.UnexpectedAttribute(node, attrib);
1598 break; 1531 break;
1599 } 1532 }
1600 } 1533 }
1601 else 1534 else
1602 { 1535 {
1603 this.core.ParseExtensionAttribute(node, attrib); 1536 this.Core.ParseExtensionAttribute(node, attrib);
1604 } 1537 }
1605 } 1538 }
1606 1539
1607 1540
1608 if (null == mask) 1541 if (null == mask)
1609 { 1542 {
1610 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Mask")); 1543 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Mask"));
1611 } 1544 }
1612 1545
1613 if (CompilerConstants.IntegerNotSet == offset) 1546 if (CompilerConstants.IntegerNotSet == offset)
1614 { 1547 {
1615 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Offset")); 1548 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Offset"));
1616 } 1549 }
1617 1550
1618 if (null == value) 1551 if (null == value)
1619 { 1552 {
1620 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 1553 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
1621 } 1554 }
1622 1555
1623 this.core.ParseForExtensionElements(node); 1556 this.Core.ParseForExtensionElements(node);
1624 1557
1625 if (!this.core.EncounteredError) 1558 if (!this.Core.EncounteredError)
1626 { 1559 {
1627 if (mask.Length != value.Length) 1560 if (mask.Length != value.Length)
1628 { 1561 {
1629 this.core.OnMessage(WixErrors.ValueAndMaskMustBeSameLength(sourceLineNumbers)); 1562 this.Core.OnMessage(WixErrors.ValueAndMaskMustBeSameLength(sourceLineNumbers));
1630 } 1563 }
1631 cb = mask.Length / 2; 1564 cb = mask.Length / 2;
1632 } 1565 }
@@ -1656,62 +1589,62 @@ namespace WixToolset
1656 switch (attrib.Name.LocalName) 1589 switch (attrib.Name.LocalName)
1657 { 1590 {
1658 case "ExcludeLanguages": 1591 case "ExcludeLanguages":
1659 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 1592 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1660 { 1593 {
1661 options |= MsiInterop.MsidbUpgradeAttributesLanguagesExclusive; 1594 options |= MsiInterop.MsidbUpgradeAttributesLanguagesExclusive;
1662 } 1595 }
1663 break; 1596 break;
1664 case "IncludeMaximum": 1597 case "IncludeMaximum":
1665 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 1598 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1666 { 1599 {
1667 options |= MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive; 1600 options |= MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive;
1668 } 1601 }
1669 break; 1602 break;
1670 case "IncludeMinimum": // this is "yes" by default 1603 case "IncludeMinimum": // this is "yes" by default
1671 if (YesNoType.No == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 1604 if (YesNoType.No == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1672 { 1605 {
1673 options &= ~MsiInterop.MsidbUpgradeAttributesVersionMinInclusive; 1606 options &= ~MsiInterop.MsidbUpgradeAttributesVersionMinInclusive;
1674 } 1607 }
1675 break; 1608 break;
1676 case "Language": 1609 case "Language":
1677 language = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1610 language = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1678 break; 1611 break;
1679 case "Minimum": 1612 case "Minimum":
1680 minimum = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1613 minimum = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1681 break; 1614 break;
1682 case "Maximum": 1615 case "Maximum":
1683 maximum = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1616 maximum = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1684 break; 1617 break;
1685 case "UpgradeCode": 1618 case "UpgradeCode":
1686 upgradeCode = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 1619 upgradeCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
1687 break; 1620 break;
1688 default: 1621 default:
1689 this.core.UnexpectedAttribute(node, attrib); 1622 this.Core.UnexpectedAttribute(node, attrib);
1690 break; 1623 break;
1691 } 1624 }
1692 } 1625 }
1693 else 1626 else
1694 { 1627 {
1695 this.core.ParseExtensionAttribute(node, attrib); 1628 this.Core.ParseExtensionAttribute(node, attrib);
1696 } 1629 }
1697 } 1630 }
1698 1631
1699 if (null == minimum && null == maximum) 1632 if (null == minimum && null == maximum)
1700 { 1633 {
1701 this.core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "Minimum", "Maximum")); 1634 this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "Minimum", "Maximum"));
1702 } 1635 }
1703 1636
1704 this.core.ParseForExtensionElements(node); 1637 this.Core.ParseForExtensionElements(node);
1705 1638
1706 if (!this.core.EncounteredError) 1639 if (!this.Core.EncounteredError)
1707 { 1640 {
1708 Row row = this.core.CreateRow(sourceLineNumbers, "Upgrade"); 1641 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Upgrade);
1709 row[0] = upgradeCode; 1642 row.Set(0, upgradeCode);
1710 row[1] = minimum; 1643 row.Set(1, minimum);
1711 row[2] = maximum; 1644 row.Set(2, maximum);
1712 row[3] = language; 1645 row.Set(3, language);
1713 row[4] = options; 1646 row.Set(4, options);
1714 row[6] = propertyId; 1647 row.Set(6, propertyId);
1715 } 1648 }
1716 } 1649 }
1717 1650
@@ -1739,19 +1672,19 @@ namespace WixToolset
1739 switch (attrib.Name.LocalName) 1672 switch (attrib.Name.LocalName)
1740 { 1673 {
1741 case "Id": 1674 case "Id":
1742 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 1675 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
1743 break; 1676 break;
1744 case "Key": 1677 case "Key":
1745 key = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1678 key = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1746 break; 1679 break;
1747 case "Name": 1680 case "Name":
1748 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1681 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1749 break; 1682 break;
1750 case "Root": 1683 case "Root":
1751 root = this.core.GetAttributeMsidbRegistryRootValue(sourceLineNumbers, attrib, false); 1684 root = this.Core.GetAttributeMsidbRegistryRootValue(sourceLineNumbers, attrib, false);
1752 break; 1685 break;
1753 case "Type": 1686 case "Type":
1754 string typeValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 1687 string typeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1755 if (0 < typeValue.Length) 1688 if (0 < typeValue.Length)
1756 { 1689 {
1757 Wix.RegistrySearch.TypeType typeType = Wix.RegistrySearch.ParseTypeType(typeValue); 1690 Wix.RegistrySearch.TypeType typeType = Wix.RegistrySearch.ParseTypeType(typeValue);
@@ -1767,23 +1700,23 @@ namespace WixToolset
1767 type = 2; 1700 type = 2;
1768 break; 1701 break;
1769 default: 1702 default:
1770 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Type", typeValue, "directory", "file", "raw")); 1703 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Type", typeValue, "directory", "file", "raw"));
1771 break; 1704 break;
1772 } 1705 }
1773 } 1706 }
1774 break; 1707 break;
1775 case "Win64": 1708 case "Win64":
1776 explicitWin64 = true; 1709 explicitWin64 = true;
1777 search64bit = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 1710 search64bit = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1778 break; 1711 break;
1779 default: 1712 default:
1780 this.core.UnexpectedAttribute(node, attrib); 1713 this.Core.UnexpectedAttribute(node, attrib);
1781 break; 1714 break;
1782 } 1715 }
1783 } 1716 }
1784 else 1717 else
1785 { 1718 {
1786 this.core.ParseExtensionAttribute(node, attrib); 1719 this.Core.ParseExtensionAttribute(node, attrib);
1787 } 1720 }
1788 } 1721 }
1789 1722
@@ -1794,22 +1727,22 @@ namespace WixToolset
1794 1727
1795 if (null == id) 1728 if (null == id)
1796 { 1729 {
1797 id = this.core.CreateIdentifier("reg", root.ToString(), key, name, type.ToString(), search64bit.ToString()); 1730 id = this.Core.CreateIdentifier("reg", root.ToString(), key, name, type.ToString(), search64bit.ToString());
1798 } 1731 }
1799 1732
1800 if (null == key) 1733 if (null == key)
1801 { 1734 {
1802 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); 1735 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
1803 } 1736 }
1804 1737
1805 if (CompilerConstants.IntegerNotSet == root) 1738 if (CompilerConstants.IntegerNotSet == root)
1806 { 1739 {
1807 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root")); 1740 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root"));
1808 } 1741 }
1809 1742
1810 if (CompilerConstants.IntegerNotSet == type) 1743 if (CompilerConstants.IntegerNotSet == type)
1811 { 1744 {
1812 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type")); 1745 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type"));
1813 } 1746 }
1814 1747
1815 signature = id.Id; 1748 signature = id.Id;
@@ -1823,7 +1756,7 @@ namespace WixToolset
1823 case "DirectorySearch": 1756 case "DirectorySearch":
1824 if (oneChild) 1757 if (oneChild)
1825 { 1758 {
1826 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 1759 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
1827 } 1760 }
1828 oneChild = true; 1761 oneChild = true;
1829 1762
@@ -1833,7 +1766,7 @@ namespace WixToolset
1833 case "DirectorySearchRef": 1766 case "DirectorySearchRef":
1834 if (oneChild) 1767 if (oneChild)
1835 { 1768 {
1836 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 1769 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
1837 } 1770 }
1838 oneChild = true; 1771 oneChild = true;
1839 signature = this.ParseDirectorySearchRefElement(child, id.Id); 1772 signature = this.ParseDirectorySearchRefElement(child, id.Id);
@@ -1841,7 +1774,7 @@ namespace WixToolset
1841 case "FileSearch": 1774 case "FileSearch":
1842 if (oneChild) 1775 if (oneChild)
1843 { 1776 {
1844 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 1777 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
1845 } 1778 }
1846 oneChild = true; 1779 oneChild = true;
1847 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet); 1780 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet);
@@ -1850,7 +1783,7 @@ namespace WixToolset
1850 case "FileSearchRef": 1783 case "FileSearchRef":
1851 if (oneChild) 1784 if (oneChild)
1852 { 1785 {
1853 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 1786 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
1854 } 1787 }
1855 oneChild = true; 1788 oneChild = true;
1856 string newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures 1789 string newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures
@@ -1858,24 +1791,24 @@ namespace WixToolset
1858 signature = null; 1791 signature = null;
1859 break; 1792 break;
1860 default: 1793 default:
1861 this.core.UnexpectedElement(node, child); 1794 this.Core.UnexpectedElement(node, child);
1862 break; 1795 break;
1863 } 1796 }
1864 } 1797 }
1865 else 1798 else
1866 { 1799 {
1867 this.core.ParseExtensionElement(node, child); 1800 this.Core.ParseExtensionElement(node, child);
1868 } 1801 }
1869 } 1802 }
1870 1803
1871 1804
1872 if (!this.core.EncounteredError) 1805 if (!this.Core.EncounteredError)
1873 { 1806 {
1874 Row row = this.core.CreateRow(sourceLineNumbers, "RegLocator", id); 1807 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RegLocator, id);
1875 row[1] = root; 1808 row.Set(1, root);
1876 row[2] = key; 1809 row.Set(2, key);
1877 row[3] = name; 1810 row.Set(3, name);
1878 row[4] = search64bit ? (type | 16) : type; 1811 row.Set(4, search64bit ? (type | 16) : type);
1879 } 1812 }
1880 1813
1881 return signature; 1814 return signature;
@@ -1898,26 +1831,26 @@ namespace WixToolset
1898 switch (attrib.Name.LocalName) 1831 switch (attrib.Name.LocalName)
1899 { 1832 {
1900 case "Id": 1833 case "Id":
1901 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 1834 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1902 this.core.CreateSimpleReference(sourceLineNumbers, "RegLocator", id); 1835 this.Core.CreateSimpleReference(sourceLineNumbers, "RegLocator", id);
1903 break; 1836 break;
1904 default: 1837 default:
1905 this.core.UnexpectedAttribute(node, attrib); 1838 this.Core.UnexpectedAttribute(node, attrib);
1906 break; 1839 break;
1907 } 1840 }
1908 } 1841 }
1909 else 1842 else
1910 { 1843 {
1911 this.core.ParseExtensionAttribute(node, attrib); 1844 this.Core.ParseExtensionAttribute(node, attrib);
1912 } 1845 }
1913 } 1846 }
1914 1847
1915 if (null == id) 1848 if (null == id)
1916 { 1849 {
1917 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 1850 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
1918 } 1851 }
1919 1852
1920 this.core.ParseForExtensionElements(node); 1853 this.Core.ParseForExtensionElements(node);
1921 1854
1922 return id; // the id of the RegistrySearchRef element is its signature 1855 return id; // the id of the RegistrySearchRef element is its signature
1923 } 1856 }
@@ -1963,13 +1896,13 @@ namespace WixToolset
1963 signature = this.ParseRegistrySearchRefElement(child); 1896 signature = this.ParseRegistrySearchRefElement(child);
1964 break; 1897 break;
1965 default: 1898 default:
1966 this.core.UnexpectedElement(node, child); 1899 this.Core.UnexpectedElement(node, child);
1967 break; 1900 break;
1968 } 1901 }
1969 } 1902 }
1970 else 1903 else
1971 { 1904 {
1972 this.core.ParseExtensionElement(node, child); 1905 this.Core.ParseExtensionElement(node, child);
1973 } 1906 }
1974 1907
1975 1908
@@ -2003,7 +1936,7 @@ namespace WixToolset
2003 case "DirectorySearch": 1936 case "DirectorySearch":
2004 if (oneChild) 1937 if (oneChild)
2005 { 1938 {
2006 this.core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName)); 1939 this.Core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName));
2007 } 1940 }
2008 oneChild = true; 1941 oneChild = true;
2009 signature = this.ParseDirectorySearchElement(child, "CCP_DRIVE"); 1942 signature = this.ParseDirectorySearchElement(child, "CCP_DRIVE");
@@ -2011,25 +1944,25 @@ namespace WixToolset
2011 case "DirectorySearchRef": 1944 case "DirectorySearchRef":
2012 if (oneChild) 1945 if (oneChild)
2013 { 1946 {
2014 this.core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName)); 1947 this.Core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName));
2015 } 1948 }
2016 oneChild = true; 1949 oneChild = true;
2017 signature = this.ParseDirectorySearchRefElement(child, "CCP_DRIVE"); 1950 signature = this.ParseDirectorySearchRefElement(child, "CCP_DRIVE");
2018 break; 1951 break;
2019 default: 1952 default:
2020 this.core.UnexpectedElement(node, child); 1953 this.Core.UnexpectedElement(node, child);
2021 break; 1954 break;
2022 } 1955 }
2023 } 1956 }
2024 else 1957 else
2025 { 1958 {
2026 this.core.ParseExtensionElement(node, child); 1959 this.Core.ParseExtensionElement(node, child);
2027 } 1960 }
2028 } 1961 }
2029 1962
2030 if (null == signature) 1963 if (null == signature)
2031 { 1964 {
2032 this.core.OnMessage(WixErrors.SearchElementRequired(sourceLineNumbers, node.Name.LocalName)); 1965 this.Core.OnMessage(WixErrors.SearchElementRequired(sourceLineNumbers, node.Name.LocalName));
2033 } 1966 }
2034 1967
2035 return signature; 1968 return signature;
@@ -2050,13 +1983,13 @@ namespace WixToolset
2050 switch (attrib.Name.LocalName) 1983 switch (attrib.Name.LocalName)
2051 { 1984 {
2052 default: 1985 default:
2053 this.core.UnexpectedAttribute(node, attrib); 1986 this.Core.UnexpectedAttribute(node, attrib);
2054 break; 1987 break;
2055 } 1988 }
2056 } 1989 }
2057 else 1990 else
2058 { 1991 {
2059 this.core.ParseExtensionAttribute(node, attrib); 1992 this.Core.ParseExtensionAttribute(node, attrib);
2060 } 1993 }
2061 } 1994 }
2062 1995
@@ -2075,19 +2008,19 @@ namespace WixToolset
2075 else if (signature != sig) 2008 else if (signature != sig)
2076 { 2009 {
2077 // all signatures under a ComplianceCheck must be the same 2010 // all signatures under a ComplianceCheck must be the same
2078 this.core.OnMessage(WixErrors.MultipleIdentifiersFound(sourceLineNumbers, node.Name.LocalName, sig, signature)); 2011 this.Core.OnMessage(WixErrors.MultipleIdentifiersFound(sourceLineNumbers, node.Name.LocalName, sig, signature));
2079 } 2012 }
2080 } 2013 }
2081 2014
2082 if (null == signature) 2015 if (null == signature)
2083 { 2016 {
2084 this.core.OnMessage(WixErrors.SearchElementRequired(sourceLineNumbers, node.Name.LocalName)); 2017 this.Core.OnMessage(WixErrors.SearchElementRequired(sourceLineNumbers, node.Name.LocalName));
2085 } 2018 }
2086 2019
2087 if (!this.core.EncounteredError) 2020 if (!this.Core.EncounteredError)
2088 { 2021 {
2089 Row row = this.core.CreateRow(sourceLineNumbers, "CCPSearch"); 2022 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CCPSearch);
2090 row[0] = signature; 2023 row.Set(0, signature);
2091 } 2024 }
2092 } 2025 }
2093 2026
@@ -2132,31 +2065,31 @@ namespace WixToolset
2132 switch (attrib.Name.LocalName) 2065 switch (attrib.Name.LocalName)
2133 { 2066 {
2134 case "Id": 2067 case "Id":
2135 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 2068 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
2136 break; 2069 break;
2137 case "ComPlusFlags": 2070 case "ComPlusFlags":
2138 comPlusBits = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 2071 comPlusBits = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
2139 break; 2072 break;
2140 case "DisableRegistryReflection": 2073 case "DisableRegistryReflection":
2141 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 2074 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2142 { 2075 {
2143 bits |= MsiInterop.MsidbComponentAttributesDisableRegistryReflection; 2076 bits |= MsiInterop.MsidbComponentAttributesDisableRegistryReflection;
2144 } 2077 }
2145 break; 2078 break;
2146 case "Directory": 2079 case "Directory":
2147 directoryId = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, directoryId); 2080 directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, directoryId);
2148 break; 2081 break;
2149 case "DiskId": 2082 case "DiskId":
2150 diskId = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); 2083 diskId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue);
2151 break; 2084 break;
2152 case "Feature": 2085 case "Feature":
2153 feature = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 2086 feature = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2154 break; 2087 break;
2155 case "Guid": 2088 case "Guid":
2156 guid = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, true, true); 2089 guid = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true, true);
2157 break; 2090 break;
2158 case "KeyPath": 2091 case "KeyPath":
2159 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 2092 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2160 { 2093 {
2161 keyFound = true; 2094 keyFound = true;
2162 keyPath = null; 2095 keyPath = null;
@@ -2165,7 +2098,7 @@ namespace WixToolset
2165 } 2098 }
2166 break; 2099 break;
2167 case "Location": 2100 case "Location":
2168 string location = this.core.GetAttributeValue(sourceLineNumbers, attrib); 2101 string location = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2169 if (0 < location.Length) 2102 if (0 < location.Length)
2170 { 2103 {
2171 Wix.Component.LocationType locationType = Wix.Component.ParseLocationType(location); 2104 Wix.Component.LocationType locationType = Wix.Component.ParseLocationType(location);
@@ -2180,66 +2113,66 @@ namespace WixToolset
2180 bits |= MsiInterop.MsidbComponentAttributesSourceOnly; 2113 bits |= MsiInterop.MsidbComponentAttributesSourceOnly;
2181 break; 2114 break;
2182 default: 2115 default:
2183 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "either", "local", "source")); 2116 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "either", "local", "source"));
2184 break; 2117 break;
2185 } 2118 }
2186 } 2119 }
2187 break; 2120 break;
2188 case "MultiInstance": 2121 case "MultiInstance":
2189 multiInstance = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2122 multiInstance = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2190 break; 2123 break;
2191 case "NeverOverwrite": 2124 case "NeverOverwrite":
2192 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 2125 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2193 { 2126 {
2194 bits |= MsiInterop.MsidbComponentAttributesNeverOverwrite; 2127 bits |= MsiInterop.MsidbComponentAttributesNeverOverwrite;
2195 } 2128 }
2196 break; 2129 break;
2197 case "Permanent": 2130 case "Permanent":
2198 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 2131 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2199 { 2132 {
2200 bits |= MsiInterop.MsidbComponentAttributesPermanent; 2133 bits |= MsiInterop.MsidbComponentAttributesPermanent;
2201 } 2134 }
2202 break; 2135 break;
2203 case "Shared": 2136 case "Shared":
2204 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 2137 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2205 { 2138 {
2206 bits |= MsiInterop.MsidbComponentAttributesShared; 2139 bits |= MsiInterop.MsidbComponentAttributesShared;
2207 } 2140 }
2208 break; 2141 break;
2209 case "SharedDllRefCount": 2142 case "SharedDllRefCount":
2210 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 2143 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2211 { 2144 {
2212 bits |= MsiInterop.MsidbComponentAttributesSharedDllRefCount; 2145 bits |= MsiInterop.MsidbComponentAttributesSharedDllRefCount;
2213 } 2146 }
2214 break; 2147 break;
2215 case "Transitive": 2148 case "Transitive":
2216 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 2149 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2217 { 2150 {
2218 bits |= MsiInterop.MsidbComponentAttributesTransitive; 2151 bits |= MsiInterop.MsidbComponentAttributesTransitive;
2219 } 2152 }
2220 break; 2153 break;
2221 case "UninstallWhenSuperseded": 2154 case "UninstallWhenSuperseded":
2222 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 2155 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2223 { 2156 {
2224 bits |= MsiInterop.MsidbComponentAttributesUninstallOnSupersedence; 2157 bits |= MsiInterop.MsidbComponentAttributesUninstallOnSupersedence;
2225 } 2158 }
2226 break; 2159 break;
2227 case "Win64": 2160 case "Win64":
2228 explicitWin64 = true; 2161 explicitWin64 = true;
2229 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 2162 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2230 { 2163 {
2231 bits |= MsiInterop.MsidbComponentAttributes64bit; 2164 bits |= MsiInterop.MsidbComponentAttributes64bit;
2232 win64 = true; 2165 win64 = true;
2233 } 2166 }
2234 break; 2167 break;
2235 default: 2168 default:
2236 this.core.UnexpectedAttribute(node, attrib); 2169 this.Core.UnexpectedAttribute(node, attrib);
2237 break; 2170 break;
2238 } 2171 }
2239 } 2172 }
2240 else 2173 else
2241 { 2174 {
2242 this.core.ParseExtensionAttribute(node, attrib); 2175 this.Core.ParseExtensionAttribute(node, attrib);
2243 } 2176 }
2244 } 2177 }
2245 2178
@@ -2251,34 +2184,34 @@ namespace WixToolset
2251 2184
2252 if (null == directoryId) 2185 if (null == directoryId)
2253 { 2186 {
2254 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Directory")); 2187 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Directory"));
2255 } 2188 }
2256 2189
2257 if (String.IsNullOrEmpty(guid) && MsiInterop.MsidbComponentAttributesShared == (bits & MsiInterop.MsidbComponentAttributesShared)) 2190 if (String.IsNullOrEmpty(guid) && MsiInterop.MsidbComponentAttributesShared == (bits & MsiInterop.MsidbComponentAttributesShared))
2258 { 2191 {
2259 this.core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Shared", "yes", "Guid", "")); 2192 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Shared", "yes", "Guid", ""));
2260 } 2193 }
2261 2194
2262 if (String.IsNullOrEmpty(guid) && MsiInterop.MsidbComponentAttributesPermanent == (bits & MsiInterop.MsidbComponentAttributesPermanent)) 2195 if (String.IsNullOrEmpty(guid) && MsiInterop.MsidbComponentAttributesPermanent == (bits & MsiInterop.MsidbComponentAttributesPermanent))
2263 { 2196 {
2264 this.core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Permanent", "yes", "Guid", "")); 2197 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Permanent", "yes", "Guid", ""));
2265 } 2198 }
2266 2199
2267 if (null != feature) 2200 if (null != feature)
2268 { 2201 {
2269 if (this.compilingModule) 2202 if (this.compilingModule)
2270 { 2203 {
2271 this.core.OnMessage(WixErrors.IllegalAttributeInMergeModule(sourceLineNumbers, node.Name.LocalName, "Feature")); 2204 this.Core.OnMessage(WixErrors.IllegalAttributeInMergeModule(sourceLineNumbers, node.Name.LocalName, "Feature"));
2272 } 2205 }
2273 else 2206 else
2274 { 2207 {
2275 if (ComplexReferenceParentType.Feature == parentType || ComplexReferenceParentType.FeatureGroup == parentType) 2208 if (ComplexReferenceParentType.Feature == parentType || ComplexReferenceParentType.FeatureGroup == parentType)
2276 { 2209 {
2277 this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "Feature", node.Parent.Name.LocalName)); 2210 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "Feature", node.Parent.Name.LocalName));
2278 } 2211 }
2279 else 2212 else
2280 { 2213 {
2281 this.core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Feature, feature, null, ComplexReferenceChildType.Component, id.Id, true); 2214 this.Core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Feature, feature, null, ComplexReferenceChildType.Component, id.Id, true);
2282 } 2215 }
2283 } 2216 }
2284 } 2217 }
@@ -2306,7 +2239,7 @@ namespace WixToolset
2306 if (null != condition) 2239 if (null != condition)
2307 { 2240 {
2308 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 2241 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2309 this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName)); 2242 this.Core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName));
2310 } 2243 }
2311 condition = this.ParseConditionElement(child, node.Name.LocalName, null, null); 2244 condition = this.ParseConditionElement(child, node.Name.LocalName, null, null);
2312 break; 2245 break;
@@ -2349,10 +2282,10 @@ namespace WixToolset
2349 encounteredODBCDataSource = true; 2282 encounteredODBCDataSource = true;
2350 break; 2283 break;
2351 case "ODBCDriver": 2284 case "ODBCDriver":
2352 this.ParseODBCDriverOrTranslator(child, id.Id, null, this.tableDefinitions["ODBCDriver"]); 2285 this.ParseODBCDriverOrTranslator(child, id.Id, null, TupleDefinitionType.ODBCDriver);
2353 break; 2286 break;
2354 case "ODBCTranslator": 2287 case "ODBCTranslator":
2355 this.ParseODBCDriverOrTranslator(child, id.Id, null, this.tableDefinitions["ODBCTranslator"]); 2288 this.ParseODBCDriverOrTranslator(child, id.Id, null, TupleDefinitionType.ODBCTranslator);
2356 break; 2289 break;
2357 case "ProgId": 2290 case "ProgId":
2358 bool foundExtension = false; 2291 bool foundExtension = false;
@@ -2403,14 +2336,14 @@ namespace WixToolset
2403 this.ParseTypeLibElement(child, id.Id, null, win64); 2336 this.ParseTypeLibElement(child, id.Id, null, win64);
2404 break; 2337 break;
2405 default: 2338 default:
2406 this.core.UnexpectedElement(node, child); 2339 this.Core.UnexpectedElement(node, child);
2407 break; 2340 break;
2408 } 2341 }
2409 } 2342 }
2410 else 2343 else
2411 { 2344 {
2412 Dictionary<string, string> context = new Dictionary<string, string>() { { "ComponentId", id.Id }, { "DirectoryId", directoryId }, { "Win64", win64.ToString() }, }; 2345 Dictionary<string, string> context = new Dictionary<string, string>() { { "ComponentId", id.Id }, { "DirectoryId", directoryId }, { "Win64", win64.ToString() }, };
2413 ComponentKeyPath possibleKeyPath = this.core.ParsePossibleKeyPathExtensionElement(node, child, context); 2346 ComponentKeyPath possibleKeyPath = this.Core.ParsePossibleKeyPathExtensionElement(node, child, context);
2414 if (null != possibleKeyPath) 2347 if (null != possibleKeyPath)
2415 { 2348 {
2416 if (ComponentKeyPathType.None == possibleKeyPath.Type) 2349 if (ComponentKeyPathType.None == possibleKeyPath.Type)
@@ -2439,7 +2372,7 @@ namespace WixToolset
2439 2372
2440 if (keyFound && YesNoType.Yes == keyPathSet) 2373 if (keyFound && YesNoType.Yes == keyPathSet)
2441 { 2374 {
2442 this.core.OnMessage(WixErrors.ComponentMultipleKeyPaths(sourceLineNumbers, node.Name.LocalName, "KeyPath", "yes", "File", "RegistryValue", "ODBCDataSource")); 2375 this.Core.OnMessage(WixErrors.ComponentMultipleKeyPaths(sourceLineNumbers, node.Name.LocalName, "KeyPath", "yes", "File", "RegistryValue", "ODBCDataSource"));
2443 } 2376 }
2444 2377
2445 // if a possible KeyPath has been found and that value was explicitly set as 2378 // if a possible KeyPath has been found and that value was explicitly set as
@@ -2457,9 +2390,9 @@ namespace WixToolset
2457 2390
2458 if (shouldAddCreateFolder) 2391 if (shouldAddCreateFolder)
2459 { 2392 {
2460 Row row = this.core.CreateRow(sourceLineNumbers, "CreateFolder"); 2393 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CreateFolder);
2461 row[0] = directoryId; 2394 row.Set(0, directoryId);
2462 row[1] = id.Id; 2395 row.Set(1, id.Id);
2463 } 2396 }
2464 2397
2465 // check for conditions that exclude this component from using generated guids 2398 // check for conditions that exclude this component from using generated guids
@@ -2468,21 +2401,21 @@ namespace WixToolset
2468 { 2401 {
2469 if (encounteredODBCDataSource) 2402 if (encounteredODBCDataSource)
2470 { 2403 {
2471 this.core.OnMessage(WixErrors.IllegalComponentWithAutoGeneratedGuid(sourceLineNumbers)); 2404 this.Core.OnMessage(WixErrors.IllegalComponentWithAutoGeneratedGuid(sourceLineNumbers));
2472 isGeneratableGuidOk = false; 2405 isGeneratableGuidOk = false;
2473 } 2406 }
2474 2407
2475 if (0 != files && MsiInterop.MsidbComponentAttributesRegistryKeyPath == keyBits) 2408 if (0 != files && MsiInterop.MsidbComponentAttributesRegistryKeyPath == keyBits)
2476 { 2409 {
2477 this.core.OnMessage(WixErrors.IllegalComponentWithAutoGeneratedGuid(sourceLineNumbers, true)); 2410 this.Core.OnMessage(WixErrors.IllegalComponentWithAutoGeneratedGuid(sourceLineNumbers, true));
2478 isGeneratableGuidOk = false; 2411 isGeneratableGuidOk = false;
2479 } 2412 }
2480 } 2413 }
2481 2414
2482 // check for implicit KeyPath which can easily be accidentally changed 2415 // check for implicit KeyPath which can easily be accidentally changed
2483 if (this.showPedanticMessages && !keyFound && !isGeneratableGuidOk) 2416 if (this.ShowPedanticMessages && !keyFound && !isGeneratableGuidOk)
2484 { 2417 {
2485 this.core.OnMessage(WixErrors.ImplicitComponentKeyPath(sourceLineNumbers, id.Id)); 2418 this.Core.OnMessage(WixErrors.ImplicitComponentKeyPath(sourceLineNumbers, id.Id));
2486 } 2419 }
2487 2420
2488 // if there isn't an @Id attribute value, replace the placeholder with the id of the keypath. 2421 // if there isn't an @Id attribute value, replace the placeholder with the id of the keypath.
@@ -2498,35 +2431,35 @@ namespace WixToolset
2498 } 2431 }
2499 else 2432 else
2500 { 2433 {
2501 this.core.OnMessage(WixErrors.CannotDefaultComponentId(sourceLineNumbers)); 2434 this.Core.OnMessage(WixErrors.CannotDefaultComponentId(sourceLineNumbers));
2502 } 2435 }
2503 } 2436 }
2504 2437
2505 // If an id was not determined by now, we have to error. 2438 // If an id was not determined by now, we have to error.
2506 if (null == id) 2439 if (null == id)
2507 { 2440 {
2508 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 2441 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
2509 } 2442 }
2510 2443
2511 // finally add the Component table row 2444 // finally add the Component table row
2512 if (!this.core.EncounteredError) 2445 if (!this.Core.EncounteredError)
2513 { 2446 {
2514 Row row = this.core.CreateRow(sourceLineNumbers, "Component", id); 2447 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Component, id);
2515 row[1] = guid; 2448 row.Set(1, guid);
2516 row[2] = directoryId; 2449 row.Set(2, directoryId);
2517 row[3] = bits | keyBits; 2450 row.Set(3, bits | keyBits);
2518 row[4] = condition; 2451 row.Set(4, condition);
2519 row[5] = keyPath; 2452 row.Set(5, keyPath);
2520 2453
2521 if (multiInstance) 2454 if (multiInstance)
2522 { 2455 {
2523 Row instanceComponentRow = this.core.CreateRow(sourceLineNumbers, "WixInstanceComponent"); 2456 var instanceComponentRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixInstanceComponent);
2524 instanceComponentRow[0] = id; 2457 instanceComponentRow.Set(0, id);
2525 } 2458 }
2526 2459
2527 if (0 < symbols.Count) 2460 if (0 < symbols.Count)
2528 { 2461 {
2529 WixDeltaPatchSymbolPathsRow symbolRow = (WixDeltaPatchSymbolPathsRow)this.core.CreateRow(sourceLineNumbers, "WixDeltaPatchSymbolPaths", id); 2462 var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths, id);
2530 symbolRow.Type = SymbolPathType.Component; 2463 symbolRow.Type = SymbolPathType.Component;
2531 symbolRow.SymbolPaths = String.Join(";", symbols); 2464 symbolRow.SymbolPaths = String.Join(";", symbols);
2532 } 2465 }
@@ -2534,20 +2467,20 @@ namespace WixToolset
2534 // Complus 2467 // Complus
2535 if (CompilerConstants.IntegerNotSet != comPlusBits) 2468 if (CompilerConstants.IntegerNotSet != comPlusBits)
2536 { 2469 {
2537 row = this.core.CreateRow(sourceLineNumbers, "Complus"); 2470 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Complus);
2538 row[0] = id; 2471 row.Set(0, id);
2539 row[1] = comPlusBits; 2472 row.Set(1, comPlusBits);
2540 } 2473 }
2541 2474
2542 // if this is a module, automatically add this component to the references to ensure it gets in the ModuleComponents table 2475 // if this is a module, automatically add this component to the references to ensure it gets in the ModuleComponents table
2543 if (this.compilingModule) 2476 if (this.compilingModule)
2544 { 2477 {
2545 this.core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Module, this.activeName, this.activeLanguage, ComplexReferenceChildType.Component, id.Id, false); 2478 this.Core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Module, this.activeName, this.activeLanguage, ComplexReferenceChildType.Component, id.Id, false);
2546 } 2479 }
2547 else if (ComplexReferenceParentType.Unknown != parentType && null != parentId) // if parent was provided, add a complex reference to that. 2480 else if (ComplexReferenceParentType.Unknown != parentType && null != parentId) // if parent was provided, add a complex reference to that.
2548 { 2481 {
2549 // If the Component is defined directly under a feature, then mark the complex reference primary. 2482 // If the Component is defined directly under a feature, then mark the complex reference primary.
2550 this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, parentLanguage, ComplexReferenceChildType.Component, id.Id, ComplexReferenceParentType.Feature == parentType); 2483 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, parentLanguage, ComplexReferenceChildType.Component, id.Id, ComplexReferenceParentType.Feature == parentType);
2551 } 2484 }
2552 } 2485 }
2553 } 2486 }
@@ -2571,30 +2504,30 @@ namespace WixToolset
2571 switch (attrib.Name.LocalName) 2504 switch (attrib.Name.LocalName)
2572 { 2505 {
2573 case "Id": 2506 case "Id":
2574 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 2507 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
2575 break; 2508 break;
2576 case "Directory": 2509 case "Directory":
2577 // If the inline syntax is invalid it returns null. Use a static error identifier so the null 2510 // If the inline syntax is invalid it returns null. Use a static error identifier so the null
2578 // directory identifier here doesn't trickle down false errors into child elements. 2511 // directory identifier here doesn't trickle down false errors into child elements.
2579 directoryId = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null) ?? "ErrorParsingInlineSyntax"; 2512 directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null) ?? "ErrorParsingInlineSyntax";
2580 break; 2513 break;
2581 case "Source": 2514 case "Source":
2582 source = this.core.GetAttributeValue(sourceLineNumbers, attrib); 2515 source = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2583 break; 2516 break;
2584 default: 2517 default:
2585 this.core.UnexpectedAttribute(node, attrib); 2518 this.Core.UnexpectedAttribute(node, attrib);
2586 break; 2519 break;
2587 } 2520 }
2588 } 2521 }
2589 else 2522 else
2590 { 2523 {
2591 this.core.ParseExtensionAttribute(node, attrib); 2524 this.Core.ParseExtensionAttribute(node, attrib);
2592 } 2525 }
2593 } 2526 }
2594 2527
2595 if (null == id) 2528 if (null == id)
2596 { 2529 {
2597 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 2530 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
2598 id = Identifier.Invalid; 2531 id = Identifier.Invalid;
2599 } 2532 }
2600 2533
@@ -2619,22 +2552,22 @@ namespace WixToolset
2619 this.ParseComponentElement(child, ComplexReferenceParentType.ComponentGroup, id.Id, null, CompilerConstants.IntegerNotSet, directoryId, source); 2552 this.ParseComponentElement(child, ComplexReferenceParentType.ComponentGroup, id.Id, null, CompilerConstants.IntegerNotSet, directoryId, source);
2620 break; 2553 break;
2621 default: 2554 default:
2622 this.core.UnexpectedElement(node, child); 2555 this.Core.UnexpectedElement(node, child);
2623 break; 2556 break;
2624 } 2557 }
2625 } 2558 }
2626 else 2559 else
2627 { 2560 {
2628 this.core.ParseExtensionElement(node, child); 2561 this.Core.ParseExtensionElement(node, child);
2629 } 2562 }
2630 } 2563 }
2631 2564
2632 if (!this.core.EncounteredError) 2565 if (!this.Core.EncounteredError)
2633 { 2566 {
2634 Row row = this.core.CreateRow(sourceLineNumbers, "WixComponentGroup", id); 2567 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixComponentGroup, id);
2635 2568
2636 // Add this componentGroup and its parent in WixGroup. 2569 // Add this componentGroup and its parent in WixGroup.
2637 this.core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.ComponentGroup, id.Id); 2570 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.ComponentGroup, id.Id);
2638 } 2571 }
2639 } 2572 }
2640 2573
@@ -2660,31 +2593,31 @@ namespace WixToolset
2660 switch (attrib.Name.LocalName) 2593 switch (attrib.Name.LocalName)
2661 { 2594 {
2662 case "Id": 2595 case "Id":
2663 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 2596 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2664 this.core.CreateSimpleReference(sourceLineNumbers, "WixComponentGroup", id); 2597 this.Core.CreateSimpleReference(sourceLineNumbers, "WixComponentGroup", id);
2665 break; 2598 break;
2666 case "Primary": 2599 case "Primary":
2667 primary = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2600 primary = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2668 break; 2601 break;
2669 default: 2602 default:
2670 this.core.UnexpectedAttribute(node, attrib); 2603 this.Core.UnexpectedAttribute(node, attrib);
2671 break; 2604 break;
2672 } 2605 }
2673 } 2606 }
2674 else 2607 else
2675 { 2608 {
2676 this.core.ParseExtensionAttribute(node, attrib); 2609 this.Core.ParseExtensionAttribute(node, attrib);
2677 } 2610 }
2678 } 2611 }
2679 2612
2680 if (null == id) 2613 if (null == id)
2681 { 2614 {
2682 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 2615 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
2683 } 2616 }
2684 2617
2685 this.core.ParseForExtensionElements(node); 2618 this.Core.ParseForExtensionElements(node);
2686 2619
2687 this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, parentLanguage, ComplexReferenceChildType.ComponentGroup, id, (YesNoType.Yes == primary)); 2620 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, parentLanguage, ComplexReferenceChildType.ComponentGroup, id, (YesNoType.Yes == primary));
2688 } 2621 }
2689 2622
2690 /// <summary> 2623 /// <summary>
@@ -2709,31 +2642,31 @@ namespace WixToolset
2709 switch (attrib.Name.LocalName) 2642 switch (attrib.Name.LocalName)
2710 { 2643 {
2711 case "Id": 2644 case "Id":
2712 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 2645 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2713 this.core.CreateSimpleReference(sourceLineNumbers, "Component", id); 2646 this.Core.CreateSimpleReference(sourceLineNumbers, "Component", id);
2714 break; 2647 break;
2715 case "Primary": 2648 case "Primary":
2716 primary = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2649 primary = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2717 break; 2650 break;
2718 default: 2651 default:
2719 this.core.UnexpectedAttribute(node, attrib); 2652 this.Core.UnexpectedAttribute(node, attrib);
2720 break; 2653 break;
2721 } 2654 }
2722 } 2655 }
2723 else 2656 else
2724 { 2657 {
2725 this.core.ParseExtensionAttribute(node, attrib); 2658 this.Core.ParseExtensionAttribute(node, attrib);
2726 } 2659 }
2727 } 2660 }
2728 2661
2729 if (null == id) 2662 if (null == id)
2730 { 2663 {
2731 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 2664 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
2732 } 2665 }
2733 2666
2734 this.core.ParseForExtensionElements(node); 2667 this.Core.ParseForExtensionElements(node);
2735 2668
2736 this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, parentLanguage, ComplexReferenceChildType.Component, id, (YesNoType.Yes == primary)); 2669 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, parentLanguage, ComplexReferenceChildType.Component, id, (YesNoType.Yes == primary));
2737 } 2670 }
2738 2671
2739 /// <summary> 2672 /// <summary>
@@ -2756,13 +2689,13 @@ namespace WixToolset
2756 switch (attrib.Name.LocalName) 2689 switch (attrib.Name.LocalName)
2757 { 2690 {
2758 case "Id": 2691 case "Id":
2759 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 2692 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
2760 break; 2693 break;
2761 case "Guid": 2694 case "Guid":
2762 componentId = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 2695 componentId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
2763 break; 2696 break;
2764 case "Type": 2697 case "Type":
2765 string typeValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 2698 string typeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2766 if (0 < typeValue.Length) 2699 if (0 < typeValue.Length)
2767 { 2700 {
2768 Wix.ComponentSearch.TypeType typeType = Wix.ComponentSearch.ParseTypeType(typeValue); 2701 Wix.ComponentSearch.TypeType typeType = Wix.ComponentSearch.ParseTypeType(typeValue);
@@ -2775,25 +2708,25 @@ namespace WixToolset
2775 type = MsiInterop.MsidbLocatorTypeFileName; 2708 type = MsiInterop.MsidbLocatorTypeFileName;
2776 break; 2709 break;
2777 default: 2710 default:
2778 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, typeValue, "directory", "file")); 2711 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, typeValue, "directory", "file"));
2779 break; 2712 break;
2780 } 2713 }
2781 } 2714 }
2782 break; 2715 break;
2783 default: 2716 default:
2784 this.core.UnexpectedAttribute(node, attrib); 2717 this.Core.UnexpectedAttribute(node, attrib);
2785 break; 2718 break;
2786 } 2719 }
2787 } 2720 }
2788 else 2721 else
2789 { 2722 {
2790 this.core.ParseExtensionAttribute(node, attrib); 2723 this.Core.ParseExtensionAttribute(node, attrib);
2791 } 2724 }
2792 } 2725 }
2793 2726
2794 if (null == id) 2727 if (null == id)
2795 { 2728 {
2796 id = this.core.CreateIdentifier("cmp", componentId, type.ToString()); 2729 id = this.Core.CreateIdentifier("cmp", componentId, type.ToString());
2797 } 2730 }
2798 2731
2799 signature = id.Id; 2732 signature = id.Id;
@@ -2807,7 +2740,7 @@ namespace WixToolset
2807 case "DirectorySearch": 2740 case "DirectorySearch":
2808 if (oneChild) 2741 if (oneChild)
2809 { 2742 {
2810 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 2743 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
2811 } 2744 }
2812 oneChild = true; 2745 oneChild = true;
2813 2746
@@ -2817,7 +2750,7 @@ namespace WixToolset
2817 case "DirectorySearchRef": 2750 case "DirectorySearchRef":
2818 if (oneChild) 2751 if (oneChild)
2819 { 2752 {
2820 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 2753 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
2821 } 2754 }
2822 oneChild = true; 2755 oneChild = true;
2823 signature = this.ParseDirectorySearchRefElement(child, id.Id); 2756 signature = this.ParseDirectorySearchRefElement(child, id.Id);
@@ -2825,7 +2758,7 @@ namespace WixToolset
2825 case "FileSearch": 2758 case "FileSearch":
2826 if (oneChild) 2759 if (oneChild)
2827 { 2760 {
2828 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 2761 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
2829 } 2762 }
2830 oneChild = true; 2763 oneChild = true;
2831 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet); 2764 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet);
@@ -2834,7 +2767,7 @@ namespace WixToolset
2834 case "FileSearchRef": 2767 case "FileSearchRef":
2835 if (oneChild) 2768 if (oneChild)
2836 { 2769 {
2837 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 2770 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
2838 } 2771 }
2839 oneChild = true; 2772 oneChild = true;
2840 string newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures 2773 string newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures
@@ -2842,21 +2775,21 @@ namespace WixToolset
2842 signature = null; 2775 signature = null;
2843 break; 2776 break;
2844 default: 2777 default:
2845 this.core.UnexpectedElement(node, child); 2778 this.Core.UnexpectedElement(node, child);
2846 break; 2779 break;
2847 } 2780 }
2848 } 2781 }
2849 else 2782 else
2850 { 2783 {
2851 this.core.ParseExtensionElement(node, child); 2784 this.Core.ParseExtensionElement(node, child);
2852 } 2785 }
2853 } 2786 }
2854 2787
2855 if (!this.core.EncounteredError) 2788 if (!this.Core.EncounteredError)
2856 { 2789 {
2857 Row row = this.core.CreateRow(sourceLineNumbers, "CompLocator", id); 2790 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CompLocator, id);
2858 row[1] = componentId; 2791 row.Set(1, componentId);
2859 row[2] = type; 2792 row.Set(2, type);
2860 } 2793 }
2861 2794
2862 return signature; 2795 return signature;
@@ -2880,16 +2813,16 @@ namespace WixToolset
2880 switch (attrib.Name.LocalName) 2813 switch (attrib.Name.LocalName)
2881 { 2814 {
2882 case "Directory": 2815 case "Directory":
2883 directoryId = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, directoryId); 2816 directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, directoryId);
2884 break; 2817 break;
2885 default: 2818 default:
2886 this.core.UnexpectedAttribute(node, attrib); 2819 this.Core.UnexpectedAttribute(node, attrib);
2887 break; 2820 break;
2888 } 2821 }
2889 } 2822 }
2890 else 2823 else
2891 { 2824 {
2892 this.core.ParseExtensionAttribute(node, attrib); 2825 this.Core.ParseExtensionAttribute(node, attrib);
2893 } 2826 }
2894 } 2827 }
2895 2828
@@ -2909,22 +2842,22 @@ namespace WixToolset
2909 this.ParsePermissionExElement(child, directoryId, "CreateFolder"); 2842 this.ParsePermissionExElement(child, directoryId, "CreateFolder");
2910 break; 2843 break;
2911 default: 2844 default:
2912 this.core.UnexpectedElement(node, child); 2845 this.Core.UnexpectedElement(node, child);
2913 break; 2846 break;
2914 } 2847 }
2915 } 2848 }
2916 else 2849 else
2917 { 2850 {
2918 Dictionary<string, string> context = new Dictionary<string, string>() { { "DirectoryId", directoryId }, { "ComponentId", componentId }, { "Win64", win64Component.ToString() } }; 2851 Dictionary<string, string> context = new Dictionary<string, string>() { { "DirectoryId", directoryId }, { "ComponentId", componentId }, { "Win64", win64Component.ToString() } };
2919 this.core.ParseExtensionElement(node, child, context); 2852 this.Core.ParseExtensionElement(node, child, context);
2920 } 2853 }
2921 } 2854 }
2922 2855
2923 if (!this.core.EncounteredError) 2856 if (!this.Core.EncounteredError)
2924 { 2857 {
2925 Row row = this.core.CreateRow(sourceLineNumbers, "CreateFolder"); 2858 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CreateFolder);
2926 row[0] = directoryId; 2859 row.Set(0, directoryId);
2927 row[1] = componentId; 2860 row.Set(1, componentId);
2928 } 2861 }
2929 2862
2930 return directoryId; 2863 return directoryId;
@@ -2957,167 +2890,167 @@ namespace WixToolset
2957 switch (attrib.Name.LocalName) 2890 switch (attrib.Name.LocalName)
2958 { 2891 {
2959 case "Id": 2892 case "Id":
2960 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 2893 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
2961 break; 2894 break;
2962 case "Delete": 2895 case "Delete":
2963 delete = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2896 delete = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2964 break; 2897 break;
2965 case "DestinationDirectory": 2898 case "DestinationDirectory":
2966 destinationDirectory = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null); 2899 destinationDirectory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
2967 break; 2900 break;
2968 case "DestinationName": 2901 case "DestinationName":
2969 destinationName = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); 2902 destinationName = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
2970 break; 2903 break;
2971 case "DestinationProperty": 2904 case "DestinationProperty":
2972 destinationProperty = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 2905 destinationProperty = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2973 break; 2906 break;
2974 case "DestinationShortName": 2907 case "DestinationShortName":
2975 destinationShortName = this.core.GetAttributeShortFilename(sourceLineNumbers, attrib, false); 2908 destinationShortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, false);
2976 break; 2909 break;
2977 case "FileId": 2910 case "FileId":
2978 if (null != fileId) 2911 if (null != fileId)
2979 { 2912 {
2980 this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName)); 2913 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
2981 } 2914 }
2982 fileId = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 2915 fileId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2983 this.core.CreateSimpleReference(sourceLineNumbers, "File", fileId); 2916 this.Core.CreateSimpleReference(sourceLineNumbers, "File", fileId);
2984 break; 2917 break;
2985 case "SourceDirectory": 2918 case "SourceDirectory":
2986 sourceDirectory = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null); 2919 sourceDirectory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
2987 break; 2920 break;
2988 case "SourceName": 2921 case "SourceName":
2989 sourceName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 2922 sourceName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2990 break; 2923 break;
2991 case "SourceProperty": 2924 case "SourceProperty":
2992 sourceProperty = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 2925 sourceProperty = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2993 break; 2926 break;
2994 default: 2927 default:
2995 this.core.UnexpectedAttribute(node, attrib); 2928 this.Core.UnexpectedAttribute(node, attrib);
2996 break; 2929 break;
2997 } 2930 }
2998 } 2931 }
2999 else 2932 else
3000 { 2933 {
3001 this.core.ParseExtensionAttribute(node, attrib); 2934 this.Core.ParseExtensionAttribute(node, attrib);
3002 } 2935 }
3003 } 2936 }
3004 2937
3005 if (null != sourceFolder && null != sourceDirectory) // SourceFolder and SourceDirectory cannot coexist 2938 if (null != sourceFolder && null != sourceDirectory) // SourceFolder and SourceDirectory cannot coexist
3006 { 2939 {
3007 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFolder", "SourceDirectory")); 2940 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFolder", "SourceDirectory"));
3008 } 2941 }
3009 2942
3010 if (null != sourceFolder && null != sourceProperty) // SourceFolder and SourceProperty cannot coexist 2943 if (null != sourceFolder && null != sourceProperty) // SourceFolder and SourceProperty cannot coexist
3011 { 2944 {
3012 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFolder", "SourceProperty")); 2945 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFolder", "SourceProperty"));
3013 } 2946 }
3014 2947
3015 if (null != sourceDirectory && null != sourceProperty) // SourceDirectory and SourceProperty cannot coexist 2948 if (null != sourceDirectory && null != sourceProperty) // SourceDirectory and SourceProperty cannot coexist
3016 { 2949 {
3017 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceProperty", "SourceDirectory")); 2950 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceProperty", "SourceDirectory"));
3018 } 2951 }
3019 2952
3020 if (null != destinationDirectory && null != destinationProperty) // DestinationDirectory and DestinationProperty cannot coexist 2953 if (null != destinationDirectory && null != destinationProperty) // DestinationDirectory and DestinationProperty cannot coexist
3021 { 2954 {
3022 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DestinationProperty", "DestinationDirectory")); 2955 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DestinationProperty", "DestinationDirectory"));
3023 } 2956 }
3024 2957
3025 // generate a short file name 2958 // generate a short file name
3026 if (null == destinationShortName && (null != destinationName && !this.core.IsValidShortFilename(destinationName, false))) 2959 if (null == destinationShortName && (null != destinationName && !this.Core.IsValidShortFilename(destinationName, false)))
3027 { 2960 {
3028 destinationShortName = this.core.CreateShortName(destinationName, true, false, node.Name.LocalName, componentId); 2961 destinationShortName = this.Core.CreateShortName(destinationName, true, false, node.Name.LocalName, componentId);
3029 } 2962 }
3030 2963
3031 if (null == id) 2964 if (null == id)
3032 { 2965 {
3033 id = this.core.CreateIdentifier("cf", sourceFolder, sourceDirectory, sourceProperty, destinationDirectory, destinationProperty, destinationName); 2966 id = this.Core.CreateIdentifier("cf", sourceFolder, sourceDirectory, sourceProperty, destinationDirectory, destinationProperty, destinationName);
3034 } 2967 }
3035 2968
3036 this.core.ParseForExtensionElements(node); 2969 this.Core.ParseForExtensionElements(node);
3037 2970
3038 if (null == fileId) 2971 if (null == fileId)
3039 { 2972 {
3040 // DestinationDirectory or DestinationProperty must be specified 2973 // DestinationDirectory or DestinationProperty must be specified
3041 if (null == destinationDirectory && null == destinationProperty) 2974 if (null == destinationDirectory && null == destinationProperty)
3042 { 2975 {
3043 this.core.OnMessage(WixErrors.ExpectedAttributesWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DestinationDirectory", "DestinationProperty", "FileId")); 2976 this.Core.OnMessage(WixErrors.ExpectedAttributesWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DestinationDirectory", "DestinationProperty", "FileId"));
3044 } 2977 }
3045 2978
3046 if (!this.core.EncounteredError) 2979 if (!this.Core.EncounteredError)
3047 { 2980 {
3048 Row row = this.core.CreateRow(sourceLineNumbers, "MoveFile", id); 2981 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MoveFile, id);
3049 row[1] = componentId; 2982 row.Set(1, componentId);
3050 row[2] = sourceName; 2983 row.Set(2, sourceName);
3051 row[3] = String.IsNullOrEmpty(destinationShortName) && String.IsNullOrEmpty(destinationName) ? null : GetMsiFilenameValue(destinationShortName, destinationName); 2984 row.Set(3, String.IsNullOrEmpty(destinationShortName) && String.IsNullOrEmpty(destinationName) ? null : GetMsiFilenameValue(destinationShortName, destinationName));
3052 if (null != sourceDirectory) 2985 if (null != sourceDirectory)
3053 { 2986 {
3054 row[4] = sourceDirectory; 2987 row.Set(4, sourceDirectory);
3055 } 2988 }
3056 else if (null != sourceProperty) 2989 else if (null != sourceProperty)
3057 { 2990 {
3058 row[4] = sourceProperty; 2991 row.Set(4, sourceProperty);
3059 } 2992 }
3060 else 2993 else
3061 { 2994 {
3062 row[4] = sourceFolder; 2995 row.Set(4, sourceFolder);
3063 } 2996 }
3064 2997
3065 if (null != destinationDirectory) 2998 if (null != destinationDirectory)
3066 { 2999 {
3067 row[5] = destinationDirectory; 3000 row.Set(5, destinationDirectory);
3068 } 3001 }
3069 else 3002 else
3070 { 3003 {
3071 row[5] = destinationProperty; 3004 row.Set(5, destinationProperty);
3072 } 3005 }
3073 row[6] = delete ? 1 : 0; 3006 row.Set(6, delete ? 1 : 0);
3074 } 3007 }
3075 } 3008 }
3076 else // copy the file 3009 else // copy the file
3077 { 3010 {
3078 if (null != sourceDirectory) 3011 if (null != sourceDirectory)
3079 { 3012 {
3080 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceDirectory", "FileId")); 3013 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceDirectory", "FileId"));
3081 } 3014 }
3082 3015
3083 if (null != sourceFolder) 3016 if (null != sourceFolder)
3084 { 3017 {
3085 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFolder", "FileId")); 3018 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFolder", "FileId"));
3086 } 3019 }
3087 3020
3088 if (null != sourceName) 3021 if (null != sourceName)
3089 { 3022 {
3090 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceName", "FileId")); 3023 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceName", "FileId"));
3091 } 3024 }
3092 3025
3093 if (null != sourceProperty) 3026 if (null != sourceProperty)
3094 { 3027 {
3095 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceProperty", "FileId")); 3028 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceProperty", "FileId"));
3096 } 3029 }
3097 3030
3098 if (delete) 3031 if (delete)
3099 { 3032 {
3100 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Delete", "FileId")); 3033 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Delete", "FileId"));
3101 } 3034 }
3102 3035
3103 if (null == destinationName && null == destinationDirectory && null == destinationProperty) 3036 if (null == destinationName && null == destinationDirectory && null == destinationProperty)
3104 { 3037 {
3105 this.core.OnMessage(WixWarnings.CopyFileFileIdUseless(sourceLineNumbers)); 3038 this.Core.OnMessage(WixWarnings.CopyFileFileIdUseless(sourceLineNumbers));
3106 } 3039 }
3107 3040
3108 if (!this.core.EncounteredError) 3041 if (!this.Core.EncounteredError)
3109 { 3042 {
3110 Row row = this.core.CreateRow(sourceLineNumbers, "DuplicateFile", id); 3043 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.DuplicateFile, id);
3111 row[1] = componentId; 3044 row.Set(1, componentId);
3112 row[2] = fileId; 3045 row.Set(2, fileId);
3113 row[3] = String.IsNullOrEmpty(destinationShortName) && String.IsNullOrEmpty(destinationName) ? null : GetMsiFilenameValue(destinationShortName, destinationName); 3046 row.Set(3, String.IsNullOrEmpty(destinationShortName) && String.IsNullOrEmpty(destinationName) ? null : GetMsiFilenameValue(destinationShortName, destinationName));
3114 if (null != destinationDirectory) 3047 if (null != destinationDirectory)
3115 { 3048 {
3116 row[4] = destinationDirectory; 3049 row.Set(4, destinationDirectory);
3117 } 3050 }
3118 else 3051 else
3119 { 3052 {
3120 row[4] = destinationProperty; 3053 row.Set(4, destinationProperty);
3121 } 3054 }
3122 } 3055 }
3123 } 3056 }
@@ -3149,39 +3082,39 @@ namespace WixToolset
3149 switch (attrib.Name.LocalName) 3082 switch (attrib.Name.LocalName)
3150 { 3083 {
3151 case "Id": 3084 case "Id":
3152 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 3085 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
3153 break; 3086 break;
3154 case "BinaryKey": 3087 case "BinaryKey":
3155 if (null != source) 3088 if (null != source)
3156 { 3089 {
3157 this.core.OnMessage(WixErrors.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileKey", "Property", "Script")); 3090 this.Core.OnMessage(WixErrors.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileKey", "Property", "Script"));
3158 } 3091 }
3159 source = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 3092 source = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3160 sourceBits = MsiInterop.MsidbCustomActionTypeBinaryData; 3093 sourceBits = MsiInterop.MsidbCustomActionTypeBinaryData;
3161 this.core.CreateSimpleReference(sourceLineNumbers, "Binary", source); // add a reference to the appropriate Binary 3094 this.Core.CreateSimpleReference(sourceLineNumbers, "Binary", source); // add a reference to the appropriate Binary
3162 break; 3095 break;
3163 case "Directory": 3096 case "Directory":
3164 if (null != source) 3097 if (null != source)
3165 { 3098 {
3166 this.core.OnMessage(WixErrors.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileKey", "Property", "Script")); 3099 this.Core.OnMessage(WixErrors.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileKey", "Property", "Script"));
3167 } 3100 }
3168 source = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null); 3101 source = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
3169 sourceBits = MsiInterop.MsidbCustomActionTypeDirectory; 3102 sourceBits = MsiInterop.MsidbCustomActionTypeDirectory;
3170 break; 3103 break;
3171 case "DllEntry": 3104 case "DllEntry":
3172 if (null != target) 3105 if (null != target)
3173 { 3106 {
3174 this.core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall")); 3107 this.Core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall"));
3175 } 3108 }
3176 target = this.core.GetAttributeValue(sourceLineNumbers, attrib); 3109 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3177 targetBits = MsiInterop.MsidbCustomActionTypeDll; 3110 targetBits = MsiInterop.MsidbCustomActionTypeDll;
3178 break; 3111 break;
3179 case "Error": 3112 case "Error":
3180 if (null != target) 3113 if (null != target)
3181 { 3114 {
3182 this.core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall")); 3115 this.Core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall"));
3183 } 3116 }
3184 target = this.core.GetAttributeValue(sourceLineNumbers, attrib); 3117 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3185 targetBits = MsiInterop.MsidbCustomActionTypeTextData | MsiInterop.MsidbCustomActionTypeSourceFile; 3118 targetBits = MsiInterop.MsidbCustomActionTypeTextData | MsiInterop.MsidbCustomActionTypeSourceFile;
3186 3119
3187 bool errorReference = true; 3120 bool errorReference = true;
@@ -3204,19 +3137,19 @@ namespace WixToolset
3204 3137
3205 if (errorReference) 3138 if (errorReference)
3206 { 3139 {
3207 this.core.CreateSimpleReference(sourceLineNumbers, "Error", target); 3140 this.Core.CreateSimpleReference(sourceLineNumbers, "Error", target);
3208 } 3141 }
3209 break; 3142 break;
3210 case "ExeCommand": 3143 case "ExeCommand":
3211 if (null != target) 3144 if (null != target)
3212 { 3145 {
3213 this.core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall")); 3146 this.Core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall"));
3214 } 3147 }
3215 target = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); // one of the few cases where an empty string value is valid 3148 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); // one of the few cases where an empty string value is valid
3216 targetBits = MsiInterop.MsidbCustomActionTypeExe; 3149 targetBits = MsiInterop.MsidbCustomActionTypeExe;
3217 break; 3150 break;
3218 case "Execute": 3151 case "Execute":
3219 string execute = this.core.GetAttributeValue(sourceLineNumbers, attrib); 3152 string execute = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3220 if (0 < execute.Length) 3153 if (0 < execute.Length)
3221 { 3154 {
3222 Wix.CustomAction.ExecuteType executeType = Wix.CustomAction.ParseExecuteType(execute); 3155 Wix.CustomAction.ExecuteType executeType = Wix.CustomAction.ParseExecuteType(execute);
@@ -3243,7 +3176,7 @@ namespace WixToolset
3243 bits |= MsiInterop.MsidbCustomActionTypeClientRepeat; 3176 bits |= MsiInterop.MsidbCustomActionTypeClientRepeat;
3244 break; 3177 break;
3245 default: 3178 default:
3246 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, execute, "commit", "deferred", "firstSequence", "immediate", "oncePerProcess", "rollback", "secondSequence")); 3179 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, execute, "commit", "deferred", "firstSequence", "immediate", "oncePerProcess", "rollback", "secondSequence"));
3247 break; 3180 break;
3248 } 3181 }
3249 } 3182 }
@@ -3251,20 +3184,20 @@ namespace WixToolset
3251 case "FileKey": 3184 case "FileKey":
3252 if (null != source) 3185 if (null != source)
3253 { 3186 {
3254 this.core.OnMessage(WixErrors.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileKey", "Property", "Script")); 3187 this.Core.OnMessage(WixErrors.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileKey", "Property", "Script"));
3255 } 3188 }
3256 source = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 3189 source = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3257 sourceBits = MsiInterop.MsidbCustomActionTypeSourceFile; 3190 sourceBits = MsiInterop.MsidbCustomActionTypeSourceFile;
3258 this.core.CreateSimpleReference(sourceLineNumbers, "File", source); // add a reference to the appropriate File 3191 this.Core.CreateSimpleReference(sourceLineNumbers, "File", source); // add a reference to the appropriate File
3259 break; 3192 break;
3260 case "HideTarget": 3193 case "HideTarget":
3261 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 3194 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
3262 { 3195 {
3263 bits |= MsiInterop.MsidbCustomActionTypeHideTarget; 3196 bits |= MsiInterop.MsidbCustomActionTypeHideTarget;
3264 } 3197 }
3265 break; 3198 break;
3266 case "Impersonate": 3199 case "Impersonate":
3267 if (YesNoType.No == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 3200 if (YesNoType.No == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
3268 { 3201 {
3269 bits |= MsiInterop.MsidbCustomActionTypeNoImpersonate; 3202 bits |= MsiInterop.MsidbCustomActionTypeNoImpersonate;
3270 } 3203 }
@@ -3272,13 +3205,13 @@ namespace WixToolset
3272 case "JScriptCall": 3205 case "JScriptCall":
3273 if (null != target) 3206 if (null != target)
3274 { 3207 {
3275 this.core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall")); 3208 this.Core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall"));
3276 } 3209 }
3277 target = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); // one of the few cases where an empty string value is valid 3210 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); // one of the few cases where an empty string value is valid
3278 targetBits = MsiInterop.MsidbCustomActionTypeJScript; 3211 targetBits = MsiInterop.MsidbCustomActionTypeJScript;
3279 break; 3212 break;
3280 case "PatchUninstall": 3213 case "PatchUninstall":
3281 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 3214 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
3282 { 3215 {
3283 extendedBits |= MsiInterop.MsidbCustomActionTypePatchUninstall; 3216 extendedBits |= MsiInterop.MsidbCustomActionTypePatchUninstall;
3284 } 3217 }
@@ -3286,13 +3219,13 @@ namespace WixToolset
3286 case "Property": 3219 case "Property":
3287 if (null != source) 3220 if (null != source)
3288 { 3221 {
3289 this.core.OnMessage(WixErrors.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileKey", "Property", "Script")); 3222 this.Core.OnMessage(WixErrors.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileKey", "Property", "Script"));
3290 } 3223 }
3291 source = this.core.GetAttributeValue(sourceLineNumbers, attrib); 3224 source = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3292 sourceBits = MsiInterop.MsidbCustomActionTypeProperty; 3225 sourceBits = MsiInterop.MsidbCustomActionTypeProperty;
3293 break; 3226 break;
3294 case "Return": 3227 case "Return":
3295 string returnValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 3228 string returnValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3296 if (0 < returnValue.Length) 3229 if (0 < returnValue.Length)
3297 { 3230 {
3298 Wix.CustomAction.ReturnType returnType = Wix.CustomAction.ParseReturnType(returnValue); 3231 Wix.CustomAction.ReturnType returnType = Wix.CustomAction.ParseReturnType(returnValue);
@@ -3310,7 +3243,7 @@ namespace WixToolset
3310 bits |= MsiInterop.MsidbCustomActionTypeContinue; 3243 bits |= MsiInterop.MsidbCustomActionTypeContinue;
3311 break; 3244 break;
3312 default: 3245 default:
3313 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, returnValue, "asyncNoWait", "asyncWait", "check", "ignore")); 3246 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, returnValue, "asyncNoWait", "asyncWait", "check", "ignore"));
3314 break; 3247 break;
3315 } 3248 }
3316 } 3249 }
@@ -3318,12 +3251,12 @@ namespace WixToolset
3318 case "Script": 3251 case "Script":
3319 if (null != source) 3252 if (null != source)
3320 { 3253 {
3321 this.core.OnMessage(WixErrors.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileKey", "Property", "Script")); 3254 this.Core.OnMessage(WixErrors.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileKey", "Property", "Script"));
3322 } 3255 }
3323 3256
3324 if (null != target) 3257 if (null != target)
3325 { 3258 {
3326 this.core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall")); 3259 this.Core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall"));
3327 } 3260 }
3328 3261
3329 // set the source and target to empty string for error messages when the user sets multiple sources or targets 3262 // set the source and target to empty string for error messages when the user sets multiple sources or targets
@@ -3332,7 +3265,7 @@ namespace WixToolset
3332 3265
3333 inlineScript = true; 3266 inlineScript = true;
3334 3267
3335 string script = this.core.GetAttributeValue(sourceLineNumbers, attrib); 3268 string script = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3336 if (0 < script.Length) 3269 if (0 < script.Length)
3337 { 3270 {
3338 Wix.CustomAction.ScriptType scriptType = Wix.CustomAction.ParseScriptType(script); 3271 Wix.CustomAction.ScriptType scriptType = Wix.CustomAction.ParseScriptType(script);
@@ -3347,16 +3280,16 @@ namespace WixToolset
3347 targetBits = MsiInterop.MsidbCustomActionTypeVBScript; 3280 targetBits = MsiInterop.MsidbCustomActionTypeVBScript;
3348 break; 3281 break;
3349 default: 3282 default:
3350 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, script, "jscript", "vbscript")); 3283 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, script, "jscript", "vbscript"));
3351 break; 3284 break;
3352 } 3285 }
3353 } 3286 }
3354 break; 3287 break;
3355 case "SuppressModularization": 3288 case "SuppressModularization":
3356 suppressModularization = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 3289 suppressModularization = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
3357 break; 3290 break;
3358 case "TerminalServerAware": 3291 case "TerminalServerAware":
3359 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 3292 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
3360 { 3293 {
3361 bits |= MsiInterop.MsidbCustomActionTypeTSAware; 3294 bits |= MsiInterop.MsidbCustomActionTypeTSAware;
3362 } 3295 }
@@ -3364,40 +3297,40 @@ namespace WixToolset
3364 case "Value": 3297 case "Value":
3365 if (null != target) 3298 if (null != target)
3366 { 3299 {
3367 this.core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall")); 3300 this.Core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall"));
3368 } 3301 }
3369 target = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); // one of the few cases where an empty string value is valid 3302 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); // one of the few cases where an empty string value is valid
3370 targetBits = MsiInterop.MsidbCustomActionTypeTextData; 3303 targetBits = MsiInterop.MsidbCustomActionTypeTextData;
3371 break; 3304 break;
3372 case "VBScriptCall": 3305 case "VBScriptCall":
3373 if (null != target) 3306 if (null != target)
3374 { 3307 {
3375 this.core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall")); 3308 this.Core.OnMessage(WixErrors.CustomActionMultipleTargets(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall"));
3376 } 3309 }
3377 target = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); // one of the few cases where an empty string value is valid 3310 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); // one of the few cases where an empty string value is valid
3378 targetBits = MsiInterop.MsidbCustomActionTypeVBScript; 3311 targetBits = MsiInterop.MsidbCustomActionTypeVBScript;
3379 break; 3312 break;
3380 case "Win64": 3313 case "Win64":
3381 explicitWin64 = true; 3314 explicitWin64 = true;
3382 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 3315 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
3383 { 3316 {
3384 bits |= MsiInterop.MsidbCustomActionType64BitScript; 3317 bits |= MsiInterop.MsidbCustomActionType64BitScript;
3385 } 3318 }
3386 break; 3319 break;
3387 default: 3320 default:
3388 this.core.UnexpectedAttribute(node, attrib); 3321 this.Core.UnexpectedAttribute(node, attrib);
3389 break; 3322 break;
3390 } 3323 }
3391 } 3324 }
3392 else 3325 else
3393 { 3326 {
3394 this.core.ParseExtensionAttribute(node, attrib); 3327 this.Core.ParseExtensionAttribute(node, attrib);
3395 } 3328 }
3396 } 3329 }
3397 3330
3398 if (null == id) 3331 if (null == id)
3399 { 3332 {
3400 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 3333 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
3401 id = Identifier.Invalid; 3334 id = Identifier.Invalid;
3402 } 3335 }
3403 3336
@@ -3407,7 +3340,7 @@ namespace WixToolset
3407 } 3340 }
3408 3341
3409 // get the inner text if any exists 3342 // get the inner text if any exists
3410 innerText = this.core.GetTrimmedInnerText(node); 3343 innerText = this.Core.GetTrimmedInnerText(node);
3411 3344
3412 // if we have an in-lined Script CustomAction ensure no source or target attributes were provided 3345 // if we have an in-lined Script CustomAction ensure no source or target attributes were provided
3413 if (inlineScript) 3346 if (inlineScript)
@@ -3418,48 +3351,48 @@ namespace WixToolset
3418 { 3351 {
3419 if (null == source) 3352 if (null == source)
3420 { 3353 {
3421 this.core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "VBScriptCall", "BinaryKey", "FileKey", "Property")); 3354 this.Core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "VBScriptCall", "BinaryKey", "FileKey", "Property"));
3422 } 3355 }
3423 else if (MsiInterop.MsidbCustomActionTypeDirectory == sourceBits) 3356 else if (MsiInterop.MsidbCustomActionTypeDirectory == sourceBits)
3424 { 3357 {
3425 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "VBScriptCall", "Directory")); 3358 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "VBScriptCall", "Directory"));
3426 } 3359 }
3427 } 3360 }
3428 else if (MsiInterop.MsidbCustomActionTypeJScript == targetBits) // non-inline jscript 3361 else if (MsiInterop.MsidbCustomActionTypeJScript == targetBits) // non-inline jscript
3429 { 3362 {
3430 if (null == source) 3363 if (null == source)
3431 { 3364 {
3432 this.core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "JScriptCall", "BinaryKey", "FileKey", "Property")); 3365 this.Core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "JScriptCall", "BinaryKey", "FileKey", "Property"));
3433 } 3366 }
3434 else if (MsiInterop.MsidbCustomActionTypeDirectory == sourceBits) 3367 else if (MsiInterop.MsidbCustomActionTypeDirectory == sourceBits)
3435 { 3368 {
3436 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "JScriptCall", "Directory")); 3369 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "JScriptCall", "Directory"));
3437 } 3370 }
3438 } 3371 }
3439 else if (MsiInterop.MsidbCustomActionTypeExe == targetBits) // exe-command 3372 else if (MsiInterop.MsidbCustomActionTypeExe == targetBits) // exe-command
3440 { 3373 {
3441 if (null == source) 3374 if (null == source)
3442 { 3375 {
3443 this.core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "ExeCommand", "BinaryKey", "Directory", "FileKey", "Property")); 3376 this.Core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "ExeCommand", "BinaryKey", "Directory", "FileKey", "Property"));
3444 } 3377 }
3445 } 3378 }
3446 else if (MsiInterop.MsidbCustomActionTypeTextData == (bits | sourceBits | targetBits)) 3379 else if (MsiInterop.MsidbCustomActionTypeTextData == (bits | sourceBits | targetBits))
3447 { 3380 {
3448 this.core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "Value", "Directory", "Property")); 3381 this.Core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "Value", "Directory", "Property"));
3449 } 3382 }
3450 else if (!String.IsNullOrEmpty(innerText)) // inner text cannot be specified with non-script CAs 3383 else if (!String.IsNullOrEmpty(innerText)) // inner text cannot be specified with non-script CAs
3451 { 3384 {
3452 this.core.OnMessage(WixErrors.CustomActionIllegalInnerText(sourceLineNumbers, node.Name.LocalName, innerText, "Script")); 3385 this.Core.OnMessage(WixErrors.CustomActionIllegalInnerText(sourceLineNumbers, node.Name.LocalName, innerText, "Script"));
3453 } 3386 }
3454 3387
3455 if (MsiInterop.MsidbCustomActionType64BitScript == (bits & MsiInterop.MsidbCustomActionType64BitScript) && MsiInterop.MsidbCustomActionTypeVBScript != targetBits && MsiInterop.MsidbCustomActionTypeJScript != targetBits) 3388 if (MsiInterop.MsidbCustomActionType64BitScript == (bits & MsiInterop.MsidbCustomActionType64BitScript) && MsiInterop.MsidbCustomActionTypeVBScript != targetBits && MsiInterop.MsidbCustomActionTypeJScript != targetBits)
3456 { 3389 {
3457 this.core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "Win64", "Script", "VBScriptCall", "JScriptCall")); 3390 this.Core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "Win64", "Script", "VBScriptCall", "JScriptCall"));
3458 } 3391 }
3459 3392
3460 if ((MsiInterop.MsidbCustomActionTypeAsync | MsiInterop.MsidbCustomActionTypeContinue) == (bits & (MsiInterop.MsidbCustomActionTypeAsync | MsiInterop.MsidbCustomActionTypeContinue)) && MsiInterop.MsidbCustomActionTypeExe != targetBits) 3393 if ((MsiInterop.MsidbCustomActionTypeAsync | MsiInterop.MsidbCustomActionTypeContinue) == (bits & (MsiInterop.MsidbCustomActionTypeAsync | MsiInterop.MsidbCustomActionTypeContinue)) && MsiInterop.MsidbCustomActionTypeExe != targetBits)
3461 { 3394 {
3462 this.core.OnMessage(WixErrors.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Return", "asyncNoWait", "ExeCommand")); 3395 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Return", "asyncNoWait", "ExeCommand"));
3463 } 3396 }
3464 3397
3465 if (MsiInterop.MsidbCustomActionTypeTSAware == (bits & MsiInterop.MsidbCustomActionTypeTSAware)) 3398 if (MsiInterop.MsidbCustomActionTypeTSAware == (bits & MsiInterop.MsidbCustomActionTypeTSAware))
@@ -3467,7 +3400,7 @@ namespace WixToolset
3467 // TS-aware CAs are valid only when deferred so require the in-script Type bit... 3400 // TS-aware CAs are valid only when deferred so require the in-script Type bit...
3468 if (0 == (bits & MsiInterop.MsidbCustomActionTypeInScript)) 3401 if (0 == (bits & MsiInterop.MsidbCustomActionTypeInScript))
3469 { 3402 {
3470 this.core.OnMessage(WixErrors.IllegalTerminalServerCustomActionAttributes(sourceLineNumbers)); 3403 this.Core.OnMessage(WixErrors.IllegalTerminalServerCustomActionAttributes(sourceLineNumbers));
3471 } 3404 }
3472 } 3405 }
3473 3406
@@ -3476,30 +3409,30 @@ namespace WixToolset
3476 MsiInterop.MsidbCustomActionTypeTextData == targetBits && 3409 MsiInterop.MsidbCustomActionTypeTextData == targetBits &&
3477 0 != (bits & MsiInterop.MsidbCustomActionTypeInScript)) 3410 0 != (bits & MsiInterop.MsidbCustomActionTypeInScript))
3478 { 3411 {
3479 this.core.OnMessage(WixErrors.IllegalPropertyCustomActionAttributes(sourceLineNumbers)); 3412 this.Core.OnMessage(WixErrors.IllegalPropertyCustomActionAttributes(sourceLineNumbers));
3480 } 3413 }
3481 3414
3482 if (0 == targetBits) 3415 if (0 == targetBits)
3483 { 3416 {
3484 this.core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall")); 3417 this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "DllEntry", "Error", "ExeCommand", "JScriptCall", "Script", "Value", "VBScriptCall"));
3485 } 3418 }
3486 3419
3487 this.core.ParseForExtensionElements(node); 3420 this.Core.ParseForExtensionElements(node);
3488 3421
3489 if (!this.core.EncounteredError) 3422 if (!this.Core.EncounteredError)
3490 { 3423 {
3491 Row row = this.core.CreateRow(sourceLineNumbers, "CustomAction", id); 3424 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CustomAction, id);
3492 row[1] = bits | sourceBits | targetBits; 3425 row.Set(1, bits | sourceBits | targetBits);
3493 row[2] = source; 3426 row.Set(2, source);
3494 row[3] = target; 3427 row.Set(3, target);
3495 if (0 != extendedBits) 3428 if (0 != extendedBits)
3496 { 3429 {
3497 row[4] = extendedBits; 3430 row.Set(4, extendedBits);
3498 } 3431 }
3499 3432
3500 if (YesNoType.Yes == suppressModularization) 3433 if (YesNoType.Yes == suppressModularization)
3501 { 3434 {
3502 this.core.CreateRow(sourceLineNumbers, "WixSuppressModularization", id); 3435 this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSuppressModularization, id);
3503 } 3436 }
3504 3437
3505 // For deferred CAs that specify HideTarget we should also hide the CA data property for the action. 3438 // For deferred CAs that specify HideTarget we should also hide the CA data property for the action.
@@ -3529,26 +3462,26 @@ namespace WixToolset
3529 switch (attrib.Name.LocalName) 3462 switch (attrib.Name.LocalName)
3530 { 3463 {
3531 case "Id": 3464 case "Id":
3532 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 3465 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3533 this.core.CreateSimpleReference(sourceLineNumbers, table, id); 3466 this.Core.CreateSimpleReference(sourceLineNumbers, table, id);
3534 break; 3467 break;
3535 default: 3468 default:
3536 this.core.UnexpectedAttribute(node, attrib); 3469 this.Core.UnexpectedAttribute(node, attrib);
3537 break; 3470 break;
3538 } 3471 }
3539 } 3472 }
3540 else 3473 else
3541 { 3474 {
3542 this.core.ParseExtensionAttribute(node, attrib); 3475 this.Core.ParseExtensionAttribute(node, attrib);
3543 } 3476 }
3544 } 3477 }
3545 3478
3546 if (null == id) 3479 if (null == id)
3547 { 3480 {
3548 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 3481 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
3549 } 3482 }
3550 3483
3551 this.core.ParseForExtensionElements(node); 3484 this.Core.ParseForExtensionElements(node);
3552 3485
3553 return id; 3486 return id;
3554 } 3487 }
@@ -3572,34 +3505,34 @@ namespace WixToolset
3572 switch (attrib.Name.LocalName) 3505 switch (attrib.Name.LocalName)
3573 { 3506 {
3574 case "Id": 3507 case "Id":
3575 primaryKeys[0] = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 3508 primaryKeys[0] = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3576 break; 3509 break;
3577 case "ProductCode": 3510 case "ProductCode":
3578 primaryKeys[1] = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 3511 primaryKeys[1] = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3579 break; 3512 break;
3580 default: 3513 default:
3581 this.core.UnexpectedAttribute(node, attrib); 3514 this.Core.UnexpectedAttribute(node, attrib);
3582 break; 3515 break;
3583 } 3516 }
3584 } 3517 }
3585 else 3518 else
3586 { 3519 {
3587 this.core.ParseExtensionAttribute(node, attrib); 3520 this.Core.ParseExtensionAttribute(node, attrib);
3588 } 3521 }
3589 } 3522 }
3590 3523
3591 if (null == primaryKeys[0]) 3524 if (null == primaryKeys[0])
3592 { 3525 {
3593 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 3526 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
3594 } 3527 }
3595 3528
3596 this.core.CreateSimpleReference(sourceLineNumbers, "MsiPatchSequence", primaryKeys); 3529 this.Core.CreateSimpleReference(sourceLineNumbers, "MsiPatchSequence", primaryKeys);
3597 3530
3598 this.core.ParseForExtensionElements(node); 3531 this.Core.ParseForExtensionElements(node);
3599 3532
3600 if (!this.core.EncounteredError) 3533 if (!this.Core.EncounteredError)
3601 { 3534 {
3602 this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamily, primaryKeys[0], true); 3535 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamily, primaryKeys[0], true);
3603 } 3536 }
3604 } 3537 }
3605 3538
@@ -3620,22 +3553,22 @@ namespace WixToolset
3620 switch (attrib.Name.LocalName) 3553 switch (attrib.Name.LocalName)
3621 { 3554 {
3622 case "Id": 3555 case "Id":
3623 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 3556 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
3624 break; 3557 break;
3625 default: 3558 default:
3626 this.core.UnexpectedAttribute(node, attrib); 3559 this.Core.UnexpectedAttribute(node, attrib);
3627 break; 3560 break;
3628 } 3561 }
3629 } 3562 }
3630 else 3563 else
3631 { 3564 {
3632 this.core.ParseExtensionAttribute(node, attrib); 3565 this.Core.ParseExtensionAttribute(node, attrib);
3633 } 3566 }
3634 } 3567 }
3635 3568
3636 if (null == id) 3569 if (null == id)
3637 { 3570 {
3638 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 3571 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
3639 id = Identifier.Invalid; 3572 id = Identifier.Invalid;
3640 } 3573 }
3641 3574
@@ -3655,22 +3588,22 @@ namespace WixToolset
3655 this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.PatchFamilyGroup, id.Id); 3588 this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.PatchFamilyGroup, id.Id);
3656 break; 3589 break;
3657 default: 3590 default:
3658 this.core.UnexpectedElement(node, child); 3591 this.Core.UnexpectedElement(node, child);
3659 break; 3592 break;
3660 } 3593 }
3661 } 3594 }
3662 else 3595 else
3663 { 3596 {
3664 this.core.ParseExtensionElement(node, child); 3597 this.Core.ParseExtensionElement(node, child);
3665 } 3598 }
3666 } 3599 }
3667 3600
3668 if (!this.core.EncounteredError) 3601 if (!this.Core.EncounteredError)
3669 { 3602 {
3670 Row row = this.core.CreateRow(sourceLineNumbers, "WixPatchFamilyGroup", id); 3603 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchFamilyGroup, id);
3671 3604
3672 //Add this PatchFamilyGroup and its parent in WixGroup. 3605 //Add this PatchFamilyGroup and its parent in WixGroup.
3673 this.core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PatchFamilyGroup, id.Id); 3606 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PatchFamilyGroup, id.Id);
3674 } 3607 }
3675 } 3608 }
3676 3609
@@ -3694,30 +3627,30 @@ namespace WixToolset
3694 switch (attrib.Name.LocalName) 3627 switch (attrib.Name.LocalName)
3695 { 3628 {
3696 case "Id": 3629 case "Id":
3697 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 3630 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3698 this.core.CreateSimpleReference(sourceLineNumbers, "WixPatchFamilyGroup", id); 3631 this.Core.CreateSimpleReference(sourceLineNumbers, "WixPatchFamilyGroup", id);
3699 break; 3632 break;
3700 default: 3633 default:
3701 this.core.UnexpectedAttribute(node, attrib); 3634 this.Core.UnexpectedAttribute(node, attrib);
3702 break; 3635 break;
3703 } 3636 }
3704 } 3637 }
3705 else 3638 else
3706 { 3639 {
3707 this.core.ParseExtensionAttribute(node, attrib); 3640 this.Core.ParseExtensionAttribute(node, attrib);
3708 } 3641 }
3709 } 3642 }
3710 3643
3711 if (null == id) 3644 if (null == id)
3712 { 3645 {
3713 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 3646 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
3714 } 3647 }
3715 3648
3716 this.core.ParseForExtensionElements(node); 3649 this.Core.ParseForExtensionElements(node);
3717 3650
3718 if (!this.core.EncounteredError) 3651 if (!this.Core.EncounteredError)
3719 { 3652 {
3720 this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamilyGroup, id, true); 3653 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamilyGroup, id, true);
3721 } 3654 }
3722 } 3655 }
3723 3656
@@ -3737,31 +3670,31 @@ namespace WixToolset
3737 switch (attrib.Name.LocalName) 3670 switch (attrib.Name.LocalName)
3738 { 3671 {
3739 case "Id": 3672 case "Id":
3740 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 3673 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3741 break; 3674 break;
3742 default: 3675 default:
3743 this.core.UnexpectedAttribute(node, attrib); 3676 this.Core.UnexpectedAttribute(node, attrib);
3744 break; 3677 break;
3745 } 3678 }
3746 } 3679 }
3747 else 3680 else
3748 { 3681 {
3749 this.core.ParseExtensionAttribute(node, attrib); 3682 this.Core.ParseExtensionAttribute(node, attrib);
3750 } 3683 }
3751 } 3684 }
3752 3685
3753 if (null == id) 3686 if (null == id)
3754 { 3687 {
3755 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 3688 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
3756 } 3689 }
3757 else if (31 < id.Length) 3690 else if (31 < id.Length)
3758 { 3691 {
3759 this.core.OnMessage(WixErrors.TableNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", id)); 3692 this.Core.OnMessage(WixErrors.TableNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", id));
3760 } 3693 }
3761 3694
3762 this.core.ParseForExtensionElements(node); 3695 this.Core.ParseForExtensionElements(node);
3763 3696
3764 this.core.EnsureTable(sourceLineNumbers, id); 3697 this.Core.EnsureTable(sourceLineNumbers, id);
3765 } 3698 }
3766 3699
3767 /// <summary> 3700 /// <summary>
@@ -3769,9 +3702,6 @@ namespace WixToolset
3769 /// </summary> 3702 /// </summary>
3770 /// <param name="node">Element to parse.</param> 3703 /// <param name="node">Element to parse.</param>
3771 /// <remarks>not cleaned</remarks> 3704 /// <remarks>not cleaned</remarks>
3772 [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Changing the way this string normalizes would result " +
3773 "in a change to the way the WixCustomTable table is generated. Furthermore, there is no security hole here, as the strings won't need to " +
3774 "make a round trip")]
3775 private void ParseCustomTableElement(XElement node) 3705 private void ParseCustomTableElement(XElement node)
3776 { 3706 {
3777 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 3707 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
@@ -3798,29 +3728,29 @@ namespace WixToolset
3798 switch (attrib.Name.LocalName) 3728 switch (attrib.Name.LocalName)
3799 { 3729 {
3800 case "Id": 3730 case "Id":
3801 tableId = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 3731 tableId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3802 break; 3732 break;
3803 case "BootstrapperApplicationData": 3733 case "BootstrapperApplicationData":
3804 bootstrapperApplicationData = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 3734 bootstrapperApplicationData = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
3805 break; 3735 break;
3806 default: 3736 default:
3807 this.core.UnexpectedAttribute(node, attrib); 3737 this.Core.UnexpectedAttribute(node, attrib);
3808 break; 3738 break;
3809 } 3739 }
3810 } 3740 }
3811 else 3741 else
3812 { 3742 {
3813 this.core.ParseExtensionAttribute(node, attrib); 3743 this.Core.ParseExtensionAttribute(node, attrib);
3814 } 3744 }
3815 } 3745 }
3816 3746
3817 if (null == tableId) 3747 if (null == tableId)
3818 { 3748 {
3819 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 3749 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
3820 } 3750 }
3821 else if (31 < tableId.Length) 3751 else if (31 < tableId.Length)
3822 { 3752 {
3823 this.core.OnMessage(WixErrors.CustomTableNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", tableId)); 3753 this.Core.OnMessage(WixErrors.CustomTableNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", tableId));
3824 } 3754 }
3825 3755
3826 foreach (XElement child in node.Elements()) 3756 foreach (XElement child in node.Elements())
@@ -3854,43 +3784,43 @@ namespace WixToolset
3854 switch (childAttrib.Name.LocalName) 3784 switch (childAttrib.Name.LocalName)
3855 { 3785 {
3856 case "Id": 3786 case "Id":
3857 columnName = this.core.GetAttributeIdentifierValue(childSourceLineNumbers, childAttrib); 3787 columnName = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, childAttrib);
3858 break; 3788 break;
3859 case "Category": 3789 case "Category":
3860 category = this.core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3790 category = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3861 break; 3791 break;
3862 case "Description": 3792 case "Description":
3863 description = this.core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3793 description = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3864 break; 3794 break;
3865 case "KeyColumn": 3795 case "KeyColumn":
3866 keyColumn = this.core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 1, 32); 3796 keyColumn = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 1, 32);
3867 break; 3797 break;
3868 case "KeyTable": 3798 case "KeyTable":
3869 keyTable = this.core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3799 keyTable = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3870 break; 3800 break;
3871 case "Localizable": 3801 case "Localizable":
3872 localizable = YesNoType.Yes == this.core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib); 3802 localizable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3873 break; 3803 break;
3874 case "MaxValue": 3804 case "MaxValue":
3875 maxValue = this.core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, int.MinValue + 1, int.MaxValue); 3805 maxValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, int.MinValue + 1, int.MaxValue);
3876 break; 3806 break;
3877 case "MinValue": 3807 case "MinValue":
3878 minValue = this.core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, int.MinValue + 1, int.MaxValue); 3808 minValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, int.MinValue + 1, int.MaxValue);
3879 break; 3809 break;
3880 case "Modularize": 3810 case "Modularize":
3881 modularization = this.core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3811 modularization = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3882 break; 3812 break;
3883 case "Nullable": 3813 case "Nullable":
3884 nullable = YesNoType.Yes == this.core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib); 3814 nullable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3885 break; 3815 break;
3886 case "PrimaryKey": 3816 case "PrimaryKey":
3887 primaryKey = YesNoType.Yes == this.core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib); 3817 primaryKey = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib);
3888 break; 3818 break;
3889 case "Set": 3819 case "Set":
3890 setValues = this.core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3820 setValues = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3891 break; 3821 break;
3892 case "Type": 3822 case "Type":
3893 string typeValue = this.core.GetAttributeValue(childSourceLineNumbers, childAttrib); 3823 string typeValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
3894 if (0 < typeValue.Length) 3824 if (0 < typeValue.Length)
3895 { 3825 {
3896 Wix.Column.TypeType typeType = Wix.Column.ParseTypeType(typeValue); 3826 Wix.Column.TypeType typeType = Wix.Column.ParseTypeType(typeValue);
@@ -3906,34 +3836,34 @@ namespace WixToolset
3906 typeName = "CHAR"; 3836 typeName = "CHAR";
3907 break; 3837 break;
3908 default: 3838 default:
3909 this.core.OnMessage(WixErrors.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Type", typeValue, "binary", "int", "string")); 3839 this.Core.OnMessage(WixErrors.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Type", typeValue, "binary", "int", "string"));
3910 break; 3840 break;
3911 } 3841 }
3912 } 3842 }
3913 break; 3843 break;
3914 case "Width": 3844 case "Width":
3915 width = this.core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 0, int.MaxValue); 3845 width = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 0, int.MaxValue);
3916 break; 3846 break;
3917 default: 3847 default:
3918 this.core.UnexpectedAttribute(child, childAttrib); 3848 this.Core.UnexpectedAttribute(child, childAttrib);
3919 break; 3849 break;
3920 } 3850 }
3921 } 3851 }
3922 3852
3923 if (null == columnName) 3853 if (null == columnName)
3924 { 3854 {
3925 this.core.OnMessage(WixErrors.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Id")); 3855 this.Core.OnMessage(WixErrors.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Id"));
3926 } 3856 }
3927 3857
3928 if (null == typeName) 3858 if (null == typeName)
3929 { 3859 {
3930 this.core.OnMessage(WixErrors.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Type")); 3860 this.Core.OnMessage(WixErrors.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Type"));
3931 } 3861 }
3932 else if ("SHORT" == typeName) 3862 else if ("SHORT" == typeName)
3933 { 3863 {
3934 if (2 != width && 4 != width) 3864 if (2 != width && 4 != width)
3935 { 3865 {
3936 this.core.OnMessage(WixErrors.CustomTableIllegalColumnWidth(childSourceLineNumbers, child.Name.LocalName, "Width", width)); 3866 this.Core.OnMessage(WixErrors.CustomTableIllegalColumnWidth(childSourceLineNumbers, child.Name.LocalName, "Width", width));
3937 } 3867 }
3938 columnType = String.Concat(nullable ? "I" : "i", width); 3868 columnType = String.Concat(nullable ? "I" : "i", width);
3939 } 3869 }
@@ -3946,12 +3876,12 @@ namespace WixToolset
3946 { 3876 {
3947 if ("Binary" != category) 3877 if ("Binary" != category)
3948 { 3878 {
3949 this.core.OnMessage(WixErrors.ExpectedBinaryCategory(childSourceLineNumbers)); 3879 this.Core.OnMessage(WixErrors.ExpectedBinaryCategory(childSourceLineNumbers));
3950 } 3880 }
3951 columnType = String.Concat(nullable ? "V" : "v", width); 3881 columnType = String.Concat(nullable ? "V" : "v", width);
3952 } 3882 }
3953 3883
3954 this.core.ParseForExtensionElements(child); 3884 this.Core.ParseForExtensionElements(child);
3955 3885
3956 columnNames = String.Concat(columnNames, null == columnNames ? String.Empty : "\t", columnName); 3886 columnNames = String.Concat(columnNames, null == columnNames ? String.Empty : "\t", columnName);
3957 columnTypes = String.Concat(columnTypes, null == columnTypes ? String.Empty : "\t", columnType); 3887 columnTypes = String.Concat(columnTypes, null == columnTypes ? String.Empty : "\t", columnType);
@@ -3975,7 +3905,7 @@ namespace WixToolset
3975 3905
3976 foreach (XAttribute childAttrib in child.Attributes()) 3906 foreach (XAttribute childAttrib in child.Attributes())
3977 { 3907 {
3978 this.core.ParseExtensionAttribute(child, childAttrib); 3908 this.Core.ParseExtensionAttribute(child, childAttrib);
3979 } 3909 }
3980 3910
3981 foreach (XElement data in child.Elements()) 3911 foreach (XElement data in child.Elements())
@@ -3990,17 +3920,17 @@ namespace WixToolset
3990 switch (dataAttrib.Name.LocalName) 3920 switch (dataAttrib.Name.LocalName)
3991 { 3921 {
3992 case "Column": 3922 case "Column":
3993 columnName = this.core.GetAttributeValue(dataSourceLineNumbers, dataAttrib); 3923 columnName = this.Core.GetAttributeValue(dataSourceLineNumbers, dataAttrib);
3994 break; 3924 break;
3995 default: 3925 default:
3996 this.core.UnexpectedAttribute(data, dataAttrib); 3926 this.Core.UnexpectedAttribute(data, dataAttrib);
3997 break; 3927 break;
3998 } 3928 }
3999 } 3929 }
4000 3930
4001 if (null == columnName) 3931 if (null == columnName)
4002 { 3932 {
4003 this.core.OnMessage(WixErrors.ExpectedAttribute(dataSourceLineNumbers, data.Name.LocalName, "Column")); 3933 this.Core.OnMessage(WixErrors.ExpectedAttribute(dataSourceLineNumbers, data.Name.LocalName, "Column"));
4004 } 3934 }
4005 3935
4006 dataValue = String.Concat(dataValue, null == dataValue ? String.Empty : Common.CustomRowFieldSeparator.ToString(), columnName, ":", Common.GetInnerText(data)); 3936 dataValue = String.Concat(dataValue, null == dataValue ? String.Empty : Common.CustomRowFieldSeparator.ToString(), columnName, ":", Common.GetInnerText(data));
@@ -4008,23 +3938,23 @@ namespace WixToolset
4008 } 3938 }
4009 } 3939 }
4010 3940
4011 this.core.CreateSimpleReference(sourceLineNumbers, "WixCustomTable", tableId); 3941 this.Core.CreateSimpleReference(sourceLineNumbers, "WixCustomTable", tableId);
4012 3942
4013 if (!this.core.EncounteredError) 3943 if (!this.Core.EncounteredError)
4014 { 3944 {
4015 Row rowRow = this.core.CreateRow(childSourceLineNumbers, "WixCustomRow"); 3945 var rowRow = this.Core.CreateRow(childSourceLineNumbers, TupleDefinitionType.WixCustomRow);
4016 rowRow[0] = tableId; 3946 rowRow.Set(0, tableId);
4017 rowRow[1] = dataValue; 3947 rowRow.Set(1, dataValue);
4018 } 3948 }
4019 break; 3949 break;
4020 default: 3950 default:
4021 this.core.UnexpectedElement(node, child); 3951 this.Core.UnexpectedElement(node, child);
4022 break; 3952 break;
4023 } 3953 }
4024 } 3954 }
4025 else 3955 else
4026 { 3956 {
4027 this.core.ParseExtensionElement(node, child); 3957 this.Core.ParseExtensionElement(node, child);
4028 } 3958 }
4029 } 3959 }
4030 3960
@@ -4032,26 +3962,26 @@ namespace WixToolset
4032 { 3962 {
4033 if (null == primaryKeys || 0 == primaryKeys.Length) 3963 if (null == primaryKeys || 0 == primaryKeys.Length)
4034 { 3964 {
4035 this.core.OnMessage(WixErrors.CustomTableMissingPrimaryKey(sourceLineNumbers)); 3965 this.Core.OnMessage(WixErrors.CustomTableMissingPrimaryKey(sourceLineNumbers));
4036 } 3966 }
4037 3967
4038 if (!this.core.EncounteredError) 3968 if (!this.Core.EncounteredError)
4039 { 3969 {
4040 Row row = this.core.CreateRow(sourceLineNumbers, "WixCustomTable"); 3970 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixCustomTable);
4041 row[0] = tableId; 3971 row.Set(0, tableId);
4042 row[1] = columnCount; 3972 row.Set(1, columnCount);
4043 row[2] = columnNames; 3973 row.Set(2, columnNames);
4044 row[3] = columnTypes; 3974 row.Set(3, columnTypes);
4045 row[4] = primaryKeys; 3975 row.Set(4, primaryKeys);
4046 row[5] = minValues; 3976 row.Set(5, minValues);
4047 row[6] = maxValues; 3977 row.Set(6, maxValues);
4048 row[7] = keyTables; 3978 row.Set(7, keyTables);
4049 row[8] = keyColumns; 3979 row.Set(8, keyColumns);
4050 row[9] = categories; 3980 row.Set(9, categories);
4051 row[10] = sets; 3981 row.Set(10, sets);
4052 row[11] = descriptions; 3982 row.Set(11, descriptions);
4053 row[12] = modularizations; 3983 row.Set(12, modularizations);
4054 row[13] = bootstrapperApplicationData ? 1 : 0; 3984 row.Set(13, bootstrapperApplicationData ? 1 : 0);
4055 } 3985 }
4056 } 3986 }
4057 } 3987 }
@@ -4086,16 +4016,16 @@ namespace WixToolset
4086 switch (attrib.Name.LocalName) 4016 switch (attrib.Name.LocalName)
4087 { 4017 {
4088 case "Id": 4018 case "Id":
4089 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 4019 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
4090 break; 4020 break;
4091 case "ComponentGuidGenerationSeed": 4021 case "ComponentGuidGenerationSeed":
4092 componentGuidGenerationSeed = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 4022 componentGuidGenerationSeed = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
4093 break; 4023 break;
4094 case "DiskId": 4024 case "DiskId":
4095 diskId = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); 4025 diskId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue);
4096 break; 4026 break;
4097 case "FileSource": 4027 case "FileSource":
4098 fileSource = this.core.GetAttributeValue(sourceLineNumbers, attrib); 4028 fileSource = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4099 fileSourceAttribSet = true; 4029 fileSourceAttribSet = true;
4100 break; 4030 break;
4101 case "Name": 4031 case "Name":
@@ -4106,14 +4036,14 @@ namespace WixToolset
4106 } 4036 }
4107 else 4037 else
4108 { 4038 {
4109 inlineSyntax = this.core.GetAttributeInlineDirectorySyntax(sourceLineNumbers, attrib); 4039 inlineSyntax = this.Core.GetAttributeInlineDirectorySyntax(sourceLineNumbers, attrib);
4110 } 4040 }
4111 break; 4041 break;
4112 case "ShortName": 4042 case "ShortName":
4113 shortName = this.core.GetAttributeShortFilename(sourceLineNumbers, attrib, false); 4043 shortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, false);
4114 break; 4044 break;
4115 case "ShortSourceName": 4045 case "ShortSourceName":
4116 shortSourceName = this.core.GetAttributeShortFilename(sourceLineNumbers, attrib, false); 4046 shortSourceName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, false);
4117 break; 4047 break;
4118 case "SourceName": 4048 case "SourceName":
4119 if ("." == attrib.Value) 4049 if ("." == attrib.Value)
@@ -4122,17 +4052,17 @@ namespace WixToolset
4122 } 4052 }
4123 else 4053 else
4124 { 4054 {
4125 sourceName = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); 4055 sourceName = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
4126 } 4056 }
4127 break; 4057 break;
4128 default: 4058 default:
4129 this.core.UnexpectedAttribute(node, attrib); 4059 this.Core.UnexpectedAttribute(node, attrib);
4130 break; 4060 break;
4131 } 4061 }
4132 } 4062 }
4133 else 4063 else
4134 { 4064 {
4135 this.core.ParseExtensionAttribute(node, attrib); 4065 this.Core.ParseExtensionAttribute(node, attrib);
4136 } 4066 }
4137 } 4067 }
4138 4068
@@ -4151,14 +4081,14 @@ namespace WixToolset
4151 if (inlineSyntax[0].EndsWith(":")) 4081 if (inlineSyntax[0].EndsWith(":"))
4152 { 4082 {
4153 parentId = inlineSyntax[0].TrimEnd(':'); 4083 parentId = inlineSyntax[0].TrimEnd(':');
4154 this.core.CreateSimpleReference(sourceLineNumbers, "Directory", parentId); 4084 this.Core.CreateSimpleReference(sourceLineNumbers, "Directory", parentId);
4155 4085
4156 pathStartsAt = 1; 4086 pathStartsAt = 1;
4157 } 4087 }
4158 4088
4159 for (int i = pathStartsAt; i < inlineSyntax.Length - 1; ++i) 4089 for (int i = pathStartsAt; i < inlineSyntax.Length - 1; ++i)
4160 { 4090 {
4161 Identifier inlineId = this.core.CreateDirectoryRow(sourceLineNumbers, null, parentId, inlineSyntax[i]); 4091 Identifier inlineId = this.Core.CreateDirectoryRow(sourceLineNumbers, null, parentId, inlineSyntax[i]);
4162 parentId = inlineId.Id; 4092 parentId = inlineId.Id;
4163 } 4093 }
4164 4094
@@ -4170,30 +4100,30 @@ namespace WixToolset
4170 { 4100 {
4171 if (!String.IsNullOrEmpty(shortName)) 4101 if (!String.IsNullOrEmpty(shortName))
4172 { 4102 {
4173 this.core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "ShortName", "Name")); 4103 this.Core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "ShortName", "Name"));
4174 } 4104 }
4175 4105
4176 if (null == parentId) 4106 if (null == parentId)
4177 { 4107 {
4178 this.core.OnMessage(WixErrors.DirectoryRootWithoutName(sourceLineNumbers, node.Name.LocalName, "Name")); 4108 this.Core.OnMessage(WixErrors.DirectoryRootWithoutName(sourceLineNumbers, node.Name.LocalName, "Name"));
4179 } 4109 }
4180 } 4110 }
4181 else if (!String.IsNullOrEmpty(name)) 4111 else if (!String.IsNullOrEmpty(name))
4182 { 4112 {
4183 if (String.IsNullOrEmpty(shortName)) 4113 if (String.IsNullOrEmpty(shortName))
4184 { 4114 {
4185 if (!name.Equals(".") && !name.Equals("SourceDir") && !this.core.IsValidShortFilename(name, false)) 4115 if (!name.Equals(".") && !name.Equals("SourceDir") && !this.Core.IsValidShortFilename(name, false))
4186 { 4116 {
4187 shortName = this.core.CreateShortName(name, false, false, "Directory", parentId); 4117 shortName = this.Core.CreateShortName(name, false, false, "Directory", parentId);
4188 } 4118 }
4189 } 4119 }
4190 else if (name.Equals(".")) 4120 else if (name.Equals("."))
4191 { 4121 {
4192 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "ShortName", "Name", name)); 4122 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "ShortName", "Name", name));
4193 } 4123 }
4194 else if (name.Equals(shortName)) 4124 else if (name.Equals(shortName))
4195 { 4125 {
4196 this.core.OnMessage(WixWarnings.DirectoryRedundantNames(sourceLineNumbers, node.Name.LocalName, "Name", "ShortName", name)); 4126 this.Core.OnMessage(WixWarnings.DirectoryRedundantNames(sourceLineNumbers, node.Name.LocalName, "Name", "ShortName", name));
4197 } 4127 }
4198 } 4128 }
4199 4129
@@ -4201,25 +4131,25 @@ namespace WixToolset
4201 { 4131 {
4202 if (!String.IsNullOrEmpty(shortSourceName)) 4132 if (!String.IsNullOrEmpty(shortSourceName))
4203 { 4133 {
4204 this.core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "ShortSourceName", "SourceName")); 4134 this.Core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "ShortSourceName", "SourceName"));
4205 } 4135 }
4206 } 4136 }
4207 else 4137 else
4208 { 4138 {
4209 if (String.IsNullOrEmpty(shortSourceName)) 4139 if (String.IsNullOrEmpty(shortSourceName))
4210 { 4140 {
4211 if (!sourceName.Equals(".") && !this.core.IsValidShortFilename(sourceName, false)) 4141 if (!sourceName.Equals(".") && !this.Core.IsValidShortFilename(sourceName, false))
4212 { 4142 {
4213 shortSourceName = this.core.CreateShortName(sourceName, false, false, "Directory", parentId); 4143 shortSourceName = this.Core.CreateShortName(sourceName, false, false, "Directory", parentId);
4214 } 4144 }
4215 } 4145 }
4216 else if (sourceName.Equals(".")) 4146 else if (sourceName.Equals("."))
4217 { 4147 {
4218 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "ShortSourceName", "SourceName", sourceName)); 4148 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "ShortSourceName", "SourceName", sourceName));
4219 } 4149 }
4220 else if (sourceName.Equals(shortSourceName)) 4150 else if (sourceName.Equals(shortSourceName))
4221 { 4151 {
4222 this.core.OnMessage(WixWarnings.DirectoryRedundantNames(sourceLineNumbers, node.Name.LocalName, "SourceName", "ShortSourceName", sourceName)); 4152 this.Core.OnMessage(WixWarnings.DirectoryRedundantNames(sourceLineNumbers, node.Name.LocalName, "SourceName", "ShortSourceName", sourceName));
4223 } 4153 }
4224 } 4154 }
4225 4155
@@ -4252,7 +4182,7 @@ namespace WixToolset
4252 4182
4253 if (null == id) 4183 if (null == id)
4254 { 4184 {
4255 id = this.core.CreateIdentifier("dir", parentId, name, shortName, sourceName, shortSourceName); 4185 id = this.Core.CreateIdentifier("dir", parentId, name, shortName, sourceName, shortSourceName);
4256 } 4186 }
4257 4187
4258 // Calculate the DefaultDir for the directory row. 4188 // Calculate the DefaultDir for the directory row.
@@ -4264,7 +4194,7 @@ namespace WixToolset
4264 4194
4265 if ("TARGETDIR".Equals(id.Id) && !"SourceDir".Equals(defaultDir)) 4195 if ("TARGETDIR".Equals(id.Id) && !"SourceDir".Equals(defaultDir))
4266 { 4196 {
4267 this.core.OnMessage(WixErrors.IllegalTargetDirDefaultDir(sourceLineNumbers, defaultDir)); 4197 this.Core.OnMessage(WixErrors.IllegalTargetDirDefaultDir(sourceLineNumbers, defaultDir));
4268 } 4198 }
4269 4199
4270 foreach (XElement child in node.Elements()) 4200 foreach (XElement child in node.Elements())
@@ -4293,32 +4223,32 @@ namespace WixToolset
4293 } 4223 }
4294 break; 4224 break;
4295 default: 4225 default:
4296 this.core.UnexpectedElement(node, child); 4226 this.Core.UnexpectedElement(node, child);
4297 break; 4227 break;
4298 } 4228 }
4299 } 4229 }
4300 else 4230 else
4301 { 4231 {
4302 this.core.ParseExtensionElement(node, child); 4232 this.Core.ParseExtensionElement(node, child);
4303 } 4233 }
4304 } 4234 }
4305 4235
4306 if (!this.core.EncounteredError) 4236 if (!this.Core.EncounteredError)
4307 { 4237 {
4308 Row row = this.core.CreateRow(sourceLineNumbers, "Directory", id); 4238 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Directory, id);
4309 row[1] = parentId; 4239 row.Set(1, parentId);
4310 row[2] = defaultDir; 4240 row.Set(2, defaultDir);
4311 4241
4312 if (null != componentGuidGenerationSeed) 4242 if (null != componentGuidGenerationSeed)
4313 { 4243 {
4314 Row wixRow = this.core.CreateRow(sourceLineNumbers, "WixDirectory"); 4244 var wixRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDirectory);
4315 wixRow[0] = id.Id; 4245 wixRow.Set(0, id.Id);
4316 wixRow[1] = componentGuidGenerationSeed; 4246 wixRow.Set(1, componentGuidGenerationSeed);
4317 } 4247 }
4318 4248
4319 if (null != symbols) 4249 if (null != symbols)
4320 { 4250 {
4321 WixDeltaPatchSymbolPathsRow symbolRow = (WixDeltaPatchSymbolPathsRow)this.core.CreateRow(sourceLineNumbers, "WixDeltaPatchSymbolPaths", id); 4251 var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths, id);
4322 symbolRow.Type = SymbolPathType.Directory; 4252 symbolRow.Type = SymbolPathType.Directory;
4323 symbolRow.SymbolPaths = symbols; 4253 symbolRow.SymbolPaths = symbols;
4324 } 4254 }
@@ -4344,29 +4274,29 @@ namespace WixToolset
4344 switch (attrib.Name.LocalName) 4274 switch (attrib.Name.LocalName)
4345 { 4275 {
4346 case "Id": 4276 case "Id":
4347 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 4277 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
4348 this.core.CreateSimpleReference(sourceLineNumbers, "Directory", id); 4278 this.Core.CreateSimpleReference(sourceLineNumbers, "Directory", id);
4349 break; 4279 break;
4350 case "DiskId": 4280 case "DiskId":
4351 diskId = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); 4281 diskId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue);
4352 break; 4282 break;
4353 case "FileSource": 4283 case "FileSource":
4354 fileSource = this.core.GetAttributeValue(sourceLineNumbers, attrib); 4284 fileSource = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4355 break; 4285 break;
4356 default: 4286 default:
4357 this.core.UnexpectedAttribute(node, attrib); 4287 this.Core.UnexpectedAttribute(node, attrib);
4358 break; 4288 break;
4359 } 4289 }
4360 } 4290 }
4361 else 4291 else
4362 { 4292 {
4363 this.core.ParseExtensionAttribute(node, attrib); 4293 this.Core.ParseExtensionAttribute(node, attrib);
4364 } 4294 }
4365 } 4295 }
4366 4296
4367 if (null == id) 4297 if (null == id)
4368 { 4298 {
4369 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 4299 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
4370 } 4300 }
4371 4301
4372 if (!String.IsNullOrEmpty(fileSource) && !fileSource.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) 4302 if (!String.IsNullOrEmpty(fileSource) && !fileSource.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
@@ -4390,13 +4320,13 @@ namespace WixToolset
4390 this.ParseMergeElement(child, id, diskId); 4320 this.ParseMergeElement(child, id, diskId);
4391 break; 4321 break;
4392 default: 4322 default:
4393 this.core.UnexpectedElement(node, child); 4323 this.Core.UnexpectedElement(node, child);
4394 break; 4324 break;
4395 } 4325 }
4396 } 4326 }
4397 else 4327 else
4398 { 4328 {
4399 this.core.ParseExtensionElement(node, child); 4329 this.Core.ParseExtensionElement(node, child);
4400 } 4330 }
4401 } 4331 }
4402 } 4332 }
@@ -4423,31 +4353,31 @@ namespace WixToolset
4423 switch (attrib.Name.LocalName) 4353 switch (attrib.Name.LocalName)
4424 { 4354 {
4425 case "Id": 4355 case "Id":
4426 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 4356 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
4427 break; 4357 break;
4428 case "Depth": 4358 case "Depth":
4429 depth = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 4359 depth = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
4430 break; 4360 break;
4431 case "Path": 4361 case "Path":
4432 path = this.core.GetAttributeValue(sourceLineNumbers, attrib); 4362 path = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4433 break; 4363 break;
4434 case "AssignToProperty": 4364 case "AssignToProperty":
4435 assignToProperty = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 4365 assignToProperty = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
4436 break; 4366 break;
4437 default: 4367 default:
4438 this.core.UnexpectedAttribute(node, attrib); 4368 this.Core.UnexpectedAttribute(node, attrib);
4439 break; 4369 break;
4440 } 4370 }
4441 } 4371 }
4442 else 4372 else
4443 { 4373 {
4444 this.core.ParseExtensionAttribute(node, attrib); 4374 this.Core.ParseExtensionAttribute(node, attrib);
4445 } 4375 }
4446 } 4376 }
4447 4377
4448 if (null == id) 4378 if (null == id)
4449 { 4379 {
4450 id = this.core.CreateIdentifier("dir", path, depth.ToString()); 4380 id = this.Core.CreateIdentifier("dir", path, depth.ToString());
4451 } 4381 }
4452 4382
4453 signature = id.Id; 4383 signature = id.Id;
@@ -4464,7 +4394,7 @@ namespace WixToolset
4464 case "DirectorySearch": 4394 case "DirectorySearch":
4465 if (oneChild) 4395 if (oneChild)
4466 { 4396 {
4467 this.core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName)); 4397 this.Core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName));
4468 } 4398 }
4469 oneChild = true; 4399 oneChild = true;
4470 signature = this.ParseDirectorySearchElement(child, id.Id); 4400 signature = this.ParseDirectorySearchElement(child, id.Id);
@@ -4472,7 +4402,7 @@ namespace WixToolset
4472 case "DirectorySearchRef": 4402 case "DirectorySearchRef":
4473 if (oneChild) 4403 if (oneChild)
4474 { 4404 {
4475 this.core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName)); 4405 this.Core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName));
4476 } 4406 }
4477 oneChild = true; 4407 oneChild = true;
4478 signature = this.ParseDirectorySearchRefElement(child, id.Id); 4408 signature = this.ParseDirectorySearchRefElement(child, id.Id);
@@ -4480,7 +4410,7 @@ namespace WixToolset
4480 case "FileSearch": 4410 case "FileSearch":
4481 if (oneChild) 4411 if (oneChild)
4482 { 4412 {
4483 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 4413 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
4484 } 4414 }
4485 oneChild = true; 4415 oneChild = true;
4486 hasFileSearch = true; 4416 hasFileSearch = true;
@@ -4489,13 +4419,13 @@ namespace WixToolset
4489 case "FileSearchRef": 4419 case "FileSearchRef":
4490 if (oneChild) 4420 if (oneChild)
4491 { 4421 {
4492 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 4422 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
4493 } 4423 }
4494 oneChild = true; 4424 oneChild = true;
4495 signature = this.ParseSimpleRefElement(child, "Signature"); 4425 signature = this.ParseSimpleRefElement(child, "Signature");
4496 break; 4426 break;
4497 default: 4427 default:
4498 this.core.UnexpectedElement(node, child); 4428 this.Core.UnexpectedElement(node, child);
4499 break; 4429 break;
4500 } 4430 }
4501 4431
@@ -4505,7 +4435,7 @@ namespace WixToolset
4505 { 4435 {
4506 if (!hasFileSearch) 4436 if (!hasFileSearch)
4507 { 4437 {
4508 this.core.OnMessage(WixErrors.IllegalParentAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "AssignToProperty", child.Name.LocalName)); 4438 this.Core.OnMessage(WixErrors.IllegalParentAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "AssignToProperty", child.Name.LocalName));
4509 } 4439 }
4510 else if (!oneChild) 4440 else if (!oneChild)
4511 { 4441 {
@@ -4516,11 +4446,11 @@ namespace WixToolset
4516 } 4446 }
4517 else 4447 else
4518 { 4448 {
4519 this.core.ParseExtensionElement(node, child); 4449 this.Core.ParseExtensionElement(node, child);
4520 } 4450 }
4521 } 4451 }
4522 4452
4523 if (!this.core.EncounteredError) 4453 if (!this.Core.EncounteredError)
4524 { 4454 {
4525 Identifier rowId = id; 4455 Identifier rowId = id;
4526 4456
@@ -4535,12 +4465,12 @@ namespace WixToolset
4535 signature = id.Id; 4465 signature = id.Id;
4536 } 4466 }
4537 4467
4538 Row row = this.core.CreateRow(sourceLineNumbers, "DrLocator", rowId); 4468 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.DrLocator, rowId);
4539 row[1] = parentSignature; 4469 row.Set(1, parentSignature);
4540 row[2] = path; 4470 row.Set(2, path);
4541 if (CompilerConstants.IntegerNotSet != depth) 4471 if (CompilerConstants.IntegerNotSet != depth)
4542 { 4472 {
4543 row[3] = depth; 4473 row.Set(3, depth);
4544 } 4474 }
4545 } 4475 }
4546 4476
@@ -4568,22 +4498,22 @@ namespace WixToolset
4568 switch (attrib.Name.LocalName) 4498 switch (attrib.Name.LocalName)
4569 { 4499 {
4570 case "Id": 4500 case "Id":
4571 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 4501 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
4572 break; 4502 break;
4573 case "Parent": 4503 case "Parent":
4574 parent = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 4504 parent = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
4575 break; 4505 break;
4576 case "Path": 4506 case "Path":
4577 path = this.core.GetAttributeValue(sourceLineNumbers, attrib); 4507 path = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4578 break; 4508 break;
4579 default: 4509 default:
4580 this.core.UnexpectedAttribute(node, attrib); 4510 this.Core.UnexpectedAttribute(node, attrib);
4581 break; 4511 break;
4582 } 4512 }
4583 } 4513 }
4584 else 4514 else
4585 { 4515 {
4586 this.core.ParseExtensionAttribute(node, attrib); 4516 this.Core.ParseExtensionAttribute(node, attrib);
4587 } 4517 }
4588 } 4518 }
4589 4519
@@ -4591,7 +4521,7 @@ namespace WixToolset
4591 { 4521 {
4592 if (!String.IsNullOrEmpty(parentSignature)) 4522 if (!String.IsNullOrEmpty(parentSignature))
4593 { 4523 {
4594 this.core.OnMessage(WixErrors.CanNotHaveTwoParents(sourceLineNumbers, id.Id, parent.Id, parentSignature)); 4524 this.Core.OnMessage(WixErrors.CanNotHaveTwoParents(sourceLineNumbers, id.Id, parent.Id, parentSignature));
4595 } 4525 }
4596 else 4526 else
4597 { 4527 {
@@ -4601,7 +4531,7 @@ namespace WixToolset
4601 4531
4602 if (null == id) 4532 if (null == id)
4603 { 4533 {
4604 id = this.core.CreateIdentifier("dsr", parentSignature, path); 4534 id = this.Core.CreateIdentifier("dsr", parentSignature, path);
4605 } 4535 }
4606 4536
4607 signature = id.Id; 4537 signature = id.Id;
@@ -4617,7 +4547,7 @@ namespace WixToolset
4617 case "DirectorySearch": 4547 case "DirectorySearch":
4618 if (oneChild) 4548 if (oneChild)
4619 { 4549 {
4620 this.core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName)); 4550 this.Core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName));
4621 } 4551 }
4622 oneChild = true; 4552 oneChild = true;
4623 signature = this.ParseDirectorySearchElement(child, id.Id); 4553 signature = this.ParseDirectorySearchElement(child, id.Id);
@@ -4625,7 +4555,7 @@ namespace WixToolset
4625 case "DirectorySearchRef": 4555 case "DirectorySearchRef":
4626 if (oneChild) 4556 if (oneChild)
4627 { 4557 {
4628 this.core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName)); 4558 this.Core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName));
4629 } 4559 }
4630 oneChild = true; 4560 oneChild = true;
4631 signature = this.ParseDirectorySearchRefElement(child, id.Id); 4561 signature = this.ParseDirectorySearchRefElement(child, id.Id);
@@ -4633,7 +4563,7 @@ namespace WixToolset
4633 case "FileSearch": 4563 case "FileSearch":
4634 if (oneChild) 4564 if (oneChild)
4635 { 4565 {
4636 this.core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName)); 4566 this.Core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName));
4637 } 4567 }
4638 oneChild = true; 4568 oneChild = true;
4639 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet); 4569 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet);
@@ -4641,24 +4571,24 @@ namespace WixToolset
4641 case "FileSearchRef": 4571 case "FileSearchRef":
4642 if (oneChild) 4572 if (oneChild)
4643 { 4573 {
4644 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 4574 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
4645 } 4575 }
4646 oneChild = true; 4576 oneChild = true;
4647 signature = this.ParseSimpleRefElement(child, "Signature"); 4577 signature = this.ParseSimpleRefElement(child, "Signature");
4648 break; 4578 break;
4649 default: 4579 default:
4650 this.core.UnexpectedElement(node, child); 4580 this.Core.UnexpectedElement(node, child);
4651 break; 4581 break;
4652 } 4582 }
4653 } 4583 }
4654 else 4584 else
4655 { 4585 {
4656 this.core.ParseExtensionElement(node, child); 4586 this.Core.ParseExtensionElement(node, child);
4657 } 4587 }
4658 } 4588 }
4659 4589
4660 4590
4661 this.core.CreateSimpleReference(sourceLineNumbers, "DrLocator", id.Id, parentSignature, path); 4591 this.Core.CreateSimpleReference(sourceLineNumbers, "DrLocator", id.Id, parentSignature, path);
4662 4592
4663 return signature; 4593 return signature;
4664 } 4594 }
@@ -4694,10 +4624,10 @@ namespace WixToolset
4694 switch (attrib.Name.LocalName) 4624 switch (attrib.Name.LocalName)
4695 { 4625 {
4696 case "Id": 4626 case "Id":
4697 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 4627 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
4698 break; 4628 break;
4699 case "Absent": 4629 case "Absent":
4700 string absent = this.core.GetAttributeValue(sourceLineNumbers, attrib); 4630 string absent = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4701 if (0 < absent.Length) 4631 if (0 < absent.Length)
4702 { 4632 {
4703 Wix.Feature.AbsentType absentType = Wix.Feature.ParseAbsentType(absent); 4633 Wix.Feature.AbsentType absentType = Wix.Feature.ParseAbsentType(absent);
@@ -4709,13 +4639,13 @@ namespace WixToolset
4709 bits = bits | MsiInterop.MsidbFeatureAttributesUIDisallowAbsent; 4639 bits = bits | MsiInterop.MsidbFeatureAttributesUIDisallowAbsent;
4710 break; 4640 break;
4711 default: 4641 default:
4712 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, absent, "allow", "disallow")); 4642 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, absent, "allow", "disallow"));
4713 break; 4643 break;
4714 } 4644 }
4715 } 4645 }
4716 break; 4646 break;
4717 case "AllowAdvertise": 4647 case "AllowAdvertise":
4718 allowAdvertise = this.core.GetAttributeValue(sourceLineNumbers, attrib); 4648 allowAdvertise = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4719 if (0 < allowAdvertise.Length) 4649 if (0 < allowAdvertise.Length)
4720 { 4650 {
4721 Wix.Feature.AllowAdvertiseType allowAdvertiseType = Wix.Feature.ParseAllowAdvertiseType(allowAdvertise); 4651 Wix.Feature.AllowAdvertiseType allowAdvertiseType = Wix.Feature.ParseAllowAdvertiseType(allowAdvertise);
@@ -4730,22 +4660,22 @@ namespace WixToolset
4730 case Wix.Feature.AllowAdvertiseType.yes: // this is the default 4660 case Wix.Feature.AllowAdvertiseType.yes: // this is the default
4731 break; 4661 break;
4732 default: 4662 default:
4733 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, allowAdvertise, "no", "system", "yes")); 4663 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, allowAdvertise, "no", "system", "yes"));
4734 break; 4664 break;
4735 } 4665 }
4736 } 4666 }
4737 break; 4667 break;
4738 case "ConfigurableDirectory": 4668 case "ConfigurableDirectory":
4739 configurableDirectory = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null); 4669 configurableDirectory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
4740 break; 4670 break;
4741 case "Description": 4671 case "Description":
4742 description = this.core.GetAttributeValue(sourceLineNumbers, attrib); 4672 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4743 break; 4673 break;
4744 case "Display": 4674 case "Display":
4745 display = this.core.GetAttributeValue(sourceLineNumbers, attrib); 4675 display = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4746 break; 4676 break;
4747 case "InstallDefault": 4677 case "InstallDefault":
4748 installDefault = this.core.GetAttributeValue(sourceLineNumbers, attrib); 4678 installDefault = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4749 if (0 < installDefault.Length) 4679 if (0 < installDefault.Length)
4750 { 4680 {
4751 Wix.Feature.InstallDefaultType installDefaultType = Wix.Feature.ParseInstallDefaultType(installDefault); 4681 Wix.Feature.InstallDefaultType installDefaultType = Wix.Feature.ParseInstallDefaultType(installDefault);
@@ -4754,7 +4684,7 @@ namespace WixToolset
4754 case Wix.Feature.InstallDefaultType.followParent: 4684 case Wix.Feature.InstallDefaultType.followParent:
4755 if (ComplexReferenceParentType.Product == parentType) 4685 if (ComplexReferenceParentType.Product == parentType)
4756 { 4686 {
4757 this.core.OnMessage(WixErrors.RootFeatureCannotFollowParent(sourceLineNumbers)); 4687 this.Core.OnMessage(WixErrors.RootFeatureCannotFollowParent(sourceLineNumbers));
4758 } 4688 }
4759 bits = bits | MsiInterop.MsidbFeatureAttributesFollowParent; 4689 bits = bits | MsiInterop.MsidbFeatureAttributesFollowParent;
4760 break; 4690 break;
@@ -4764,23 +4694,23 @@ namespace WixToolset
4764 bits = bits | MsiInterop.MsidbFeatureAttributesFavorSource; 4694 bits = bits | MsiInterop.MsidbFeatureAttributesFavorSource;
4765 break; 4695 break;
4766 default: 4696 default:
4767 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, installDefault, "followParent", "local", "source")); 4697 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, installDefault, "followParent", "local", "source"));
4768 break; 4698 break;
4769 } 4699 }
4770 } 4700 }
4771 break; 4701 break;
4772 case "Level": 4702 case "Level":
4773 level = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 4703 level = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
4774 break; 4704 break;
4775 case "Title": 4705 case "Title":
4776 title = this.core.GetAttributeValue(sourceLineNumbers, attrib); 4706 title = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4777 if ("PUT-FEATURE-TITLE-HERE" == title) 4707 if ("PUT-FEATURE-TITLE-HERE" == title)
4778 { 4708 {
4779 this.core.OnMessage(WixWarnings.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, title)); 4709 this.Core.OnMessage(WixWarnings.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, title));
4780 } 4710 }
4781 break; 4711 break;
4782 case "TypicalDefault": 4712 case "TypicalDefault":
4783 typicalDefault = this.core.GetAttributeValue(sourceLineNumbers, attrib); 4713 typicalDefault = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4784 if (0 < typicalDefault.Length) 4714 if (0 < typicalDefault.Length)
4785 { 4715 {
4786 Wix.Feature.TypicalDefaultType typicalDefaultType = Wix.Feature.ParseTypicalDefaultType(typicalDefault); 4716 Wix.Feature.TypicalDefaultType typicalDefaultType = Wix.Feature.ParseTypicalDefaultType(typicalDefault);
@@ -4792,45 +4722,45 @@ namespace WixToolset
4792 case Wix.Feature.TypicalDefaultType.install: // this is the default 4722 case Wix.Feature.TypicalDefaultType.install: // this is the default
4793 break; 4723 break;
4794 default: 4724 default:
4795 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, typicalDefault, "advertise", "install")); 4725 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, typicalDefault, "advertise", "install"));
4796 break; 4726 break;
4797 } 4727 }
4798 } 4728 }
4799 break; 4729 break;
4800 default: 4730 default:
4801 this.core.UnexpectedAttribute(node, attrib); 4731 this.Core.UnexpectedAttribute(node, attrib);
4802 break; 4732 break;
4803 } 4733 }
4804 } 4734 }
4805 else 4735 else
4806 { 4736 {
4807 this.core.ParseExtensionAttribute(node, attrib); 4737 this.Core.ParseExtensionAttribute(node, attrib);
4808 } 4738 }
4809 } 4739 }
4810 4740
4811 if (null == id) 4741 if (null == id)
4812 { 4742 {
4813 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 4743 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
4814 id = Identifier.Invalid; 4744 id = Identifier.Invalid;
4815 } 4745 }
4816 else if (38 < id.Id.Length) 4746 else if (38 < id.Id.Length)
4817 { 4747 {
4818 this.core.OnMessage(WixErrors.FeatureNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", id.Id)); 4748 this.Core.OnMessage(WixErrors.FeatureNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", id.Id));
4819 } 4749 }
4820 4750
4821 if (null != configurableDirectory && configurableDirectory.ToUpper(CultureInfo.InvariantCulture) != configurableDirectory) 4751 if (null != configurableDirectory && configurableDirectory.ToUpper(CultureInfo.InvariantCulture) != configurableDirectory)
4822 { 4752 {
4823 this.core.OnMessage(WixErrors.FeatureConfigurableDirectoryNotUppercase(sourceLineNumbers, node.Name.LocalName, "ConfigurableDirectory", configurableDirectory)); 4753 this.Core.OnMessage(WixErrors.FeatureConfigurableDirectoryNotUppercase(sourceLineNumbers, node.Name.LocalName, "ConfigurableDirectory", configurableDirectory));
4824 } 4754 }
4825 4755
4826 if ("advertise" == typicalDefault && "no" == allowAdvertise) 4756 if ("advertise" == typicalDefault && "no" == allowAdvertise)
4827 { 4757 {
4828 this.core.OnMessage(WixErrors.FeatureCannotFavorAndDisallowAdvertise(sourceLineNumbers, node.Name.LocalName, "TypicalDefault", typicalDefault, "AllowAdvertise", allowAdvertise)); 4758 this.Core.OnMessage(WixErrors.FeatureCannotFavorAndDisallowAdvertise(sourceLineNumbers, node.Name.LocalName, "TypicalDefault", typicalDefault, "AllowAdvertise", allowAdvertise));
4829 } 4759 }
4830 4760
4831 if (YesNoType.Yes == followParent && ("local" == installDefault || "source" == installDefault)) 4761 if (YesNoType.Yes == followParent && ("local" == installDefault || "source" == installDefault))
4832 { 4762 {
4833 this.core.OnMessage(WixErrors.FeatureCannotFollowParentAndFavorLocalOrSource(sourceLineNumbers, node.Name.LocalName, "InstallDefault", "FollowParent", "yes")); 4763 this.Core.OnMessage(WixErrors.FeatureCannotFollowParentAndFavorLocalOrSource(sourceLineNumbers, node.Name.LocalName, "InstallDefault", "FollowParent", "yes"));
4834 } 4764 }
4835 4765
4836 int childDisplay = 0; 4766 int childDisplay = 0;
@@ -4865,46 +4795,46 @@ namespace WixToolset
4865 this.ParseMergeRefElement(child, ComplexReferenceParentType.Feature, id.Id); 4795 this.ParseMergeRefElement(child, ComplexReferenceParentType.Feature, id.Id);
4866 break; 4796 break;
4867 default: 4797 default:
4868 this.core.UnexpectedElement(node, child); 4798 this.Core.UnexpectedElement(node, child);
4869 break; 4799 break;
4870 } 4800 }
4871 } 4801 }
4872 else 4802 else
4873 { 4803 {
4874 this.core.ParseExtensionElement(node, child); 4804 this.Core.ParseExtensionElement(node, child);
4875 } 4805 }
4876 } 4806 }
4877 4807
4878 if (!this.core.EncounteredError) 4808 if (!this.Core.EncounteredError)
4879 { 4809 {
4880 Row row = this.core.CreateRow(sourceLineNumbers, "Feature", id); 4810 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Feature, id);
4881 row[1] = null; // this column is set in the linker 4811 row.Set(1, null); // this column is set in the linker
4882 row[2] = title; 4812 row.Set(2, title);
4883 row[3] = description; 4813 row.Set(3, description);
4884 if (0 < display.Length) 4814 if (0 < display.Length)
4885 { 4815 {
4886 switch (display) 4816 switch (display)
4887 { 4817 {
4888 case "collapse": 4818 case "collapse":
4889 lastDisplay = (lastDisplay | 1) + 1; 4819 lastDisplay = (lastDisplay | 1) + 1;
4890 row[4] = lastDisplay; 4820 row.Set(4, lastDisplay);
4891 break; 4821 break;
4892 case "expand": 4822 case "expand":
4893 lastDisplay = (lastDisplay + 1) | 1; 4823 lastDisplay = (lastDisplay + 1) | 1;
4894 row[4] = lastDisplay; 4824 row.Set(4, lastDisplay);
4895 break; 4825 break;
4896 case "hidden": 4826 case "hidden":
4897 row[4] = 0; 4827 row.Set(4, 0);
4898 break; 4828 break;
4899 default: 4829 default:
4900 int value; 4830 int value;
4901 if (!Int32.TryParse(display, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) 4831 if (!Int32.TryParse(display, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
4902 { 4832 {
4903 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Display", display, "collapse", "expand", "hidden")); 4833 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Display", display, "collapse", "expand", "hidden"));
4904 } 4834 }
4905 else 4835 else
4906 { 4836 {
4907 row[4] = value; 4837 row.Set(4, value);
4908 // save the display value of this row (if its not hidden) for subsequent rows 4838 // save the display value of this row (if its not hidden) for subsequent rows
4909 if (0 != (int)row[4]) 4839 if (0 != (int)row[4])
4910 { 4840 {
@@ -4914,13 +4844,13 @@ namespace WixToolset
4914 break; 4844 break;
4915 } 4845 }
4916 } 4846 }
4917 row[5] = level; 4847 row.Set(5, level);
4918 row[6] = configurableDirectory; 4848 row.Set(6, configurableDirectory);
4919 row[7] = bits; 4849 row.Set(7, bits);
4920 4850
4921 if (ComplexReferenceParentType.Unknown != parentType) 4851 if (ComplexReferenceParentType.Unknown != parentType)
4922 { 4852 {
4923 this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Feature, id.Id, false); 4853 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Feature, id.Id, false);
4924 } 4854 }
4925 } 4855 }
4926 } 4856 }
@@ -4945,27 +4875,27 @@ namespace WixToolset
4945 switch (attrib.Name.LocalName) 4875 switch (attrib.Name.LocalName)
4946 { 4876 {
4947 case "Id": 4877 case "Id":
4948 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 4878 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
4949 this.core.CreateSimpleReference(sourceLineNumbers, "Feature", id); 4879 this.Core.CreateSimpleReference(sourceLineNumbers, "Feature", id);
4950 break; 4880 break;
4951 case "IgnoreParent": 4881 case "IgnoreParent":
4952 ignoreParent = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 4882 ignoreParent = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
4953 break; 4883 break;
4954 default: 4884 default:
4955 this.core.UnexpectedAttribute(node, attrib); 4885 this.Core.UnexpectedAttribute(node, attrib);
4956 break; 4886 break;
4957 } 4887 }
4958 } 4888 }
4959 else 4889 else
4960 { 4890 {
4961 this.core.ParseExtensionAttribute(node, attrib); 4891 this.Core.ParseExtensionAttribute(node, attrib);
4962 } 4892 }
4963 } 4893 }
4964 4894
4965 4895
4966 if (null == id) 4896 if (null == id)
4967 { 4897 {
4968 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 4898 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
4969 } 4899 }
4970 4900
4971 int lastDisplay = 0; 4901 int lastDisplay = 0;
@@ -5000,21 +4930,21 @@ namespace WixToolset
5000 this.ParseMergeRefElement(child, ComplexReferenceParentType.Feature, id); 4930 this.ParseMergeRefElement(child, ComplexReferenceParentType.Feature, id);
5001 break; 4931 break;
5002 default: 4932 default:
5003 this.core.UnexpectedElement(node, child); 4933 this.Core.UnexpectedElement(node, child);
5004 break; 4934 break;
5005 } 4935 }
5006 } 4936 }
5007 else 4937 else
5008 { 4938 {
5009 this.core.ParseExtensionElement(node, child); 4939 this.Core.ParseExtensionElement(node, child);
5010 } 4940 }
5011 } 4941 }
5012 4942
5013 if (!this.core.EncounteredError) 4943 if (!this.Core.EncounteredError)
5014 { 4944 {
5015 if (ComplexReferenceParentType.Unknown != parentType && YesNoType.Yes != ignoreParent) 4945 if (ComplexReferenceParentType.Unknown != parentType && YesNoType.Yes != ignoreParent)
5016 { 4946 {
5017 this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Feature, id, false); 4947 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Feature, id, false);
5018 } 4948 }
5019 } 4949 }
5020 } 4950 }
@@ -5036,22 +4966,22 @@ namespace WixToolset
5036 switch (attrib.Name.LocalName) 4966 switch (attrib.Name.LocalName)
5037 { 4967 {
5038 case "Id": 4968 case "Id":
5039 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 4969 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
5040 break; 4970 break;
5041 default: 4971 default:
5042 this.core.UnexpectedAttribute(node, attrib); 4972 this.Core.UnexpectedAttribute(node, attrib);
5043 break; 4973 break;
5044 } 4974 }
5045 } 4975 }
5046 else 4976 else
5047 { 4977 {
5048 this.core.ParseExtensionAttribute(node, attrib); 4978 this.Core.ParseExtensionAttribute(node, attrib);
5049 } 4979 }
5050 } 4980 }
5051 4981
5052 if (null == id) 4982 if (null == id)
5053 { 4983 {
5054 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 4984 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
5055 id = Identifier.Invalid; 4985 id = Identifier.Invalid;
5056 } 4986 }
5057 4987
@@ -5084,22 +5014,22 @@ namespace WixToolset
5084 this.ParseMergeRefElement(child, ComplexReferenceParentType.FeatureGroup, id.Id); 5014 this.ParseMergeRefElement(child, ComplexReferenceParentType.FeatureGroup, id.Id);
5085 break; 5015 break;
5086 default: 5016 default:
5087 this.core.UnexpectedElement(node, child); 5017 this.Core.UnexpectedElement(node, child);
5088 break; 5018 break;
5089 } 5019 }
5090 } 5020 }
5091 else 5021 else
5092 { 5022 {
5093 this.core.ParseExtensionElement(node, child); 5023 this.Core.ParseExtensionElement(node, child);
5094 } 5024 }
5095 } 5025 }
5096 5026
5097 if (!this.core.EncounteredError) 5027 if (!this.Core.EncounteredError)
5098 { 5028 {
5099 Row row = this.core.CreateRow(sourceLineNumbers, "WixFeatureGroup", id); 5029 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixFeatureGroup, id);
5100 5030
5101 //Add this FeatureGroup and its parent in WixGroup. 5031 //Add this FeatureGroup and its parent in WixGroup.
5102 this.core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.FeatureGroup, id.Id); 5032 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.FeatureGroup, id.Id);
5103 } 5033 }
5104 } 5034 }
5105 5035
@@ -5125,38 +5055,38 @@ namespace WixToolset
5125 switch (attrib.Name.LocalName) 5055 switch (attrib.Name.LocalName)
5126 { 5056 {
5127 case "Id": 5057 case "Id":
5128 id = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5058 id = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5129 this.core.CreateSimpleReference(sourceLineNumbers, "WixFeatureGroup", id); 5059 this.Core.CreateSimpleReference(sourceLineNumbers, "WixFeatureGroup", id);
5130 break; 5060 break;
5131 case "IgnoreParent": 5061 case "IgnoreParent":
5132 ignoreParent = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 5062 ignoreParent = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
5133 break; 5063 break;
5134 case "Primary": 5064 case "Primary":
5135 primary = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 5065 primary = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
5136 break; 5066 break;
5137 default: 5067 default:
5138 this.core.UnexpectedAttribute(node, attrib); 5068 this.Core.UnexpectedAttribute(node, attrib);
5139 break; 5069 break;
5140 } 5070 }
5141 } 5071 }
5142 else 5072 else
5143 { 5073 {
5144 this.core.ParseExtensionAttribute(node, attrib); 5074 this.Core.ParseExtensionAttribute(node, attrib);
5145 } 5075 }
5146 } 5076 }
5147 5077
5148 if (null == id) 5078 if (null == id)
5149 { 5079 {
5150 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 5080 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
5151 } 5081 }
5152 5082
5153 this.core.ParseForExtensionElements(node); 5083 this.Core.ParseForExtensionElements(node);
5154 5084
5155 if (!this.core.EncounteredError) 5085 if (!this.Core.EncounteredError)
5156 { 5086 {
5157 if (YesNoType.Yes != ignoreParent) 5087 if (YesNoType.Yes != ignoreParent)
5158 { 5088 {
5159 this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.FeatureGroup, id, (YesNoType.Yes == primary)); 5089 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.FeatureGroup, id, (YesNoType.Yes == primary));
5160 } 5090 }
5161 } 5091 }
5162 } 5092 }
@@ -5187,10 +5117,10 @@ namespace WixToolset
5187 switch (attrib.Name.LocalName) 5117 switch (attrib.Name.LocalName)
5188 { 5118 {
5189 case "Id": 5119 case "Id":
5190 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 5120 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
5191 break; 5121 break;
5192 case "Action": 5122 case "Action":
5193 string value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5123 string value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5194 if (0 < value.Length) 5124 if (0 < value.Length)
5195 { 5125 {
5196 Wix.Environment.ActionType actionType = Wix.Environment.ParseActionType(value); 5126 Wix.Environment.ActionType actionType = Wix.Environment.ParseActionType(value);
@@ -5206,59 +5136,59 @@ namespace WixToolset
5206 action = "!"; 5136 action = "!";
5207 break; 5137 break;
5208 default: 5138 default:
5209 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "create", "set", "remove")); 5139 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "create", "set", "remove"));
5210 break; 5140 break;
5211 } 5141 }
5212 } 5142 }
5213 break; 5143 break;
5214 case "Name": 5144 case "Name":
5215 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5145 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5216 break; 5146 break;
5217 case "Part": 5147 case "Part":
5218 part = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5148 part = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5219 if (!Wix.Environment.TryParsePartType(part, out partType)) 5149 if (!Wix.Environment.TryParsePartType(part, out partType))
5220 { 5150 {
5221 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Part", part, "all", "first", "last")); 5151 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Part", part, "all", "first", "last"));
5222 } 5152 }
5223 break; 5153 break;
5224 case "Permanent": 5154 case "Permanent":
5225 permanent = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 5155 permanent = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
5226 break; 5156 break;
5227 case "Separator": 5157 case "Separator":
5228 separator = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5158 separator = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5229 break; 5159 break;
5230 case "System": 5160 case "System":
5231 system = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 5161 system = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
5232 break; 5162 break;
5233 case "Value": 5163 case "Value":
5234 text = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5164 text = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5235 break; 5165 break;
5236 default: 5166 default:
5237 this.core.UnexpectedAttribute(node, attrib); 5167 this.Core.UnexpectedAttribute(node, attrib);
5238 break; 5168 break;
5239 } 5169 }
5240 } 5170 }
5241 else 5171 else
5242 { 5172 {
5243 this.core.ParseExtensionAttribute(node, attrib); 5173 this.Core.ParseExtensionAttribute(node, attrib);
5244 } 5174 }
5245 } 5175 }
5246 5176
5247 if (null == id) 5177 if (null == id)
5248 { 5178 {
5249 id = this.core.CreateIdentifier("env", action, name, part, system.ToString()); 5179 id = this.Core.CreateIdentifier("env", action, name, part, system.ToString());
5250 } 5180 }
5251 5181
5252 if (null == name) 5182 if (null == name)
5253 { 5183 {
5254 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 5184 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
5255 } 5185 }
5256 5186
5257 if (Wix.Environment.PartType.NotSet != partType) 5187 if (Wix.Environment.PartType.NotSet != partType)
5258 { 5188 {
5259 if ("+" == action) 5189 if ("+" == action)
5260 { 5190 {
5261 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Part", "Action", "create")); 5191 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Part", "Action", "create"));
5262 } 5192 }
5263 5193
5264 switch (partType) 5194 switch (partType)
@@ -5279,14 +5209,14 @@ namespace WixToolset
5279 uninstall = null; 5209 uninstall = null;
5280 } 5210 }
5281 5211
5282 this.core.ParseForExtensionElements(node); 5212 this.Core.ParseForExtensionElements(node);
5283 5213
5284 if (!this.core.EncounteredError) 5214 if (!this.Core.EncounteredError)
5285 { 5215 {
5286 Row row = this.core.CreateRow(sourceLineNumbers, "Environment", id); 5216 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Environment, id);
5287 row[1] = String.Concat(action, uninstall, system ? "*" : String.Empty, name); 5217 row.Set(1, String.Concat(action, uninstall, system ? "*" : String.Empty, name));
5288 row[2] = text; 5218 row.Set(2, text);
5289 row[3] = componentId; 5219 row.Set(3, componentId);
5290 } 5220 }
5291 } 5221 }
5292 5222
@@ -5306,32 +5236,32 @@ namespace WixToolset
5306 switch (attrib.Name.LocalName) 5236 switch (attrib.Name.LocalName)
5307 { 5237 {
5308 case "Id": 5238 case "Id":
5309 id = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 5239 id = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
5310 break; 5240 break;
5311 default: 5241 default:
5312 this.core.UnexpectedAttribute(node, attrib); 5242 this.Core.UnexpectedAttribute(node, attrib);
5313 break; 5243 break;
5314 } 5244 }
5315 } 5245 }
5316 else 5246 else
5317 { 5247 {
5318 this.core.ParseExtensionAttribute(node, attrib); 5248 this.Core.ParseExtensionAttribute(node, attrib);
5319 } 5249 }
5320 } 5250 }
5321 5251
5322 if (CompilerConstants.IntegerNotSet == id) 5252 if (CompilerConstants.IntegerNotSet == id)
5323 { 5253 {
5324 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 5254 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
5325 id = CompilerConstants.IllegalInteger; 5255 id = CompilerConstants.IllegalInteger;
5326 } 5256 }
5327 5257
5328 this.core.ParseForExtensionElements(node); 5258 this.Core.ParseForExtensionElements(node);
5329 5259
5330 if (!this.core.EncounteredError) 5260 if (!this.Core.EncounteredError)
5331 { 5261 {
5332 Row row = this.core.CreateRow(sourceLineNumbers, "Error"); 5262 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Error);
5333 row[0] = id; 5263 row.Set(0, id);
5334 row[1] = Common.GetInnerText(node); // TODO: * 5264 row.Set(1, Common.GetInnerText(node)); // TODO: *
5335 } 5265 }
5336 } 5266 }
5337 5267
@@ -5355,28 +5285,28 @@ namespace WixToolset
5355 switch (attrib.Name.LocalName) 5285 switch (attrib.Name.LocalName)
5356 { 5286 {
5357 case "Id": 5287 case "Id":
5358 extension = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5288 extension = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5359 break; 5289 break;
5360 case "Advertise": 5290 case "Advertise":
5361 YesNoType extensionAdvertise = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 5291 YesNoType extensionAdvertise = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
5362 if ((YesNoType.No == advertise && YesNoType.Yes == extensionAdvertise) || (YesNoType.Yes == advertise && YesNoType.No == extensionAdvertise)) 5292 if ((YesNoType.No == advertise && YesNoType.Yes == extensionAdvertise) || (YesNoType.Yes == advertise && YesNoType.No == extensionAdvertise))
5363 { 5293 {
5364 this.core.OnMessage(WixErrors.AdvertiseStateMustMatch(sourceLineNumbers, extensionAdvertise.ToString(), advertise.ToString())); 5294 this.Core.OnMessage(WixErrors.AdvertiseStateMustMatch(sourceLineNumbers, extensionAdvertise.ToString(), advertise.ToString()));
5365 } 5295 }
5366 advertise = extensionAdvertise; 5296 advertise = extensionAdvertise;
5367 break; 5297 break;
5368 case "ContentType": 5298 case "ContentType":
5369 mime = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5299 mime = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5370 break; 5300 break;
5371 default: 5301 default:
5372 this.core.UnexpectedAttribute(node, attrib); 5302 this.Core.UnexpectedAttribute(node, attrib);
5373 break; 5303 break;
5374 } 5304 }
5375 } 5305 }
5376 else 5306 else
5377 { 5307 {
5378 Dictionary<string, string> context = new Dictionary<string, string>() { { "ProgId", progId }, { "ComponentId", componentId } }; 5308 Dictionary<string, string> context = new Dictionary<string, string>() { { "ProgId", progId }, { "ComponentId", componentId } };
5379 this.core.ParseExtensionAttribute(node, attrib, context); 5309 this.Core.ParseExtensionAttribute(node, attrib, context);
5380 } 5310 }
5381 } 5311 }
5382 5312
@@ -5402,37 +5332,37 @@ namespace WixToolset
5402 } 5332 }
5403 break; 5333 break;
5404 default: 5334 default:
5405 this.core.UnexpectedElement(node, child); 5335 this.Core.UnexpectedElement(node, child);
5406 break; 5336 break;
5407 } 5337 }
5408 } 5338 }
5409 else 5339 else
5410 { 5340 {
5411 this.core.ParseExtensionElement(node, child); 5341 this.Core.ParseExtensionElement(node, child);
5412 } 5342 }
5413 } 5343 }
5414 5344
5415 5345
5416 if (YesNoType.Yes == advertise) 5346 if (YesNoType.Yes == advertise)
5417 { 5347 {
5418 if (!this.core.EncounteredError) 5348 if (!this.Core.EncounteredError)
5419 { 5349 {
5420 Row row = this.core.CreateRow(sourceLineNumbers, "Extension"); 5350 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Extension);
5421 row[0] = extension; 5351 row.Set(0, extension);
5422 row[1] = componentId; 5352 row.Set(1, componentId);
5423 row[2] = progId; 5353 row.Set(2, progId);
5424 row[3] = mime; 5354 row.Set(3, mime);
5425 row[4] = Guid.Empty.ToString("B"); 5355 row.Set(4, Guid.Empty.ToString("B"));
5426 5356
5427 this.core.EnsureTable(sourceLineNumbers, "Verb"); 5357 this.Core.EnsureTable(sourceLineNumbers, "Verb");
5428 } 5358 }
5429 } 5359 }
5430 else if (YesNoType.No == advertise) 5360 else if (YesNoType.No == advertise)
5431 { 5361 {
5432 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(".", extension), String.Empty, progId, componentId); // Extension 5362 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(".", extension), String.Empty, progId, componentId); // Extension
5433 if (null != mime) 5363 if (null != mime)
5434 { 5364 {
5435 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(".", extension), "Content Type", mime, componentId); // Extension's MIME ContentType 5365 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(".", extension), "Content Type", mime, componentId); // Extension's MIME ContentType
5436 } 5366 }
5437 } 5367 }
5438 } 5368 }
@@ -5458,7 +5388,15 @@ namespace WixToolset
5458 string assemblyApplication = null; 5388 string assemblyApplication = null;
5459 string assemblyManifest = null; 5389 string assemblyManifest = null;
5460 string bindPath = null; 5390 string bindPath = null;
5461 int bits = MsiInterop.MsidbFileAttributesVital; // assume all files are vital. 5391
5392 //int bits = MsiInterop.MsidbFileAttributesVital;
5393 bool readOnly = false;
5394 bool checksum = false;
5395 bool? compressed = null;
5396 bool hidden = false;
5397 bool system = false;
5398 bool vital = true; // assume all files are vital.
5399
5462 string companionFile = null; 5400 string companionFile = null;
5463 string defaultLanguage = null; 5401 string defaultLanguage = null;
5464 int defaultSize = 0; 5402 int defaultSize = 0;
@@ -5491,10 +5429,10 @@ namespace WixToolset
5491 switch (attrib.Name.LocalName) 5429 switch (attrib.Name.LocalName)
5492 { 5430 {
5493 case "Id": 5431 case "Id":
5494 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 5432 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
5495 break; 5433 break;
5496 case "Assembly": 5434 case "Assembly":
5497 string assemblyValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5435 string assemblyValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5498 if (0 < assemblyValue.Length) 5436 if (0 < assemblyValue.Length)
5499 { 5437 {
5500 Wix.File.AssemblyType parsedAssemblyType = Wix.File.ParseAssemblyType(assemblyValue); 5438 Wix.File.AssemblyType parsedAssemblyType = Wix.File.ParseAssemblyType(assemblyValue);
@@ -5510,84 +5448,88 @@ namespace WixToolset
5510 assemblyType = FileAssemblyType.Win32Assembly; 5448 assemblyType = FileAssemblyType.Win32Assembly;
5511 break; 5449 break;
5512 default: 5450 default:
5513 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "File", "Assembly", assemblyValue, "no", "win32", ".net")); 5451 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "File", "Assembly", assemblyValue, "no", "win32", ".net"));
5514 break; 5452 break;
5515 } 5453 }
5516 } 5454 }
5517 break; 5455 break;
5518 case "AssemblyApplication": 5456 case "AssemblyApplication":
5519 assemblyApplication = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 5457 assemblyApplication = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
5520 this.core.CreateSimpleReference(sourceLineNumbers, "File", assemblyApplication); 5458 this.Core.CreateSimpleReference(sourceLineNumbers, "File", assemblyApplication);
5521 break; 5459 break;
5522 case "AssemblyManifest": 5460 case "AssemblyManifest":
5523 assemblyManifest = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 5461 assemblyManifest = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
5524 this.core.CreateSimpleReference(sourceLineNumbers, "File", assemblyManifest); 5462 this.Core.CreateSimpleReference(sourceLineNumbers, "File", assemblyManifest);
5525 break; 5463 break;
5526 case "BindPath": 5464 case "BindPath":
5527 bindPath = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 5465 bindPath = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
5528 break; 5466 break;
5529 case "Checksum": 5467 case "Checksum":
5530 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 5468 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
5531 { 5469 {
5532 bits |= MsiInterop.MsidbFileAttributesChecksum; 5470 checksum = true;
5471 //bits |= MsiInterop.MsidbFileAttributesChecksum;
5533 } 5472 }
5534 break; 5473 break;
5535 case "CompanionFile": 5474 case "CompanionFile":
5536 companionFile = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 5475 companionFile = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
5537 this.core.CreateSimpleReference(sourceLineNumbers, "File", companionFile); 5476 this.Core.CreateSimpleReference(sourceLineNumbers, "File", companionFile);
5538 break; 5477 break;
5539 case "Compressed": 5478 case "Compressed":
5540 YesNoDefaultType compressed = this.core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); 5479 YesNoDefaultType compressedValue = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
5541 if (YesNoDefaultType.Yes == compressed) 5480 if (YesNoDefaultType.Yes == compressedValue)
5542 { 5481 {
5543 bits |= MsiInterop.MsidbFileAttributesCompressed; 5482 compressed = true;
5483 //bits |= MsiInterop.MsidbFileAttributesCompressed;
5544 } 5484 }
5545 else if (YesNoDefaultType.No == compressed) 5485 else if (YesNoDefaultType.No == compressedValue)
5546 { 5486 {
5547 bits |= MsiInterop.MsidbFileAttributesNoncompressed; 5487 compressed = false;
5488 //bits |= MsiInterop.MsidbFileAttributesNoncompressed;
5548 } 5489 }
5549 break; 5490 break;
5550 case "DefaultLanguage": 5491 case "DefaultLanguage":
5551 defaultLanguage = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5492 defaultLanguage = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5552 break; 5493 break;
5553 case "DefaultSize": 5494 case "DefaultSize":
5554 defaultSize = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 5495 defaultSize = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
5555 break; 5496 break;
5556 case "DefaultVersion": 5497 case "DefaultVersion":
5557 defaultVersion = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5498 defaultVersion = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5558 break; 5499 break;
5559 case "DiskId": 5500 case "DiskId":
5560 diskId = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); 5501 diskId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue);
5561 break; 5502 break;
5562 case "FontTitle": 5503 case "FontTitle":
5563 fontTitle = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5504 fontTitle = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5564 break; 5505 break;
5565 case "Hidden": 5506 case "Hidden":
5566 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 5507 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
5567 { 5508 {
5568 bits |= MsiInterop.MsidbFileAttributesHidden; 5509 hidden = true;
5510 //bits |= MsiInterop.MsidbFileAttributesHidden;
5569 } 5511 }
5570 break; 5512 break;
5571 case "KeyPath": 5513 case "KeyPath":
5572 keyPath = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 5514 keyPath = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
5573 break; 5515 break;
5574 case "Name": 5516 case "Name":
5575 name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); 5517 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
5576 break; 5518 break;
5577 case "PatchGroup": 5519 case "PatchGroup":
5578 patchGroup = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, int.MaxValue); 5520 patchGroup = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, int.MaxValue);
5579 break; 5521 break;
5580 case "PatchIgnore": 5522 case "PatchIgnore":
5581 patchIgnore = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 5523 patchIgnore = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
5582 break; 5524 break;
5583 case "PatchWholeFile": 5525 case "PatchWholeFile":
5584 patchIncludeWholeFile = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 5526 patchIncludeWholeFile = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
5585 break; 5527 break;
5586 case "PatchAllowIgnoreOnError": 5528 case "PatchAllowIgnoreOnError":
5587 patchAllowIgnoreOnError = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 5529 patchAllowIgnoreOnError = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
5588 break; 5530 break;
5589 case "ProcessorArchitecture": 5531 case "ProcessorArchitecture":
5590 string procArchValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5532 string procArchValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5591 if (0 < procArchValue.Length) 5533 if (0 < procArchValue.Length)
5592 { 5534 {
5593 Wix.File.ProcessorArchitectureType procArchType = Wix.File.ParseProcessorArchitectureType(procArchValue); 5535 Wix.File.ProcessorArchitectureType procArchType = Wix.File.ParseProcessorArchitectureType(procArchValue);
@@ -5606,58 +5548,62 @@ namespace WixToolset
5606 procArch = "ia64"; 5548 procArch = "ia64";
5607 break; 5549 break;
5608 default: 5550 default:
5609 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "File", "ProcessorArchitecture", procArchValue, "msil", "x86", "x64", "ia64")); 5551 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "File", "ProcessorArchitecture", procArchValue, "msil", "x86", "x64", "ia64"));
5610 break; 5552 break;
5611 } 5553 }
5612 } 5554 }
5613 break; 5555 break;
5614 case "ReadOnly": 5556 case "ReadOnly":
5615 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 5557 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
5616 { 5558 {
5617 bits |= MsiInterop.MsidbFileAttributesReadOnly; 5559 readOnly = true;
5560 //bits |= MsiInterop.MsidbFileAttributesReadOnly;
5618 } 5561 }
5619 break; 5562 break;
5620 case "SelfRegCost": 5563 case "SelfRegCost":
5621 selfRegCost = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 5564 selfRegCost = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
5622 break; 5565 break;
5623 case "ShortName": 5566 case "ShortName":
5624 shortName = this.core.GetAttributeShortFilename(sourceLineNumbers, attrib, false); 5567 shortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, false);
5625 break; 5568 break;
5626 case "Source": 5569 case "Source":
5627 source = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5570 source = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5628 sourceSet = true; 5571 sourceSet = true;
5629 break; 5572 break;
5630 case "System": 5573 case "System":
5631 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 5574 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
5632 { 5575 {
5633 bits |= MsiInterop.MsidbFileAttributesSystem; 5576 system = true;
5577 //bits |= MsiInterop.MsidbFileAttributesSystem;
5634 } 5578 }
5635 break; 5579 break;
5636 case "TrueType": 5580 case "TrueType":
5637 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 5581 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
5638 { 5582 {
5639 fontTitle = String.Empty; 5583 fontTitle = String.Empty;
5640 } 5584 }
5641 break; 5585 break;
5642 case "Vital": 5586 case "Vital":
5643 YesNoType isVital = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 5587 YesNoType isVital = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
5644 if (YesNoType.Yes == isVital) 5588 if (YesNoType.Yes == isVital)
5645 { 5589 {
5646 bits |= MsiInterop.MsidbFileAttributesVital; 5590 vital = true;
5591 //bits |= MsiInterop.MsidbFileAttributesVital;
5647 } 5592 }
5648 else if (YesNoType.No == isVital) 5593 else if (YesNoType.No == isVital)
5649 { 5594 {
5650 bits &= ~MsiInterop.MsidbFileAttributesVital; 5595 vital = false;
5596 //bits &= ~MsiInterop.MsidbFileAttributesVital;
5651 } 5597 }
5652 break; 5598 break;
5653 default: 5599 default:
5654 this.core.UnexpectedAttribute(node, attrib); 5600 this.Core.UnexpectedAttribute(node, attrib);
5655 break; 5601 break;
5656 } 5602 }
5657 } 5603 }
5658 else 5604 else
5659 { 5605 {
5660 this.core.ParseExtensionAttribute(node, attrib); 5606 this.Core.ParseExtensionAttribute(node, attrib);
5661 } 5607 }
5662 } 5608 }
5663 5609
@@ -5666,29 +5612,29 @@ namespace WixToolset
5666 // the companion file cannot be the key path of a component 5612 // the companion file cannot be the key path of a component
5667 if (YesNoType.Yes == keyPath) 5613 if (YesNoType.Yes == keyPath)
5668 { 5614 {
5669 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "CompanionFile", "KeyPath", "yes")); 5615 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "CompanionFile", "KeyPath", "yes"));
5670 } 5616 }
5671 } 5617 }
5672 5618
5673 if (sourceSet && !source.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal) && null == name) 5619 if (sourceSet && !source.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal) && null == name)
5674 { 5620 {
5675 name = Path.GetFileName(source); 5621 name = Path.GetFileName(source);
5676 if (!this.core.IsValidLongFilename(name, false)) 5622 if (!this.Core.IsValidLongFilename(name, false))
5677 { 5623 {
5678 this.core.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Source", name)); 5624 this.Core.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Source", name));
5679 } 5625 }
5680 } 5626 }
5681 5627
5682 // generate a short file name 5628 // generate a short file name
5683 if (null == shortName && (null != name && !this.core.IsValidShortFilename(name, false))) 5629 if (null == shortName && (null != name && !this.Core.IsValidShortFilename(name, false)))
5684 { 5630 {
5685 shortName = this.core.CreateShortName(name, true, false, node.Name.LocalName, directoryId); 5631 shortName = this.Core.CreateShortName(name, true, false, node.Name.LocalName, directoryId);
5686 generatedShortFileName = true; 5632 generatedShortFileName = true;
5687 } 5633 }
5688 5634
5689 if (null == id) 5635 if (null == id)
5690 { 5636 {
5691 id = this.core.CreateIdentifier("fil", directoryId, name ?? shortName); 5637 id = this.Core.CreateIdentifier("fil", directoryId, name ?? shortName);
5692 } 5638 }
5693 5639
5694 if (!this.compilingModule && CompilerConstants.IntegerNotSet == diskId) 5640 if (!this.compilingModule && CompilerConstants.IntegerNotSet == diskId)
@@ -5698,32 +5644,32 @@ namespace WixToolset
5698 5644
5699 if (null != defaultVersion && null != companionFile) 5645 if (null != defaultVersion && null != companionFile)
5700 { 5646 {
5701 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DefaultVersion", "CompanionFile", companionFile)); 5647 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DefaultVersion", "CompanionFile", companionFile));
5702 } 5648 }
5703 5649
5704 if (FileAssemblyType.NotAnAssembly == assemblyType) 5650 if (FileAssemblyType.NotAnAssembly == assemblyType)
5705 { 5651 {
5706 if (null != assemblyManifest) 5652 if (null != assemblyManifest)
5707 { 5653 {
5708 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Assembly", "AssemblyManifest")); 5654 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Assembly", "AssemblyManifest"));
5709 } 5655 }
5710 5656
5711 if (null != assemblyApplication) 5657 if (null != assemblyApplication)
5712 { 5658 {
5713 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Assembly", "AssemblyApplication")); 5659 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Assembly", "AssemblyApplication"));
5714 } 5660 }
5715 } 5661 }
5716 else 5662 else
5717 { 5663 {
5718 if (FileAssemblyType.Win32Assembly == assemblyType && null == assemblyManifest) 5664 if (FileAssemblyType.Win32Assembly == assemblyType && null == assemblyManifest)
5719 { 5665 {
5720 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "AssemblyManifest", "Assembly", "win32")); 5666 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "AssemblyManifest", "Assembly", "win32"));
5721 } 5667 }
5722 5668
5723 // allow "*" guid components to omit explicit KeyPath as they can have only one file and therefore this file is the keypath 5669 // allow "*" guid components to omit explicit KeyPath as they can have only one file and therefore this file is the keypath
5724 if (YesNoType.Yes != keyPath && "*" != componentGuid) 5670 if (YesNoType.Yes != keyPath && "*" != componentGuid)
5725 { 5671 {
5726 this.core.OnMessage(WixErrors.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Assembly", (FileAssemblyType.DotNetAssembly == assemblyType ? ".net" : "win32"), "KeyPath", "yes")); 5672 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Assembly", (FileAssemblyType.DotNetAssembly == assemblyType ? ".net" : "win32"), "KeyPath", "yes"));
5727 } 5673 }
5728 } 5674 }
5729 5675
@@ -5749,10 +5695,10 @@ namespace WixToolset
5749 this.ParseRangeElement(child, ref ignoreOffsets, ref ignoreLengths); 5695 this.ParseRangeElement(child, ref ignoreOffsets, ref ignoreLengths);
5750 break; 5696 break;
5751 case "ODBCDriver": 5697 case "ODBCDriver":
5752 this.ParseODBCDriverOrTranslator(child, componentId, id.Id, this.tableDefinitions["ODBCDriver"]); 5698 this.ParseODBCDriverOrTranslator(child, componentId, id.Id, TupleDefinitionType.ODBCDriver);
5753 break; 5699 break;
5754 case "ODBCTranslator": 5700 case "ODBCTranslator":
5755 this.ParseODBCDriverOrTranslator(child, componentId, id.Id, this.tableDefinitions["ODBCTranslator"]); 5701 this.ParseODBCDriverOrTranslator(child, componentId, id.Id, TupleDefinitionType.ODBCTranslator);
5756 break; 5702 break;
5757 case "Permission": 5703 case "Permission":
5758 this.ParsePermissionElement(child, id.Id, "File"); 5704 this.ParsePermissionElement(child, id.Id, "File");
@@ -5780,19 +5726,19 @@ namespace WixToolset
5780 this.ParseTypeLibElement(child, componentId, id.Id, win64Component); 5726 this.ParseTypeLibElement(child, componentId, id.Id, win64Component);
5781 break; 5727 break;
5782 default: 5728 default:
5783 this.core.UnexpectedElement(node, child); 5729 this.Core.UnexpectedElement(node, child);
5784 break; 5730 break;
5785 } 5731 }
5786 } 5732 }
5787 else 5733 else
5788 { 5734 {
5789 Dictionary<string, string> context = new Dictionary<string, string>() { { "FileId", id.Id }, { "ComponentId", componentId }, { "Win64", win64Component.ToString() } }; 5735 Dictionary<string, string> context = new Dictionary<string, string>() { { "FileId", id.Id }, { "ComponentId", componentId }, { "Win64", win64Component.ToString() } };
5790 this.core.ParseExtensionElement(node, child, context); 5736 this.Core.ParseExtensionElement(node, child, context);
5791 } 5737 }
5792 } 5738 }
5793 5739
5794 5740
5795 if (!this.core.EncounteredError) 5741 if (!this.Core.EncounteredError)
5796 { 5742 {
5797 PatchAttributeType patchAttributes = PatchAttributeType.None; 5743 PatchAttributeType patchAttributes = PatchAttributeType.None;
5798 if (patchIgnore) 5744 if (patchIgnore)
@@ -5831,28 +5777,34 @@ namespace WixToolset
5831 } 5777 }
5832 } 5778 }
5833 5779
5834 FileRow fileRow = (FileRow)this.core.CreateRow(sourceLineNumbers, "File", id); 5780 var fileRow = (FileTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.File, id);
5835 fileRow[1] = componentId; 5781 fileRow.Component_ = componentId;
5836 fileRow[2] = GetMsiFilenameValue(shortName, name); 5782 //fileRow.FileName = GetMsiFilenameValue(shortName, name);
5837 fileRow[3] = defaultSize; 5783 fileRow.ShortFileName = shortName;
5784 fileRow.LongFileName = name;
5785 fileRow.FileSize = defaultSize;
5838 if (null != companionFile) 5786 if (null != companionFile)
5839 { 5787 {
5840 fileRow[4] = companionFile; 5788 fileRow.Version = companionFile;
5841 } 5789 }
5842 else if (null != defaultVersion) 5790 else if (null != defaultVersion)
5843 { 5791 {
5844 fileRow[4] = defaultVersion; 5792 fileRow.Version = defaultVersion;
5845 } 5793 }
5846 fileRow[5] = defaultLanguage; 5794 fileRow.Language = defaultLanguage;
5847 fileRow[6] = bits; 5795 fileRow.ReadOnly = readOnly;
5848 5796 fileRow.Checksum = checksum;
5797 fileRow.Compressed = compressed;
5798 fileRow.Hidden = hidden;
5799 fileRow.System = system;
5800 fileRow.Vital = vital;
5849 // the Sequence row is set in the binder 5801 // the Sequence row is set in the binder
5850 5802
5851 WixFileRow wixFileRow = (WixFileRow)this.core.CreateRow(sourceLineNumbers, "WixFile", id); 5803 var wixFileRow = (WixFileTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixFile, id);
5852 wixFileRow.AssemblyType = assemblyType; 5804 wixFileRow.AssemblyType = assemblyType;
5853 wixFileRow.AssemblyManifest = assemblyManifest; 5805 wixFileRow.File_AssemblyManifest = assemblyManifest;
5854 wixFileRow.AssemblyApplication = assemblyApplication; 5806 wixFileRow.File_AssemblyApplication = assemblyApplication;
5855 wixFileRow.Directory = directoryId; 5807 wixFileRow.Directory_ = directoryId;
5856 wixFileRow.DiskId = (CompilerConstants.IntegerNotSet == diskId) ? 0 : diskId; 5808 wixFileRow.DiskId = (CompilerConstants.IntegerNotSet == diskId) ? 0 : diskId;
5857 wixFileRow.Source = source; 5809 wixFileRow.Source = source;
5858 wixFileRow.ProcessorArchitecture = procArch; 5810 wixFileRow.ProcessorArchitecture = procArch;
@@ -5862,7 +5814,7 @@ namespace WixToolset
5862 5814
5863 // Always create a delta patch row for this file since other elements (like Component and Media) may 5815 // Always create a delta patch row for this file since other elements (like Component and Media) may
5864 // want to add symbol paths to it. 5816 // want to add symbol paths to it.
5865 WixDeltaPatchFileRow deltaPatchFileRow = (WixDeltaPatchFileRow)this.core.CreateRow(sourceLineNumbers, "WixDeltaPatchFile", id); 5817 var deltaPatchFileRow = (WixDeltaPatchFileTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchFile, id);
5866 deltaPatchFileRow.RetainLengths = protectLengths; 5818 deltaPatchFileRow.RetainLengths = protectLengths;
5867 deltaPatchFileRow.IgnoreOffsets = ignoreOffsets; 5819 deltaPatchFileRow.IgnoreOffsets = ignoreOffsets;
5868 deltaPatchFileRow.IgnoreLengths = ignoreLengths; 5820 deltaPatchFileRow.IgnoreLengths = ignoreLengths;
@@ -5870,46 +5822,46 @@ namespace WixToolset
5870 5822
5871 if (null != symbols) 5823 if (null != symbols)
5872 { 5824 {
5873 WixDeltaPatchSymbolPathsRow symbolRow = (WixDeltaPatchSymbolPathsRow)this.core.CreateRow(sourceLineNumbers, "WixDeltaPatchSymbolPaths", id); 5825 var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths, id);
5874 symbolRow.Type = SymbolPathType.File; 5826 symbolRow.Type = SymbolPathType.File;
5875 symbolRow.SymbolPaths = symbols; 5827 symbolRow.SymbolPaths = symbols;
5876 } 5828 }
5877 5829
5878 if (FileAssemblyType.NotAnAssembly != assemblyType) 5830 if (FileAssemblyType.NotAnAssembly != assemblyType)
5879 { 5831 {
5880 Row row = this.core.CreateRow(sourceLineNumbers, "MsiAssembly"); 5832 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiAssembly);
5881 row[0] = componentId; 5833 row.Set(0, componentId);
5882 row[1] = Guid.Empty.ToString("B"); 5834 row.Set(1, Guid.Empty.ToString("B"));
5883 row[2] = assemblyManifest; 5835 row.Set(2, assemblyManifest);
5884 row[3] = assemblyApplication; 5836 row.Set(3, assemblyApplication);
5885 row[4] = (FileAssemblyType.DotNetAssembly == assemblyType) ? 0 : 1; 5837 row.Set(4, (FileAssemblyType.DotNetAssembly == assemblyType) ? 0 : 1);
5886 } 5838 }
5887 5839
5888 if (null != bindPath) 5840 if (null != bindPath)
5889 { 5841 {
5890 Row row = this.core.CreateRow(sourceLineNumbers, "BindImage"); 5842 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.BindImage);
5891 row[0] = id.Id; 5843 row.Set(0, id.Id);
5892 row[1] = bindPath; 5844 row.Set(1, bindPath);
5893 5845
5894 // TODO: technically speaking each of the properties in the "bindPath" should be added as references, but how much do we really care about BindImage? 5846 // TODO: technically speaking each of the properties in the "bindPath" should be added as references, but how much do we really care about BindImage?
5895 } 5847 }
5896 5848
5897 if (CompilerConstants.IntegerNotSet != selfRegCost) 5849 if (CompilerConstants.IntegerNotSet != selfRegCost)
5898 { 5850 {
5899 Row row = this.core.CreateRow(sourceLineNumbers, "SelfReg"); 5851 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.SelfReg);
5900 row[0] = id.Id; 5852 row.Set(0, id.Id);
5901 row[1] = selfRegCost; 5853 row.Set(1, selfRegCost);
5902 } 5854 }
5903 5855
5904 if (null != fontTitle) 5856 if (null != fontTitle)
5905 { 5857 {
5906 Row row = this.core.CreateRow(sourceLineNumbers, "Font"); 5858 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Font);
5907 row[0] = id.Id; 5859 row.Set(0, id.Id);
5908 row[1] = fontTitle; 5860 row.Set(1, fontTitle);
5909 } 5861 }
5910 } 5862 }
5911 5863
5912 this.core.CreateSimpleReference(sourceLineNumbers, "Media", diskId.ToString(CultureInfo.InvariantCulture.NumberFormat)); 5864 this.Core.CreateSimpleReference(sourceLineNumbers, "Media", diskId.ToString(CultureInfo.InvariantCulture.NumberFormat));
5913 5865
5914 // If this component does not have a companion file this file is a possible keypath. 5866 // If this component does not have a companion file this file is a possible keypath.
5915 possibleKeyPath = null; 5867 possibleKeyPath = null;
@@ -5950,57 +5902,57 @@ namespace WixToolset
5950 switch (attrib.Name.LocalName) 5902 switch (attrib.Name.LocalName)
5951 { 5903 {
5952 case "Id": 5904 case "Id":
5953 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 5905 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
5954 break; 5906 break;
5955 case "Name": 5907 case "Name":
5956 name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); 5908 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
5957 break; 5909 break;
5958 case "MinVersion": 5910 case "MinVersion":
5959 minVersion = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5911 minVersion = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5960 break; 5912 break;
5961 case "MaxVersion": 5913 case "MaxVersion":
5962 maxVersion = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5914 maxVersion = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5963 break; 5915 break;
5964 case "MinSize": 5916 case "MinSize":
5965 minSize = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 5917 minSize = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
5966 break; 5918 break;
5967 case "MaxSize": 5919 case "MaxSize":
5968 maxSize = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 5920 maxSize = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
5969 break; 5921 break;
5970 case "MinDate": 5922 case "MinDate":
5971 minDate = this.core.GetAttributeDateTimeValue(sourceLineNumbers, attrib); 5923 minDate = this.Core.GetAttributeDateTimeValue(sourceLineNumbers, attrib);
5972 break; 5924 break;
5973 case "MaxDate": 5925 case "MaxDate":
5974 maxDate = this.core.GetAttributeDateTimeValue(sourceLineNumbers, attrib); 5926 maxDate = this.Core.GetAttributeDateTimeValue(sourceLineNumbers, attrib);
5975 break; 5927 break;
5976 case "Languages": 5928 case "Languages":
5977 languages = this.core.GetAttributeValue(sourceLineNumbers, attrib); 5929 languages = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
5978 break; 5930 break;
5979 case "ShortName": 5931 case "ShortName":
5980 shortName = this.core.GetAttributeShortFilename(sourceLineNumbers, attrib, false); 5932 shortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, false);
5981 break; 5933 break;
5982 default: 5934 default:
5983 this.core.UnexpectedAttribute(node, attrib); 5935 this.Core.UnexpectedAttribute(node, attrib);
5984 break; 5936 break;
5985 } 5937 }
5986 } 5938 }
5987 else 5939 else
5988 { 5940 {
5989 this.core.ParseExtensionAttribute(node, attrib); 5941 this.Core.ParseExtensionAttribute(node, attrib);
5990 } 5942 }
5991 } 5943 }
5992 5944
5993 // Using both ShortName and Name will not always work due to a Windows Installer bug. 5945 // Using both ShortName and Name will not always work due to a Windows Installer bug.
5994 if (null != shortName && null != name) 5946 if (null != shortName && null != name)
5995 { 5947 {
5996 this.core.OnMessage(WixWarnings.FileSearchFileNameIssue(sourceLineNumbers, node.Name.LocalName, "ShortName", "Name")); 5948 this.Core.OnMessage(WixWarnings.FileSearchFileNameIssue(sourceLineNumbers, node.Name.LocalName, "ShortName", "Name"));
5997 } 5949 }
5998 else if (null == shortName && null == name) // at least one name must be specified. 5950 else if (null == shortName && null == name) // at least one name must be specified.
5999 { 5951 {
6000 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 5952 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
6001 } 5953 }
6002 5954
6003 if (this.core.IsValidShortFilename(name, false)) 5955 if (this.Core.IsValidShortFilename(name, false))
6004 { 5956 {
6005 if (null == shortName) 5957 if (null == shortName)
6006 { 5958 {
@@ -6009,7 +5961,7 @@ namespace WixToolset
6009 } 5961 }
6010 else 5962 else
6011 { 5963 {
6012 this.core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", name, "ShortName")); 5964 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", name, "ShortName"));
6013 } 5965 }
6014 } 5966 }
6015 5967
@@ -6017,7 +5969,7 @@ namespace WixToolset
6017 { 5969 {
6018 if (String.IsNullOrEmpty(parentSignature)) 5970 if (String.IsNullOrEmpty(parentSignature))
6019 { 5971 {
6020 id = this.core.CreateIdentifier("fs", name ?? shortName); 5972 id = this.Core.CreateIdentifier("fs", name ?? shortName);
6021 } 5973 }
6022 else // reuse parent signature in the Signature table 5974 else // reuse parent signature in the Signature table
6023 { 5975 {
@@ -6032,7 +5984,7 @@ namespace WixToolset
6032 // value must be specified and unique. 5984 // value must be specified and unique.
6033 if (isSameId) 5985 if (isSameId)
6034 { 5986 {
6035 this.core.OnMessage(WixErrors.UniqueFileSearchIdRequired(sourceLineNumbers, parentSignature, node.Name.LocalName)); 5987 this.Core.OnMessage(WixErrors.UniqueFileSearchIdRequired(sourceLineNumbers, parentSignature, node.Name.LocalName));
6036 } 5988 }
6037 } 5989 }
6038 else if (parentDepth > 1) 5990 else if (parentDepth > 1)
@@ -6041,36 +5993,36 @@ namespace WixToolset
6041 // as the parent DirectorySearch if AssignToProperty is not set. 5993 // as the parent DirectorySearch if AssignToProperty is not set.
6042 if (!isSameId) 5994 if (!isSameId)
6043 { 5995 {
6044 this.core.OnMessage(WixErrors.IllegalSearchIdForParentDepth(sourceLineNumbers, id.Id, parentSignature)); 5996 this.Core.OnMessage(WixErrors.IllegalSearchIdForParentDepth(sourceLineNumbers, id.Id, parentSignature));
6045 } 5997 }
6046 } 5998 }
6047 5999
6048 this.core.ParseForExtensionElements(node); 6000 this.Core.ParseForExtensionElements(node);
6049 6001
6050 if (!this.core.EncounteredError) 6002 if (!this.Core.EncounteredError)
6051 { 6003 {
6052 Row row = this.core.CreateRow(sourceLineNumbers, "Signature", id); 6004 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Signature, id);
6053 row[1] = name ?? shortName; 6005 row.Set(1, name ?? shortName);
6054 row[2] = minVersion; 6006 row.Set(2, minVersion);
6055 row[3] = maxVersion; 6007 row.Set(3, maxVersion);
6056 6008
6057 if (CompilerConstants.IntegerNotSet != minSize) 6009 if (CompilerConstants.IntegerNotSet != minSize)
6058 { 6010 {
6059 row[4] = minSize; 6011 row.Set(4, minSize);
6060 } 6012 }
6061 if (CompilerConstants.IntegerNotSet != maxSize) 6013 if (CompilerConstants.IntegerNotSet != maxSize)
6062 { 6014 {
6063 row[5] = maxSize; 6015 row.Set(5, maxSize);
6064 } 6016 }
6065 if (CompilerConstants.IntegerNotSet != minDate) 6017 if (CompilerConstants.IntegerNotSet != minDate)
6066 { 6018 {
6067 row[6] = minDate; 6019 row.Set(6, minDate);
6068 } 6020 }
6069 if (CompilerConstants.IntegerNotSet != maxDate) 6021 if (CompilerConstants.IntegerNotSet != maxDate)
6070 { 6022 {
6071 row[7] = maxDate; 6023 row.Set(7, maxDate);
6072 } 6024 }
6073 row[8] = languages; 6025 row.Set(8, languages);
6074 6026
6075 // Create a DrLocator row to associate the file with a directory 6027 // Create a DrLocator row to associate the file with a directory
6076 // when a different identifier is specified for the FileSearch. 6028 // when a different identifier is specified for the FileSearch.
@@ -6080,14 +6032,14 @@ namespace WixToolset
6080 { 6032 {
6081 // Creates the DrLocator row for the directory search while 6033 // Creates the DrLocator row for the directory search while
6082 // the parent DirectorySearch creates the file locator row. 6034 // the parent DirectorySearch creates the file locator row.
6083 row = this.core.CreateRow(sourceLineNumbers, "DrLocator"); 6035 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.DrLocator);
6084 row[0] = parentSignature; 6036 row.Set(0, parentSignature);
6085 row[1] = id; 6037 row.Set(1, id);
6086 } 6038 }
6087 else 6039 else
6088 { 6040 {
6089 row = this.core.CreateRow(sourceLineNumbers, "DrLocator", id); 6041 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.DrLocator, id);
6090 row[1] = parentSignature; 6042 row.Set(1, parentSignature);
6091 } 6043 }
6092 } 6044 }
6093 } 6045 }
@@ -6115,22 +6067,22 @@ namespace WixToolset
6115 switch (attrib.Name.LocalName) 6067 switch (attrib.Name.LocalName)
6116 { 6068 {
6117 case "Id": 6069 case "Id":
6118 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 6070 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
6119 break; 6071 break;
6120 default: 6072 default:
6121 this.core.UnexpectedAttribute(node, attrib); 6073 this.Core.UnexpectedAttribute(node, attrib);
6122 break; 6074 break;
6123 } 6075 }
6124 } 6076 }
6125 else 6077 else
6126 { 6078 {
6127 this.core.ParseExtensionAttribute(node, attrib); 6079 this.Core.ParseExtensionAttribute(node, attrib);
6128 } 6080 }
6129 } 6081 }
6130 6082
6131 // NOTE: Id is not required for Fragments, this is a departure from the normal run of the mill processing. 6083 // NOTE: Id is not required for Fragments, this is a departure from the normal run of the mill processing.
6132 6084
6133 this.core.CreateActiveSection(id, SectionType.Fragment, 0); 6085 this.Core.CreateActiveSection(id, SectionType.Fragment, 0, this.Context.CompilationId);
6134 6086
6135 int featureDisplay = 0; 6087 int featureDisplay = 0;
6136 foreach (XElement child in node.Elements()) 6088 foreach (XElement child in node.Elements())
@@ -6282,20 +6234,20 @@ namespace WixToolset
6282 this.ParseWixVariableElement(child); 6234 this.ParseWixVariableElement(child);
6283 break; 6235 break;
6284 default: 6236 default:
6285 this.core.UnexpectedElement(node, child); 6237 this.Core.UnexpectedElement(node, child);
6286 break; 6238 break;
6287 } 6239 }
6288 } 6240 }
6289 else 6241 else
6290 { 6242 {
6291 this.core.ParseExtensionElement(node, child); 6243 this.Core.ParseExtensionElement(node, child);
6292 } 6244 }
6293 } 6245 }
6294 6246
6295 if (!this.core.EncounteredError && null != id) 6247 if (!this.Core.EncounteredError && null != id)
6296 { 6248 {
6297 Row row = this.core.CreateRow(sourceLineNumbers, "WixFragment"); 6249 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixFragment);
6298 row[0] = id; 6250 row.Set(0, id);
6299 } 6251 }
6300 } 6252 }
6301 6253
@@ -6325,7 +6277,7 @@ namespace WixToolset
6325 case "Action": 6277 case "Action":
6326 if ("Control" == parentElementLocalName) 6278 if ("Control" == parentElementLocalName)
6327 { 6279 {
6328 action = this.core.GetAttributeValue(sourceLineNumbers, attrib); 6280 action = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
6329 if (0 < action.Length) 6281 if (0 < action.Length)
6330 { 6282 {
6331 Wix.Condition.ActionType actionType; 6283 Wix.Condition.ActionType actionType;
@@ -6335,56 +6287,56 @@ namespace WixToolset
6335 } 6287 }
6336 else 6288 else
6337 { 6289 {
6338 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, action, "default", "disable", "enable", "hide", "show")); 6290 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, action, "default", "disable", "enable", "hide", "show"));
6339 } 6291 }
6340 } 6292 }
6341 } 6293 }
6342 else 6294 else
6343 { 6295 {
6344 this.core.UnexpectedAttribute(node, attrib); 6296 this.Core.UnexpectedAttribute(node, attrib);
6345 } 6297 }
6346 break; 6298 break;
6347 case "Level": 6299 case "Level":
6348 if ("Feature" == parentElementLocalName) 6300 if ("Feature" == parentElementLocalName)
6349 { 6301 {
6350 level = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 6302 level = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
6351 } 6303 }
6352 else 6304 else
6353 { 6305 {
6354 this.core.UnexpectedAttribute(node, attrib); 6306 this.Core.UnexpectedAttribute(node, attrib);
6355 } 6307 }
6356 break; 6308 break;
6357 case "Message": 6309 case "Message":
6358 if ("Fragment" == parentElementLocalName || "Product" == parentElementLocalName) 6310 if ("Fragment" == parentElementLocalName || "Product" == parentElementLocalName)
6359 { 6311 {
6360 message = this.core.GetAttributeValue(sourceLineNumbers, attrib); 6312 message = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
6361 } 6313 }
6362 else 6314 else
6363 { 6315 {
6364 this.core.UnexpectedAttribute(node, attrib); 6316 this.Core.UnexpectedAttribute(node, attrib);
6365 } 6317 }
6366 break; 6318 break;
6367 default: 6319 default:
6368 this.core.UnexpectedAttribute(node, attrib); 6320 this.Core.UnexpectedAttribute(node, attrib);
6369 break; 6321 break;
6370 } 6322 }
6371 } 6323 }
6372 else 6324 else
6373 { 6325 {
6374 this.core.ParseExtensionAttribute(node, attrib); 6326 this.Core.ParseExtensionAttribute(node, attrib);
6375 } 6327 }
6376 } 6328 }
6377 6329
6378 // get the condition from the inner text of the element 6330 // get the condition from the inner text of the element
6379 condition = this.core.GetConditionInnerText(node); 6331 condition = this.Core.GetConditionInnerText(node);
6380 6332
6381 this.core.ParseForExtensionElements(node); 6333 this.Core.ParseForExtensionElements(node);
6382 6334
6383 // the condition should not be empty 6335 // the condition should not be empty
6384 if (null == condition || 0 == condition.Length) 6336 if (null == condition || 0 == condition.Length)
6385 { 6337 {
6386 condition = null; 6338 condition = null;
6387 this.core.OnMessage(WixErrors.ConditionExpected(sourceLineNumbers, node.Name.LocalName)); 6339 this.Core.OnMessage(WixErrors.ConditionExpected(sourceLineNumbers, node.Name.LocalName));
6388 } 6340 }
6389 6341
6390 switch (parentElementLocalName) 6342 switch (parentElementLocalName)
@@ -6392,45 +6344,45 @@ namespace WixToolset
6392 case "Control": 6344 case "Control":
6393 if (null == action) 6345 if (null == action)
6394 { 6346 {
6395 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Action")); 6347 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Action"));
6396 } 6348 }
6397 6349
6398 if (!this.core.EncounteredError) 6350 if (!this.Core.EncounteredError)
6399 { 6351 {
6400 Row row = this.core.CreateRow(sourceLineNumbers, "ControlCondition"); 6352 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ControlCondition);
6401 row[0] = dialog; 6353 row.Set(0, dialog);
6402 row[1] = id; 6354 row.Set(1, id);
6403 row[2] = action; 6355 row.Set(2, action);
6404 row[3] = condition; 6356 row.Set(3, condition);
6405 } 6357 }
6406 break; 6358 break;
6407 case "Feature": 6359 case "Feature":
6408 if (CompilerConstants.IntegerNotSet == level) 6360 if (CompilerConstants.IntegerNotSet == level)
6409 { 6361 {
6410 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Level")); 6362 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Level"));
6411 level = CompilerConstants.IllegalInteger; 6363 level = CompilerConstants.IllegalInteger;
6412 } 6364 }
6413 6365
6414 if (!this.core.EncounteredError) 6366 if (!this.Core.EncounteredError)
6415 { 6367 {
6416 Row row = this.core.CreateRow(sourceLineNumbers, "Condition"); 6368 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Condition);
6417 row[0] = id; 6369 row.Set(0, id);
6418 row[1] = level; 6370 row.Set(1, level);
6419 row[2] = condition; 6371 row.Set(2, condition);
6420 } 6372 }
6421 break; 6373 break;
6422 case "Fragment": 6374 case "Fragment":
6423 case "Product": 6375 case "Product":
6424 if (null == message) 6376 if (null == message)
6425 { 6377 {
6426 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Message")); 6378 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Message"));
6427 } 6379 }
6428 6380
6429 if (!this.core.EncounteredError) 6381 if (!this.Core.EncounteredError)
6430 { 6382 {
6431 Row row = this.core.CreateRow(sourceLineNumbers, "LaunchCondition"); 6383 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.LaunchCondition);
6432 row[0] = condition; 6384 row.Set(0, condition);
6433 row[1] = message; 6385 row.Set(1, message);
6434 } 6386 }
6435 break; 6387 break;
6436 } 6388 }
@@ -6453,7 +6405,7 @@ namespace WixToolset
6453 string name = null; 6405 string name = null;
6454 string section = null; 6406 string section = null;
6455 string shortName = null; 6407 string shortName = null;
6456 string tableName = null; 6408 TupleDefinitionType tableName;
6457 string value = null; 6409 string value = null;
6458 6410
6459 foreach (XAttribute attrib in node.Attributes()) 6411 foreach (XAttribute attrib in node.Attributes())
@@ -6463,10 +6415,10 @@ namespace WixToolset
6463 switch (attrib.Name.LocalName) 6415 switch (attrib.Name.LocalName)
6464 { 6416 {
6465 case "Id": 6417 case "Id":
6466 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 6418 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
6467 break; 6419 break;
6468 case "Action": 6420 case "Action":
6469 string actionValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 6421 string actionValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
6470 if (0 < actionValue.Length) 6422 if (0 < actionValue.Length)
6471 { 6423 {
6472 Wix.IniFile.ActionType actionType = Wix.IniFile.ParseActionType(actionValue); 6424 Wix.IniFile.ActionType actionType = Wix.IniFile.ParseActionType(actionValue);
@@ -6488,58 +6440,58 @@ namespace WixToolset
6488 action = MsiInterop.MsidbIniFileActionRemoveTag; 6440 action = MsiInterop.MsidbIniFileActionRemoveTag;
6489 break; 6441 break;
6490 default: 6442 default:
6491 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Action", actionValue, "addLine", "addTag", "createLine", "removeLine", "removeTag")); 6443 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Action", actionValue, "addLine", "addTag", "createLine", "removeLine", "removeTag"));
6492 break; 6444 break;
6493 } 6445 }
6494 } 6446 }
6495 break; 6447 break;
6496 case "Directory": 6448 case "Directory":
6497 directory = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 6449 directory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
6498 break; 6450 break;
6499 case "Key": 6451 case "Key":
6500 key = this.core.GetAttributeValue(sourceLineNumbers, attrib); 6452 key = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
6501 break; 6453 break;
6502 case "Name": 6454 case "Name":
6503 name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); 6455 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
6504 break; 6456 break;
6505 case "Section": 6457 case "Section":
6506 section = this.core.GetAttributeValue(sourceLineNumbers, attrib); 6458 section = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
6507 break; 6459 break;
6508 case "ShortName": 6460 case "ShortName":
6509 shortName = this.core.GetAttributeShortFilename(sourceLineNumbers, attrib, false); 6461 shortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, false);
6510 break; 6462 break;
6511 case "Value": 6463 case "Value":
6512 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 6464 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
6513 break; 6465 break;
6514 default: 6466 default:
6515 this.core.UnexpectedAttribute(node, attrib); 6467 this.Core.UnexpectedAttribute(node, attrib);
6516 break; 6468 break;
6517 } 6469 }
6518 } 6470 }
6519 else 6471 else
6520 { 6472 {
6521 this.core.ParseExtensionAttribute(node, attrib); 6473 this.Core.ParseExtensionAttribute(node, attrib);
6522 } 6474 }
6523 } 6475 }
6524 6476
6525 if (CompilerConstants.IntegerNotSet == action) 6477 if (CompilerConstants.IntegerNotSet == action)
6526 { 6478 {
6527 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Action")); 6479 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Action"));
6528 action = CompilerConstants.IllegalInteger; 6480 action = CompilerConstants.IllegalInteger;
6529 } 6481 }
6530 6482
6531 if (null == key) 6483 if (null == key)
6532 { 6484 {
6533 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); 6485 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
6534 } 6486 }
6535 6487
6536 if (null == name) 6488 if (null == name)
6537 { 6489 {
6538 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 6490 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
6539 } 6491 }
6540 else if (0 < name.Length) 6492 else if (0 < name.Length)
6541 { 6493 {
6542 if (this.core.IsValidShortFilename(name, false)) 6494 if (this.Core.IsValidShortFilename(name, false))
6543 { 6495 {
6544 if (null == shortName) 6496 if (null == shortName)
6545 { 6497 {
@@ -6548,54 +6500,54 @@ namespace WixToolset
6548 } 6500 }
6549 else 6501 else
6550 { 6502 {
6551 this.core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", name, "ShortName")); 6503 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", name, "ShortName"));
6552 } 6504 }
6553 } 6505 }
6554 else // generate a short file name. 6506 else // generate a short file name.
6555 { 6507 {
6556 if (null == shortName) 6508 if (null == shortName)
6557 { 6509 {
6558 shortName = this.core.CreateShortName(name, true, false, node.Name.LocalName, componentId); 6510 shortName = this.Core.CreateShortName(name, true, false, node.Name.LocalName, componentId);
6559 } 6511 }
6560 } 6512 }
6561 } 6513 }
6562 6514
6563 if (null == section) 6515 if (null == section)
6564 { 6516 {
6565 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Section")); 6517 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Section"));
6566 } 6518 }
6567 6519
6568 if (null == id) 6520 if (null == id)
6569 { 6521 {
6570 id = this.core.CreateIdentifier("ini", directory, name ?? shortName, section, key, name); 6522 id = this.Core.CreateIdentifier("ini", directory, name ?? shortName, section, key, name);
6571 } 6523 }
6572 6524
6573 this.core.ParseForExtensionElements(node); 6525 this.Core.ParseForExtensionElements(node);
6574 6526
6575 if (MsiInterop.MsidbIniFileActionRemoveLine == action || MsiInterop.MsidbIniFileActionRemoveTag == action) 6527 if (MsiInterop.MsidbIniFileActionRemoveLine == action || MsiInterop.MsidbIniFileActionRemoveTag == action)
6576 { 6528 {
6577 tableName = "RemoveIniFile"; 6529 tableName = TupleDefinitionType.RemoveIniFile;
6578 } 6530 }
6579 else 6531 else
6580 { 6532 {
6581 if (null == value) 6533 if (null == value)
6582 { 6534 {
6583 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 6535 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
6584 } 6536 }
6585 6537
6586 tableName = "IniFile"; 6538 tableName = TupleDefinitionType.IniFile;
6587 } 6539 }
6588 6540
6589 if (!this.core.EncounteredError) 6541 if (!this.Core.EncounteredError)
6590 { 6542 {
6591 Row row = this.core.CreateRow(sourceLineNumbers, tableName, id); 6543 var row = this.Core.CreateRow(sourceLineNumbers, tableName, id);
6592 row[1] = GetMsiFilenameValue(shortName, name); 6544 row.Set(1, GetMsiFilenameValue(shortName, name));
6593 row[2] = directory; 6545 row.Set(2, directory);
6594 row[3] = section; 6546 row.Set(3, section);
6595 row[4] = key; 6547 row.Set(4, key);
6596 row[5] = value; 6548 row.Set(5, value);
6597 row[6] = action; 6549 row.Set(6, action);
6598 row[7] = componentId; 6550 row.Set(7, componentId);
6599 } 6551 }
6600 } 6552 }
6601 6553
@@ -6623,25 +6575,25 @@ namespace WixToolset
6623 switch (attrib.Name.LocalName) 6575 switch (attrib.Name.LocalName)
6624 { 6576 {
6625 case "Id": 6577 case "Id":
6626 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 6578 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
6627 break; 6579 break;
6628 case "Field": 6580 case "Field":
6629 field = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 6581 field = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
6630 break; 6582 break;
6631 case "Key": 6583 case "Key":
6632 key = this.core.GetAttributeValue(sourceLineNumbers, attrib); 6584 key = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
6633 break; 6585 break;
6634 case "Name": 6586 case "Name":
6635 name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); 6587 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
6636 break; 6588 break;
6637 case "Section": 6589 case "Section":
6638 section = this.core.GetAttributeValue(sourceLineNumbers, attrib); 6590 section = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
6639 break; 6591 break;
6640 case "ShortName": 6592 case "ShortName":
6641 shortName = this.core.GetAttributeShortFilename(sourceLineNumbers, attrib, false); 6593 shortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, false);
6642 break; 6594 break;
6643 case "Type": 6595 case "Type":
6644 string typeValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 6596 string typeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
6645 if (0 < typeValue.Length) 6597 if (0 < typeValue.Length)
6646 { 6598 {
6647 Wix.IniFileSearch.TypeType typeType = Wix.IniFileSearch.ParseTypeType(typeValue); 6599 Wix.IniFileSearch.TypeType typeType = Wix.IniFileSearch.ParseTypeType(typeValue);
@@ -6657,34 +6609,34 @@ namespace WixToolset
6657 type = 2; 6609 type = 2;
6658 break; 6610 break;
6659 default: 6611 default:
6660 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Type", typeValue, "directory", "file", "registry")); 6612 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Type", typeValue, "directory", "file", "registry"));
6661 break; 6613 break;
6662 } 6614 }
6663 } 6615 }
6664 break; 6616 break;
6665 default: 6617 default:
6666 this.core.UnexpectedAttribute(node, attrib); 6618 this.Core.UnexpectedAttribute(node, attrib);
6667 break; 6619 break;
6668 } 6620 }
6669 } 6621 }
6670 else 6622 else
6671 { 6623 {
6672 this.core.ParseExtensionAttribute(node, attrib); 6624 this.Core.ParseExtensionAttribute(node, attrib);
6673 } 6625 }
6674 } 6626 }
6675 6627
6676 if (null == key) 6628 if (null == key)
6677 { 6629 {
6678 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); 6630 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
6679 } 6631 }
6680 6632
6681 if (null == name) 6633 if (null == name)
6682 { 6634 {
6683 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 6635 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
6684 } 6636 }
6685 else if (0 < name.Length) 6637 else if (0 < name.Length)
6686 { 6638 {
6687 if (this.core.IsValidShortFilename(name, false)) 6639 if (this.Core.IsValidShortFilename(name, false))
6688 { 6640 {
6689 if (null == shortName) 6641 if (null == shortName)
6690 { 6642 {
@@ -6693,23 +6645,23 @@ namespace WixToolset
6693 } 6645 }
6694 else 6646 else
6695 { 6647 {
6696 this.core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", name, "ShortName")); 6648 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", name, "ShortName"));
6697 } 6649 }
6698 } 6650 }
6699 else if (null == shortName) // generate a short file name. 6651 else if (null == shortName) // generate a short file name.
6700 { 6652 {
6701 shortName = this.core.CreateShortName(name, true, false, node.Name.LocalName); 6653 shortName = this.Core.CreateShortName(name, true, false, node.Name.LocalName);
6702 } 6654 }
6703 } 6655 }
6704 6656
6705 if (null == section) 6657 if (null == section)
6706 { 6658 {
6707 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Section")); 6659 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Section"));
6708 } 6660 }
6709 6661
6710 if (null == id) 6662 if (null == id)
6711 { 6663 {
6712 id = this.core.CreateIdentifier("ini", name, section, key, field.ToString(), type.ToString()); 6664 id = this.Core.CreateIdentifier("ini", name, section, key, field.ToString(), type.ToString());
6713 } 6665 }
6714 6666
6715 signature = id.Id; 6667 signature = id.Id;
@@ -6725,7 +6677,7 @@ namespace WixToolset
6725 case "DirectorySearch": 6677 case "DirectorySearch":
6726 if (oneChild) 6678 if (oneChild)
6727 { 6679 {
6728 this.core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName)); 6680 this.Core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName));
6729 } 6681 }
6730 oneChild = true; 6682 oneChild = true;
6731 6683
@@ -6735,7 +6687,7 @@ namespace WixToolset
6735 case "DirectorySearchRef": 6687 case "DirectorySearchRef":
6736 if (oneChild) 6688 if (oneChild)
6737 { 6689 {
6738 this.core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName)); 6690 this.Core.OnMessage(WixErrors.TooManySearchElements(childSourceLineNumbers, node.Name.LocalName));
6739 } 6691 }
6740 oneChild = true; 6692 oneChild = true;
6741 signature = this.ParseDirectorySearchRefElement(child, id.Id); 6693 signature = this.ParseDirectorySearchRefElement(child, id.Id);
@@ -6743,7 +6695,7 @@ namespace WixToolset
6743 case "FileSearch": 6695 case "FileSearch":
6744 if (oneChild) 6696 if (oneChild)
6745 { 6697 {
6746 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 6698 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
6747 } 6699 }
6748 oneChild = true; 6700 oneChild = true;
6749 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet); 6701 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet);
@@ -6752,7 +6704,7 @@ namespace WixToolset
6752 case "FileSearchRef": 6704 case "FileSearchRef":
6753 if (oneChild) 6705 if (oneChild)
6754 { 6706 {
6755 this.core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName)); 6707 this.Core.OnMessage(WixErrors.TooManySearchElements(sourceLineNumbers, node.Name.LocalName));
6756 } 6708 }
6757 oneChild = true; 6709 oneChild = true;
6758 string newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures 6710 string newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures
@@ -6760,27 +6712,27 @@ namespace WixToolset
6760 signature = null; 6712 signature = null;
6761 break; 6713 break;
6762 default: 6714 default:
6763 this.core.UnexpectedElement(node, child); 6715 this.Core.UnexpectedElement(node, child);
6764 break; 6716 break;
6765 } 6717 }
6766 } 6718 }
6767 else 6719 else
6768 { 6720 {
6769 this.core.ParseExtensionElement(node, child); 6721 this.Core.ParseExtensionElement(node, child);
6770 } 6722 }
6771 } 6723 }
6772 6724
6773 if (!this.core.EncounteredError) 6725 if (!this.Core.EncounteredError)
6774 { 6726 {
6775 Row row = this.core.CreateRow(sourceLineNumbers, "IniLocator", id); 6727 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.IniLocator, id);
6776 row[1] = GetMsiFilenameValue(shortName, name); 6728 row.Set(1, GetMsiFilenameValue(shortName, name));
6777 row[2] = section; 6729 row.Set(2, section);
6778 row[3] = key; 6730 row.Set(3, key);
6779 if (CompilerConstants.IntegerNotSet != field) 6731 if (CompilerConstants.IntegerNotSet != field)
6780 { 6732 {
6781 row[4] = field; 6733 row.Set(4, field);
6782 } 6734 }
6783 row[5] = type; 6735 row.Set(5, type);
6784 } 6736 }
6785 6737
6786 return signature; 6738 return signature;
@@ -6803,32 +6755,32 @@ namespace WixToolset
6803 switch (attrib.Name.LocalName) 6755 switch (attrib.Name.LocalName)
6804 { 6756 {
6805 case "Shared": 6757 case "Shared":
6806 shared = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 6758 shared = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
6807 this.core.CreateSimpleReference(sourceLineNumbers, "Component", shared); 6759 this.Core.CreateSimpleReference(sourceLineNumbers, "Component", shared);
6808 break; 6760 break;
6809 default: 6761 default:
6810 this.core.UnexpectedAttribute(node, attrib); 6762 this.Core.UnexpectedAttribute(node, attrib);
6811 break; 6763 break;
6812 } 6764 }
6813 } 6765 }
6814 else 6766 else
6815 { 6767 {
6816 this.core.ParseExtensionAttribute(node, attrib); 6768 this.Core.ParseExtensionAttribute(node, attrib);
6817 } 6769 }
6818 } 6770 }
6819 6771
6820 if (null == shared) 6772 if (null == shared)
6821 { 6773 {
6822 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Shared")); 6774 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Shared"));
6823 } 6775 }
6824 6776
6825 this.core.ParseForExtensionElements(node); 6777 this.Core.ParseForExtensionElements(node);
6826 6778
6827 if (!this.core.EncounteredError) 6779 if (!this.Core.EncounteredError)
6828 { 6780 {
6829 Row row = this.core.CreateRow(sourceLineNumbers, "IsolatedComponent"); 6781 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.IsolatedComponent);
6830 row[0] = shared; 6782 row.Set(0, shared);
6831 row[1] = componentId; 6783 row.Set(1, componentId);
6832 } 6784 }
6833 } 6785 }
6834 6786
@@ -6845,11 +6797,11 @@ namespace WixToolset
6845 { 6797 {
6846 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) 6798 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
6847 { 6799 {
6848 this.core.UnexpectedAttribute(node, attrib); 6800 this.Core.UnexpectedAttribute(node, attrib);
6849 } 6801 }
6850 else 6802 else
6851 { 6803 {
6852 this.core.ParseExtensionAttribute(node, attrib); 6804 this.Core.ParseExtensionAttribute(node, attrib);
6853 } 6805 }
6854 } 6806 }
6855 6807
@@ -6862,21 +6814,21 @@ namespace WixToolset
6862 case "DigitalCertificate": 6814 case "DigitalCertificate":
6863 string name = this.ParseDigitalCertificateElement(child); 6815 string name = this.ParseDigitalCertificateElement(child);
6864 6816
6865 if (!this.core.EncounteredError) 6817 if (!this.Core.EncounteredError)
6866 { 6818 {
6867 Row row = this.core.CreateRow(sourceLineNumbers, "PatchCertificates" == node.Name.LocalName ? "MsiPatchCertificate" : "MsiPackageCertificate"); 6819 var row = this.Core.CreateRow(sourceLineNumbers, "PatchCertificates" == node.Name.LocalName ? TupleDefinitionType.MsiPatchCertificate : TupleDefinitionType.MsiPackageCertificate);
6868 row[0] = name; 6820 row.Set(0, name);
6869 row[1] = name; 6821 row.Set(1, name);
6870 } 6822 }
6871 break; 6823 break;
6872 default: 6824 default:
6873 this.core.UnexpectedElement(node, child); 6825 this.Core.UnexpectedElement(node, child);
6874 break; 6826 break;
6875 } 6827 }
6876 } 6828 }
6877 else 6829 else
6878 { 6830 {
6879 this.core.ParseExtensionElement(node, child); 6831 this.Core.ParseExtensionElement(node, child);
6880 } 6832 }
6881 } 6833 }
6882 } 6834 }
@@ -6899,30 +6851,30 @@ namespace WixToolset
6899 switch (attrib.Name.LocalName) 6851 switch (attrib.Name.LocalName)
6900 { 6852 {
6901 case "Id": 6853 case "Id":
6902 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 6854 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
6903 break; 6855 break;
6904 case "SourceFile": 6856 case "SourceFile":
6905 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 6857 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
6906 break; 6858 break;
6907 default: 6859 default:
6908 this.core.UnexpectedAttribute(node, attrib); 6860 this.Core.UnexpectedAttribute(node, attrib);
6909 break; 6861 break;
6910 } 6862 }
6911 } 6863 }
6912 else 6864 else
6913 { 6865 {
6914 this.core.ParseExtensionAttribute(node, attrib); 6866 this.Core.ParseExtensionAttribute(node, attrib);
6915 } 6867 }
6916 } 6868 }
6917 6869
6918 if (null == id) 6870 if (null == id)
6919 { 6871 {
6920 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 6872 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
6921 id = Identifier.Invalid; 6873 id = Identifier.Invalid;
6922 } 6874 }
6923 else if (40 < id.Id.Length) 6875 else if (40 < id.Id.Length)
6924 { 6876 {
6925 this.core.OnMessage(WixErrors.StreamNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, id.Id.Length, 40)); 6877 this.Core.OnMessage(WixErrors.StreamNameTooLong(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, id.Id.Length, 40));
6926 6878
6927 // No need to check for modularization problems since DigitalSignature and thus DigitalCertificate 6879 // No need to check for modularization problems since DigitalSignature and thus DigitalCertificate
6928 // currently have no usage in merge modules. 6880 // currently have no usage in merge modules.
@@ -6930,15 +6882,15 @@ namespace WixToolset
6930 6882
6931 if (null == sourceFile) 6883 if (null == sourceFile)
6932 { 6884 {
6933 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); 6885 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
6934 } 6886 }
6935 6887
6936 this.core.ParseForExtensionElements(node); 6888 this.Core.ParseForExtensionElements(node);
6937 6889
6938 if (!this.core.EncounteredError) 6890 if (!this.Core.EncounteredError)
6939 { 6891 {
6940 Row row = this.core.CreateRow(sourceLineNumbers, "MsiDigitalCertificate", id); 6892 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiDigitalCertificate, id);
6941 row[1] = sourceFile; 6893 row.Set(1, sourceFile);
6942 } 6894 }
6943 6895
6944 return id.Id; 6896 return id.Id;
@@ -6962,16 +6914,16 @@ namespace WixToolset
6962 switch (attrib.Name.LocalName) 6914 switch (attrib.Name.LocalName)
6963 { 6915 {
6964 case "SourceFile": 6916 case "SourceFile":
6965 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 6917 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
6966 break; 6918 break;
6967 default: 6919 default:
6968 this.core.UnexpectedAttribute(node, attrib); 6920 this.Core.UnexpectedAttribute(node, attrib);
6969 break; 6921 break;
6970 } 6922 }
6971 } 6923 }
6972 else 6924 else
6973 { 6925 {
6974 this.core.ParseExtensionAttribute(node, attrib); 6926 this.Core.ParseExtensionAttribute(node, attrib);
6975 } 6927 }
6976 } 6928 }
6977 6929
@@ -6991,28 +6943,28 @@ namespace WixToolset
6991 certificateId = this.ParseDigitalCertificateElement(child); 6943 certificateId = this.ParseDigitalCertificateElement(child);
6992 break; 6944 break;
6993 default: 6945 default:
6994 this.core.UnexpectedElement(node, child); 6946 this.Core.UnexpectedElement(node, child);
6995 break; 6947 break;
6996 } 6948 }
6997 } 6949 }
6998 else 6950 else
6999 { 6951 {
7000 this.core.ParseExtensionElement(node, child); 6952 this.Core.ParseExtensionElement(node, child);
7001 } 6953 }
7002 } 6954 }
7003 6955
7004 if (null == certificateId) 6956 if (null == certificateId)
7005 { 6957 {
7006 this.core.OnMessage(WixErrors.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "DigitalCertificate")); 6958 this.Core.OnMessage(WixErrors.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "DigitalCertificate"));
7007 } 6959 }
7008 6960
7009 if (!this.core.EncounteredError) 6961 if (!this.Core.EncounteredError)
7010 { 6962 {
7011 Row row = this.core.CreateRow(sourceLineNumbers, "MsiDigitalSignature"); 6963 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiDigitalSignature);
7012 row[0] = "Media"; 6964 row.Set(0, "Media");
7013 row[1] = diskId; 6965 row.Set(1, diskId);
7014 row[2] = certificateId; 6966 row.Set(2, certificateId);
7015 row[3] = sourceFile; 6967 row.Set(3, sourceFile);
7016 } 6968 }
7017 } 6969 }
7018 6970
@@ -7036,13 +6988,13 @@ namespace WixToolset
7036 string upgradeCode = contextValues["UpgradeCode"]; 6988 string upgradeCode = contextValues["UpgradeCode"];
7037 if (String.IsNullOrEmpty(upgradeCode)) 6989 if (String.IsNullOrEmpty(upgradeCode))
7038 { 6990 {
7039 this.core.OnMessage(WixErrors.ParentElementAttributeRequired(sourceLineNumbers, "Product", "UpgradeCode", node.Name.LocalName)); 6991 this.Core.OnMessage(WixErrors.ParentElementAttributeRequired(sourceLineNumbers, "Product", "UpgradeCode", node.Name.LocalName));
7040 } 6992 }
7041 6993
7042 string productVersion = contextValues["ProductVersion"]; 6994 string productVersion = contextValues["ProductVersion"];
7043 if (String.IsNullOrEmpty(productVersion)) 6995 if (String.IsNullOrEmpty(productVersion))
7044 { 6996 {
7045 this.core.OnMessage(WixErrors.ParentElementAttributeRequired(sourceLineNumbers, "Product", "Version", node.Name.LocalName)); 6997 this.Core.OnMessage(WixErrors.ParentElementAttributeRequired(sourceLineNumbers, "Product", "Version", node.Name.LocalName));
7046 } 6998 }
7047 6999
7048 string productLanguage = contextValues["ProductLanguage"]; 7000 string productLanguage = contextValues["ProductLanguage"];
@@ -7054,104 +7006,104 @@ namespace WixToolset
7054 switch (attrib.Name.LocalName) 7006 switch (attrib.Name.LocalName)
7055 { 7007 {
7056 case "AllowDowngrades": 7008 case "AllowDowngrades":
7057 allowDowngrades = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 7009 allowDowngrades = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7058 break; 7010 break;
7059 case "AllowSameVersionUpgrades": 7011 case "AllowSameVersionUpgrades":
7060 allowSameVersionUpgrades = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 7012 allowSameVersionUpgrades = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7061 break; 7013 break;
7062 case "Disallow": 7014 case "Disallow":
7063 blockUpgrades = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 7015 blockUpgrades = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7064 break; 7016 break;
7065 case "DowngradeErrorMessage": 7017 case "DowngradeErrorMessage":
7066 downgradeErrorMessage = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7018 downgradeErrorMessage = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7067 break; 7019 break;
7068 case "DisallowUpgradeErrorMessage": 7020 case "DisallowUpgradeErrorMessage":
7069 disallowUpgradeErrorMessage = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7021 disallowUpgradeErrorMessage = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7070 break; 7022 break;
7071 case "MigrateFeatures": 7023 case "MigrateFeatures":
7072 if (YesNoType.No == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 7024 if (YesNoType.No == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
7073 { 7025 {
7074 options &= ~MsiInterop.MsidbUpgradeAttributesMigrateFeatures; 7026 options &= ~MsiInterop.MsidbUpgradeAttributesMigrateFeatures;
7075 } 7027 }
7076 break; 7028 break;
7077 case "IgnoreLanguage": 7029 case "IgnoreLanguage":
7078 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 7030 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
7079 { 7031 {
7080 productLanguage = null; 7032 productLanguage = null;
7081 } 7033 }
7082 break; 7034 break;
7083 case "IgnoreRemoveFailure": 7035 case "IgnoreRemoveFailure":
7084 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 7036 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
7085 { 7037 {
7086 options |= MsiInterop.MsidbUpgradeAttributesIgnoreRemoveFailure; 7038 options |= MsiInterop.MsidbUpgradeAttributesIgnoreRemoveFailure;
7087 } 7039 }
7088 break; 7040 break;
7089 case "RemoveFeatures": 7041 case "RemoveFeatures":
7090 removeFeatures = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7042 removeFeatures = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7091 break; 7043 break;
7092 case "Schedule": 7044 case "Schedule":
7093 schedule = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7045 schedule = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7094 break; 7046 break;
7095 default: 7047 default:
7096 this.core.UnexpectedAttribute(node, attrib); 7048 this.Core.UnexpectedAttribute(node, attrib);
7097 break; 7049 break;
7098 } 7050 }
7099 } 7051 }
7100 else 7052 else
7101 { 7053 {
7102 this.core.ParseExtensionAttribute(node, attrib); 7054 this.Core.ParseExtensionAttribute(node, attrib);
7103 } 7055 }
7104 } 7056 }
7105 7057
7106 this.core.ParseForExtensionElements(node); 7058 this.Core.ParseForExtensionElements(node);
7107 7059
7108 if (!allowDowngrades && String.IsNullOrEmpty(downgradeErrorMessage)) 7060 if (!allowDowngrades && String.IsNullOrEmpty(downgradeErrorMessage))
7109 { 7061 {
7110 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DowngradeErrorMessage", "AllowDowngrades", "yes", true)); 7062 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DowngradeErrorMessage", "AllowDowngrades", "yes", true));
7111 } 7063 }
7112 7064
7113 if (allowDowngrades && !String.IsNullOrEmpty(downgradeErrorMessage)) 7065 if (allowDowngrades && !String.IsNullOrEmpty(downgradeErrorMessage))
7114 { 7066 {
7115 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DowngradeErrorMessage", "AllowDowngrades", "yes")); 7067 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DowngradeErrorMessage", "AllowDowngrades", "yes"));
7116 } 7068 }
7117 7069
7118 if (allowDowngrades && allowSameVersionUpgrades) 7070 if (allowDowngrades && allowSameVersionUpgrades)
7119 { 7071 {
7120 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "AllowSameVersionUpgrades", "AllowDowngrades", "yes")); 7072 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "AllowSameVersionUpgrades", "AllowDowngrades", "yes"));
7121 } 7073 }
7122 7074
7123 if (blockUpgrades && String.IsNullOrEmpty(disallowUpgradeErrorMessage)) 7075 if (blockUpgrades && String.IsNullOrEmpty(disallowUpgradeErrorMessage))
7124 { 7076 {
7125 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisallowUpgradeErrorMessage", "Disallow", "yes", true)); 7077 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisallowUpgradeErrorMessage", "Disallow", "yes", true));
7126 } 7078 }
7127 7079
7128 if (!blockUpgrades && !String.IsNullOrEmpty(disallowUpgradeErrorMessage)) 7080 if (!blockUpgrades && !String.IsNullOrEmpty(disallowUpgradeErrorMessage))
7129 { 7081 {
7130 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DisallowUpgradeErrorMessage", "Disallow", "yes")); 7082 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DisallowUpgradeErrorMessage", "Disallow", "yes"));
7131 } 7083 }
7132 7084
7133 if (!this.core.EncounteredError) 7085 if (!this.Core.EncounteredError)
7134 { 7086 {
7135 // create the row that performs the upgrade (or downgrade) 7087 // create the row that performs the upgrade (or downgrade)
7136 Row row = this.core.CreateRow(sourceLineNumbers, "Upgrade"); 7088 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Upgrade);
7137 row[0] = upgradeCode; 7089 row.Set(0, upgradeCode);
7138 if (allowDowngrades) 7090 if (allowDowngrades)
7139 { 7091 {
7140 row[1] = "0"; // let any version satisfy 7092 row.Set(1, "0"); // let any version satisfy
7141 // row[2] = maximum version; omit so we don't have to fake a version like "255.255.65535"; 7093 // row.Set(2, maximum version; omit so we don't have to fake a version like "255.255.65535";
7142 row[3] = productLanguage; 7094 row.Set(3, productLanguage);
7143 row[4] = options | MsiInterop.MsidbUpgradeAttributesVersionMinInclusive; 7095 row.Set(4, options | MsiInterop.MsidbUpgradeAttributesVersionMinInclusive);
7144 } 7096 }
7145 else 7097 else
7146 { 7098 {
7147 // row[1] = minimum version; skip it so we detect all prior versions. 7099 // row.Set(1, minimum version; skip it so we detect all prior versions.
7148 row[2] = productVersion; 7100 row.Set(2, productVersion);
7149 row[3] = productLanguage; 7101 row.Set(3, productLanguage);
7150 row[4] = allowSameVersionUpgrades ? (options | MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive) : options; 7102 row.Set(4, allowSameVersionUpgrades ? (options | MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive) : options);
7151 } 7103 }
7152 7104
7153 row[5] = removeFeatures; 7105 row.Set(5, removeFeatures);
7154 row[6] = Compiler.UpgradeDetectedProperty; 7106 row.Set(6, Compiler.UpgradeDetectedProperty);
7155 7107
7156 // Ensure the action property is secure. 7108 // Ensure the action property is secure.
7157 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(Compiler.UpgradeDetectedProperty, AccessModifier.Public), false, true, false); 7109 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(Compiler.UpgradeDetectedProperty, AccessModifier.Public), false, true, false);
@@ -7159,61 +7111,61 @@ namespace WixToolset
7159 // Add launch condition that blocks upgrades 7111 // Add launch condition that blocks upgrades
7160 if (blockUpgrades) 7112 if (blockUpgrades)
7161 { 7113 {
7162 row = this.core.CreateRow(sourceLineNumbers, "LaunchCondition"); 7114 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.LaunchCondition);
7163 row[0] = Compiler.UpgradePreventedCondition; 7115 row.Set(0, Compiler.UpgradePreventedCondition);
7164 row[1] = disallowUpgradeErrorMessage; 7116 row.Set(1, disallowUpgradeErrorMessage);
7165 } 7117 }
7166 7118
7167 // now create the Upgrade row and launch conditions to prevent downgrades (unless explicitly permitted) 7119 // now create the Upgrade row and launch conditions to prevent downgrades (unless explicitly permitted)
7168 if (!allowDowngrades) 7120 if (!allowDowngrades)
7169 { 7121 {
7170 row = this.core.CreateRow(sourceLineNumbers, "Upgrade"); 7122 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Upgrade);
7171 row[0] = upgradeCode; 7123 row.Set(0, upgradeCode);
7172 row[1] = productVersion; 7124 row.Set(1, productVersion);
7173 // row[2] = maximum version; skip it so we detect all future versions. 7125 // row.Set(2, maximum version; skip it so we detect all future versions.
7174 row[3] = productLanguage; 7126 row.Set(3, productLanguage);
7175 row[4] = MsiInterop.MsidbUpgradeAttributesOnlyDetect; 7127 row.Set(4, MsiInterop.MsidbUpgradeAttributesOnlyDetect);
7176 // row[5] = removeFeatures; 7128 // row.Set(5, removeFeatures);
7177 row[6] = Compiler.DowngradeDetectedProperty; 7129 row.Set(6, Compiler.DowngradeDetectedProperty);
7178 7130
7179 // Ensure the action property is secure. 7131 // Ensure the action property is secure.
7180 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(Compiler.DowngradeDetectedProperty, AccessModifier.Public), false, true, false); 7132 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(Compiler.DowngradeDetectedProperty, AccessModifier.Public), false, true, false);
7181 7133
7182 row = this.core.CreateRow(sourceLineNumbers, "LaunchCondition"); 7134 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.LaunchCondition);
7183 row[0] = Compiler.DowngradePreventedCondition; 7135 row.Set(0, Compiler.DowngradePreventedCondition);
7184 row[1] = downgradeErrorMessage; 7136 row.Set(1, downgradeErrorMessage);
7185 } 7137 }
7186 7138
7187 // finally, schedule RemoveExistingProducts 7139 // finally, schedule RemoveExistingProducts
7188 row = this.core.CreateRow(sourceLineNumbers, "WixAction"); 7140 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixAction);
7189 row[0] = "InstallExecuteSequence"; 7141 row.Set(0, "InstallExecuteSequence");
7190 row[1] = "RemoveExistingProducts"; 7142 row.Set(1, "RemoveExistingProducts");
7191 // row[2] = condition; 7143 // row.Set(2, condition);
7192 // row[3] = sequence; 7144 // row.Set(3, sequence);
7193 row[6] = 0; // overridable 7145 row.Set(6, false); // overridable
7194 7146
7195 switch (schedule) 7147 switch (schedule)
7196 { 7148 {
7197 case null: 7149 case null:
7198 case "afterInstallValidate": 7150 case "afterInstallValidate":
7199 // row[4] = beforeAction; 7151 // row.Set(4, beforeAction;
7200 row[5] = "InstallValidate"; 7152 row.Set(5, "InstallValidate");
7201 break; 7153 break;
7202 case "afterInstallInitialize": 7154 case "afterInstallInitialize":
7203 // row[4] = beforeAction; 7155 // row.Set(4, beforeAction;
7204 row[5] = "InstallInitialize"; 7156 row.Set(5, "InstallInitialize");
7205 break; 7157 break;
7206 case "afterInstallExecute": 7158 case "afterInstallExecute":
7207 // row[4] = beforeAction; 7159 // row.Set(4, beforeAction;
7208 row[5] = "InstallExecute"; 7160 row.Set(5, "InstallExecute");
7209 break; 7161 break;
7210 case "afterInstallExecuteAgain": 7162 case "afterInstallExecuteAgain":
7211 // row[4] = beforeAction; 7163 // row.Set(4, beforeAction;
7212 row[5] = "InstallExecuteAgain"; 7164 row.Set(5, "InstallExecuteAgain");
7213 break; 7165 break;
7214 case "afterInstallFinalize": 7166 case "afterInstallFinalize":
7215 // row[4] = beforeAction; 7167 // row.Set(4, beforeAction;
7216 row[5] = "InstallFinalize"; 7168 row.Set(5, "InstallFinalize");
7217 break; 7169 break;
7218 } 7170 }
7219 } 7171 }
@@ -7246,19 +7198,19 @@ namespace WixToolset
7246 switch (attrib.Name.LocalName) 7198 switch (attrib.Name.LocalName)
7247 { 7199 {
7248 case "Id": 7200 case "Id":
7249 id = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); 7201 id = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue);
7250 break; 7202 break;
7251 case "Cabinet": 7203 case "Cabinet":
7252 cabinet = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7204 cabinet = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7253 break; 7205 break;
7254 case "CompressionLevel": 7206 case "CompressionLevel":
7255 string compressionLevelString = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7207 string compressionLevelString = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7256 if (0 < compressionLevelString.Length) 7208 if (0 < compressionLevelString.Length)
7257 { 7209 {
7258 Wix.CompressionLevelType compressionLevelType; 7210 Wix.CompressionLevelType compressionLevelType;
7259 if (!Wix.Enums.TryParseCompressionLevelType(compressionLevelString, out compressionLevelType)) 7211 if (!Wix.Enums.TryParseCompressionLevelType(compressionLevelString, out compressionLevelType))
7260 { 7212 {
7261 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, compressionLevelString, "high", "low", "medium", "mszip", "none")); 7213 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, compressionLevelString, "high", "low", "medium", "mszip", "none"));
7262 } 7214 }
7263 else 7215 else
7264 { 7216 {
@@ -7267,45 +7219,45 @@ namespace WixToolset
7267 } 7219 }
7268 break; 7220 break;
7269 case "DiskPrompt": 7221 case "DiskPrompt":
7270 diskPrompt = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7222 diskPrompt = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7271 this.core.CreateSimpleReference(sourceLineNumbers, "Property", "DiskPrompt"); // ensure the output has a DiskPrompt Property defined 7223 this.Core.CreateSimpleReference(sourceLineNumbers, "Property", "DiskPrompt"); // ensure the output has a DiskPrompt Property defined
7272 break; 7224 break;
7273 case "EmbedCab": 7225 case "EmbedCab":
7274 embedCab = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 7226 embedCab = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7275 break; 7227 break;
7276 case "Layout": 7228 case "Layout":
7277 case "src": 7229 case "src":
7278 if (null != layout) 7230 if (null != layout)
7279 { 7231 {
7280 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Layout", "src")); 7232 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Layout", "src"));
7281 } 7233 }
7282 7234
7283 if ("src" == attrib.Name.LocalName) 7235 if ("src" == attrib.Name.LocalName)
7284 { 7236 {
7285 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Layout")); 7237 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Layout"));
7286 } 7238 }
7287 layout = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7239 layout = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7288 break; 7240 break;
7289 case "VolumeLabel": 7241 case "VolumeLabel":
7290 volumeLabel = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7242 volumeLabel = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7291 break; 7243 break;
7292 case "Source": 7244 case "Source":
7293 source = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7245 source = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7294 break; 7246 break;
7295 default: 7247 default:
7296 this.core.UnexpectedAttribute(node, attrib); 7248 this.Core.UnexpectedAttribute(node, attrib);
7297 break; 7249 break;
7298 } 7250 }
7299 } 7251 }
7300 else 7252 else
7301 { 7253 {
7302 this.core.ParseExtensionAttribute(node, attrib); 7254 this.Core.ParseExtensionAttribute(node, attrib);
7303 } 7255 }
7304 } 7256 }
7305 7257
7306 if (CompilerConstants.IntegerNotSet == id) 7258 if (CompilerConstants.IntegerNotSet == id)
7307 { 7259 {
7308 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 7260 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
7309 id = CompilerConstants.IllegalInteger; 7261 id = CompilerConstants.IllegalInteger;
7310 } 7262 }
7311 7263
@@ -7315,13 +7267,13 @@ namespace WixToolset
7315 { 7267 {
7316 if (null == cabinet) 7268 if (null == cabinet)
7317 { 7269 {
7318 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Cabinet", "EmbedCab", "yes")); 7270 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Cabinet", "EmbedCab", "yes"));
7319 } 7271 }
7320 else 7272 else
7321 { 7273 {
7322 if (62 < cabinet.Length) 7274 if (62 < cabinet.Length)
7323 { 7275 {
7324 this.core.OnMessage(WixErrors.MediaEmbeddedCabinetNameTooLong(sourceLineNumbers, node.Name.LocalName, "Cabinet", cabinet, cabinet.Length)); 7276 this.Core.OnMessage(WixErrors.MediaEmbeddedCabinetNameTooLong(sourceLineNumbers, node.Name.LocalName, "Cabinet", cabinet, cabinet.Length));
7325 } 7277 }
7326 7278
7327 cabinet = String.Concat("#", cabinet); 7279 cabinet = String.Concat("#", cabinet);
@@ -7330,12 +7282,12 @@ namespace WixToolset
7330 else // external cabinet file 7282 else // external cabinet file
7331 { 7283 {
7332 // external cabinet files must use 8.3 filenames 7284 // external cabinet files must use 8.3 filenames
7333 if (!String.IsNullOrEmpty(cabinet) && !this.core.IsValidShortFilename(cabinet, false)) 7285 if (!String.IsNullOrEmpty(cabinet) && !this.Core.IsValidShortFilename(cabinet, false))
7334 { 7286 {
7335 // WiX variables in the name will trip the "not a valid 8.3 name" switch, so let them through 7287 // WiX variables in the name will trip the "not a valid 8.3 name" switch, so let them through
7336 if (!Common.WixVariableRegex.Match(cabinet).Success) 7288 if (!Common.WixVariableRegex.Match(cabinet).Success)
7337 { 7289 {
7338 this.core.OnMessage(WixWarnings.MediaExternalCabinetFilenameIllegal(sourceLineNumbers, node.Name.LocalName, "Cabinet", cabinet)); 7290 this.Core.OnMessage(WixWarnings.MediaExternalCabinetFilenameIllegal(sourceLineNumbers, node.Name.LocalName, "Cabinet", cabinet));
7339 } 7291 }
7340 } 7292 }
7341 } 7293 }
@@ -7343,7 +7295,7 @@ namespace WixToolset
7343 7295
7344 if (null != compressionLevel && null == cabinet) 7296 if (null != compressionLevel && null == cabinet)
7345 { 7297 {
7346 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Cabinet", "CompressionLevel")); 7298 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Cabinet", "CompressionLevel"));
7347 } 7299 }
7348 7300
7349 if (patch) 7301 if (patch)
@@ -7365,11 +7317,11 @@ namespace WixToolset
7365 case "DigitalSignature": 7317 case "DigitalSignature":
7366 if (YesNoType.Yes == embedCab) 7318 if (YesNoType.Yes == embedCab)
7367 { 7319 {
7368 this.core.OnMessage(WixErrors.SignedEmbeddedCabinet(childSourceLineNumbers)); 7320 this.Core.OnMessage(WixErrors.SignedEmbeddedCabinet(childSourceLineNumbers));
7369 } 7321 }
7370 else if (null == cabinet) 7322 else if (null == cabinet)
7371 { 7323 {
7372 this.core.OnMessage(WixErrors.ExpectedSignedCabinetName(childSourceLineNumbers)); 7324 this.Core.OnMessage(WixErrors.ExpectedSignedCabinetName(childSourceLineNumbers));
7373 } 7325 }
7374 else 7326 else
7375 { 7327 {
@@ -7383,7 +7335,7 @@ namespace WixToolset
7383 } 7335 }
7384 else 7336 else
7385 { 7337 {
7386 this.core.UnexpectedElement(node, child); 7338 this.Core.UnexpectedElement(node, child);
7387 } 7339 }
7388 break; 7340 break;
7389 case "SymbolPath": 7341 case "SymbolPath":
@@ -7397,22 +7349,22 @@ namespace WixToolset
7397 } 7349 }
7398 break; 7350 break;
7399 default: 7351 default:
7400 this.core.UnexpectedElement(node, child); 7352 this.Core.UnexpectedElement(node, child);
7401 break; 7353 break;
7402 } 7354 }
7403 } 7355 }
7404 else 7356 else
7405 { 7357 {
7406 this.core.ParseExtensionElement(node, child); 7358 this.Core.ParseExtensionElement(node, child);
7407 } 7359 }
7408 } 7360 }
7409 7361
7410 7362
7411 7363
7412 // add the row to the section 7364 // add the row to the section
7413 if (!this.core.EncounteredError) 7365 if (!this.Core.EncounteredError)
7414 { 7366 {
7415 MediaRow mediaRow = (MediaRow)this.core.CreateRow(sourceLineNumbers, "Media"); 7367 var mediaRow = (MediaTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Media);
7416 mediaRow.DiskId = id; 7368 mediaRow.DiskId = id;
7417 mediaRow.LastSequence = 0; // this is set in the binder 7369 mediaRow.LastSequence = 0; // this is set in the binder
7418 mediaRow.DiskPrompt = diskPrompt; 7370 mediaRow.DiskPrompt = diskPrompt;
@@ -7424,15 +7376,15 @@ namespace WixToolset
7424 7376
7425 if (null != compressionLevel || null != layout) 7377 if (null != compressionLevel || null != layout)
7426 { 7378 {
7427 WixMediaRow row = (WixMediaRow)this.core.CreateRow(sourceLineNumbers, "WixMedia"); 7379 var row = (WixMediaTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixMedia);
7428 row.DiskId = id; 7380 row.DiskId_ = id;
7429 row.CompressionLevel = compressionLevel; 7381 row.CompressionLevel = compressionLevel;
7430 row.Layout = layout; 7382 row.Layout = layout;
7431 } 7383 }
7432 7384
7433 if (null != symbols) 7385 if (null != symbols)
7434 { 7386 {
7435 WixDeltaPatchSymbolPathsRow symbolRow = (WixDeltaPatchSymbolPathsRow)this.core.CreateRow(sourceLineNumbers, "WixDeltaPatchSymbolPaths"); 7387 var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths);
7436 symbolRow.Id = id.ToString(CultureInfo.InvariantCulture); 7388 symbolRow.Id = id.ToString(CultureInfo.InvariantCulture);
7437 symbolRow.Type = SymbolPathType.Media; 7389 symbolRow.Type = SymbolPathType.Media;
7438 symbolRow.SymbolPaths = symbols; 7390 symbolRow.SymbolPaths = symbols;
@@ -7466,7 +7418,7 @@ namespace WixToolset
7466 switch (attrib.Name.LocalName) 7418 switch (attrib.Name.LocalName)
7467 { 7419 {
7468 case "CabinetTemplate": 7420 case "CabinetTemplate":
7469 string authoredCabinetTemplateValue = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 7421 string authoredCabinetTemplateValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
7470 if (!String.IsNullOrEmpty(authoredCabinetTemplateValue)) 7422 if (!String.IsNullOrEmpty(authoredCabinetTemplateValue))
7471 { 7423 {
7472 cabinetTemplate = authoredCabinetTemplateValue; 7424 cabinetTemplate = authoredCabinetTemplateValue;
@@ -7474,56 +7426,56 @@ namespace WixToolset
7474 7426
7475 // Create an example cabinet name using the maximum number of cabinets supported, 999. 7427 // Create an example cabinet name using the maximum number of cabinets supported, 999.
7476 string exampleCabinetName = String.Format(cabinetTemplate, "###"); 7428 string exampleCabinetName = String.Format(cabinetTemplate, "###");
7477 if (!this.core.IsValidLocIdentifier(exampleCabinetName)) 7429 if (!this.Core.IsValidLocIdentifier(exampleCabinetName))
7478 { 7430 {
7479 // The example name should not match the authored template since that would nullify the 7431 // The example name should not match the authored template since that would nullify the
7480 // reason for having multiple cabients. External cabinet files must also be valid file names. 7432 // reason for having multiple cabients. External cabinet files must also be valid file names.
7481 if (exampleCabinetName.Equals(authoredCabinetTemplateValue) || !this.core.IsValidLongFilename(exampleCabinetName, false)) 7433 if (exampleCabinetName.Equals(authoredCabinetTemplateValue) || !this.Core.IsValidLongFilename(exampleCabinetName, false))
7482 { 7434 {
7483 this.core.OnMessage(WixErrors.InvalidCabinetTemplate(sourceLineNumbers, cabinetTemplate)); 7435 this.Core.OnMessage(WixErrors.InvalidCabinetTemplate(sourceLineNumbers, cabinetTemplate));
7484 } 7436 }
7485 else if (!this.core.IsValidShortFilename(exampleCabinetName, false) && !Common.WixVariableRegex.Match(exampleCabinetName).Success) // ignore short names with wix variables because it rarely works out. 7437 else if (!this.Core.IsValidShortFilename(exampleCabinetName, false) && !Common.WixVariableRegex.Match(exampleCabinetName).Success) // ignore short names with wix variables because it rarely works out.
7486 { 7438 {
7487 this.core.OnMessage(WixWarnings.MediaExternalCabinetFilenameIllegal(sourceLineNumbers, node.Name.LocalName, "CabinetTemplate", cabinetTemplate)); 7439 this.Core.OnMessage(WixWarnings.MediaExternalCabinetFilenameIllegal(sourceLineNumbers, node.Name.LocalName, "CabinetTemplate", cabinetTemplate));
7488 } 7440 }
7489 } 7441 }
7490 break; 7442 break;
7491 case "CompressionLevel": 7443 case "CompressionLevel":
7492 compressionLevel = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7444 compressionLevel = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7493 if (0 < compressionLevel.Length) 7445 if (0 < compressionLevel.Length)
7494 { 7446 {
7495 if (!Wix.Enums.TryParseCompressionLevelType(compressionLevel, out compressionLevelType)) 7447 if (!Wix.Enums.TryParseCompressionLevelType(compressionLevel, out compressionLevelType))
7496 { 7448 {
7497 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, compressionLevel, "high", "low", "medium", "mszip", "none")); 7449 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, compressionLevel, "high", "low", "medium", "mszip", "none"));
7498 } 7450 }
7499 } 7451 }
7500 break; 7452 break;
7501 case "DiskPrompt": 7453 case "DiskPrompt":
7502 diskPrompt = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7454 diskPrompt = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7503 this.core.CreateSimpleReference(sourceLineNumbers, "Property", "DiskPrompt"); // ensure the output has a DiskPrompt Property defined 7455 this.Core.CreateSimpleReference(sourceLineNumbers, "Property", "DiskPrompt"); // ensure the output has a DiskPrompt Property defined
7504 this.core.OnMessage(WixWarnings.ReservedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); 7456 this.Core.OnMessage(WixWarnings.ReservedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
7505 break; 7457 break;
7506 case "EmbedCab": 7458 case "EmbedCab":
7507 embedCab = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 7459 embedCab = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7508 break; 7460 break;
7509 case "VolumeLabel": 7461 case "VolumeLabel":
7510 volumeLabel = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7462 volumeLabel = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7511 this.core.OnMessage(WixWarnings.ReservedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); 7463 this.Core.OnMessage(WixWarnings.ReservedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
7512 break; 7464 break;
7513 case "MaximumUncompressedMediaSize": 7465 case "MaximumUncompressedMediaSize":
7514 maximumUncompressedMediaSize = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, int.MaxValue); 7466 maximumUncompressedMediaSize = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, int.MaxValue);
7515 break; 7467 break;
7516 case "MaximumCabinetSizeForLargeFileSplitting": 7468 case "MaximumCabinetSizeForLargeFileSplitting":
7517 maximumCabinetSizeForLargeFileSplitting = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, CompilerCore.MinValueOfMaxCabSizeForLargeFileSplitting, CompilerCore.MaxValueOfMaxCabSizeForLargeFileSplitting); 7469 maximumCabinetSizeForLargeFileSplitting = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, CompilerCore.MinValueOfMaxCabSizeForLargeFileSplitting, CompilerCore.MaxValueOfMaxCabSizeForLargeFileSplitting);
7518 break; 7470 break;
7519 default: 7471 default:
7520 this.core.UnexpectedAttribute(node, attrib); 7472 this.Core.UnexpectedAttribute(node, attrib);
7521 break; 7473 break;
7522 } 7474 }
7523 } 7475 }
7524 else 7476 else
7525 { 7477 {
7526 this.core.ParseExtensionAttribute(node, attrib); 7478 this.Core.ParseExtensionAttribute(node, attrib);
7527 } 7479 }
7528 } 7480 }
7529 7481
@@ -7535,11 +7487,11 @@ namespace WixToolset
7535 } 7487 }
7536 } 7488 }
7537 7489
7538 if (!this.core.EncounteredError) 7490 if (!this.Core.EncounteredError)
7539 { 7491 {
7540 MediaRow temporaryMediaRow = (MediaRow)this.core.CreateRow(sourceLineNumbers, "Media"); 7492 var temporaryMediaRow = (MediaTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Media, new Identifier(1, AccessModifier.Public));
7541 temporaryMediaRow.DiskId = 1; 7493
7542 WixMediaTemplateRow mediaTemplateRow = (WixMediaTemplateRow)this.core.CreateRow(sourceLineNumbers, "WixMediaTemplate"); 7494 var mediaTemplateRow = (WixMediaTemplateTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixMediaTemplate);
7543 mediaTemplateRow.CabinetTemplate = cabinetTemplate; 7495 mediaTemplateRow.CabinetTemplate = cabinetTemplate;
7544 mediaTemplateRow.VolumeLabel = volumeLabel; 7496 mediaTemplateRow.VolumeLabel = volumeLabel;
7545 mediaTemplateRow.DiskPrompt = diskPrompt; 7497 mediaTemplateRow.DiskPrompt = diskPrompt;
@@ -7606,50 +7558,50 @@ namespace WixToolset
7606 switch (attrib.Name.LocalName) 7558 switch (attrib.Name.LocalName)
7607 { 7559 {
7608 case "Id": 7560 case "Id":
7609 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 7561 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
7610 break; 7562 break;
7611 case "DiskId": 7563 case "DiskId":
7612 diskId = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); 7564 diskId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue);
7613 this.core.CreateSimpleReference(sourceLineNumbers, "Media", diskId.ToString(CultureInfo.InvariantCulture.NumberFormat)); 7565 this.Core.CreateSimpleReference(sourceLineNumbers, "Media", diskId.ToString(CultureInfo.InvariantCulture.NumberFormat));
7614 break; 7566 break;
7615 case "FileCompression": 7567 case "FileCompression":
7616 fileCompression = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 7568 fileCompression = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7617 break; 7569 break;
7618 case "Language": 7570 case "Language":
7619 language = this.core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 7571 language = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
7620 break; 7572 break;
7621 case "SourceFile": 7573 case "SourceFile":
7622 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7574 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7623 break; 7575 break;
7624 default: 7576 default:
7625 this.core.UnexpectedAttribute(node, attrib); 7577 this.Core.UnexpectedAttribute(node, attrib);
7626 break; 7578 break;
7627 } 7579 }
7628 } 7580 }
7629 else 7581 else
7630 { 7582 {
7631 this.core.ParseExtensionAttribute(node, attrib); 7583 this.Core.ParseExtensionAttribute(node, attrib);
7632 } 7584 }
7633 } 7585 }
7634 7586
7635 if (null == id) 7587 if (null == id)
7636 { 7588 {
7637 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 7589 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
7638 } 7590 }
7639 7591
7640 if (null == language) 7592 if (null == language)
7641 { 7593 {
7642 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language")); 7594 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language"));
7643 } 7595 }
7644 7596
7645 if (null == sourceFile) 7597 if (null == sourceFile)
7646 { 7598 {
7647 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); 7599 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
7648 } 7600 }
7649 7601
7650 if (CompilerConstants.IntegerNotSet == diskId) 7602 if (CompilerConstants.IntegerNotSet == diskId)
7651 { 7603 {
7652 this.core.OnMessage(WixErrors.ExpectedAttributeInElementOrParent(sourceLineNumbers, node.Name.LocalName, "DiskId", "Directory")); 7604 this.Core.OnMessage(WixErrors.ExpectedAttributeInElementOrParent(sourceLineNumbers, node.Name.LocalName, "DiskId", "Directory"));
7653 diskId = CompilerConstants.IllegalInteger; 7605 diskId = CompilerConstants.IllegalInteger;
7654 } 7606 }
7655 7607
@@ -7670,37 +7622,37 @@ namespace WixToolset
7670 } 7622 }
7671 break; 7623 break;
7672 default: 7624 default:
7673 this.core.UnexpectedElement(node, child); 7625 this.Core.UnexpectedElement(node, child);
7674 break; 7626 break;
7675 } 7627 }
7676 } 7628 }
7677 else 7629 else
7678 { 7630 {
7679 this.core.ParseExtensionElement(node, child); 7631 this.Core.ParseExtensionElement(node, child);
7680 } 7632 }
7681 } 7633 }
7682 7634
7683 if (!this.core.EncounteredError) 7635 if (!this.Core.EncounteredError)
7684 { 7636 {
7685 Row row = this.core.CreateRow(sourceLineNumbers, "WixMerge", id); 7637 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixMerge, id);
7686 row[1] = language; 7638 row.Set(1, language);
7687 row[2] = directoryId; 7639 row.Set(2, directoryId);
7688 row[3] = sourceFile; 7640 row.Set(3, sourceFile);
7689 row[4] = diskId; 7641 row.Set(4, diskId);
7690 if (YesNoType.Yes == fileCompression) 7642 if (YesNoType.Yes == fileCompression)
7691 { 7643 {
7692 row[5] = 1; 7644 row.Set(5, 1);
7693 } 7645 }
7694 else if (YesNoType.No == fileCompression) 7646 else if (YesNoType.No == fileCompression)
7695 { 7647 {
7696 row[5] = 0; 7648 row.Set(5, 0);
7697 } 7649 }
7698 else // YesNoType.NotSet == fileCompression 7650 else // YesNoType.NotSet == fileCompression
7699 { 7651 {
7700 // and we leave the column null 7652 // and we leave the column null
7701 } 7653 }
7702 row[6] = configData; 7654 row.Set(6, configData);
7703 row[7] = Guid.Empty.ToString("B"); 7655 row.Set(7, Guid.Empty.ToString("B"));
7704 } 7656 }
7705 } 7657 }
7706 7658
@@ -7722,25 +7674,25 @@ namespace WixToolset
7722 switch (attrib.Name.LocalName) 7674 switch (attrib.Name.LocalName)
7723 { 7675 {
7724 case "Name": 7676 case "Name":
7725 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7677 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7726 break; 7678 break;
7727 case "Value": 7679 case "Value":
7728 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7680 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7729 break; 7681 break;
7730 default: 7682 default:
7731 this.core.UnexpectedAttribute(node, attrib); 7683 this.Core.UnexpectedAttribute(node, attrib);
7732 break; 7684 break;
7733 } 7685 }
7734 } 7686 }
7735 else 7687 else
7736 { 7688 {
7737 this.core.ParseExtensionAttribute(node, attrib); 7689 this.Core.ParseExtensionAttribute(node, attrib);
7738 } 7690 }
7739 } 7691 }
7740 7692
7741 if (null == name) 7693 if (null == name)
7742 { 7694 {
7743 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 7695 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
7744 } 7696 }
7745 else // need to hex encode these characters 7697 else // need to hex encode these characters
7746 { 7698 {
@@ -7751,7 +7703,7 @@ namespace WixToolset
7751 7703
7752 if (null == value) 7704 if (null == value)
7753 { 7705 {
7754 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 7706 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
7755 } 7707 }
7756 else // need to hex encode these characters 7708 else // need to hex encode these characters
7757 { 7709 {
@@ -7760,7 +7712,7 @@ namespace WixToolset
7760 value = value.Replace(",", "%2C"); 7712 value = value.Replace(",", "%2C");
7761 } 7713 }
7762 7714
7763 this.core.ParseForExtensionElements(node); 7715 this.Core.ParseForExtensionElements(node);
7764 7716
7765 return String.Concat(name, "=", value); 7717 return String.Concat(name, "=", value);
7766 } 7718 }
@@ -7784,31 +7736,31 @@ namespace WixToolset
7784 switch (attrib.Name.LocalName) 7736 switch (attrib.Name.LocalName)
7785 { 7737 {
7786 case "Id": 7738 case "Id":
7787 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 7739 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
7788 this.core.CreateSimpleReference(sourceLineNumbers, "WixMerge", id); 7740 this.Core.CreateSimpleReference(sourceLineNumbers, "WixMerge", id);
7789 break; 7741 break;
7790 case "Primary": 7742 case "Primary":
7791 primary = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 7743 primary = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7792 break; 7744 break;
7793 default: 7745 default:
7794 this.core.UnexpectedAttribute(node, attrib); 7746 this.Core.UnexpectedAttribute(node, attrib);
7795 break; 7747 break;
7796 } 7748 }
7797 } 7749 }
7798 else 7750 else
7799 { 7751 {
7800 this.core.ParseExtensionAttribute(node, attrib); 7752 this.Core.ParseExtensionAttribute(node, attrib);
7801 } 7753 }
7802 } 7754 }
7803 7755
7804 if (null == id) 7756 if (null == id)
7805 { 7757 {
7806 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 7758 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
7807 } 7759 }
7808 7760
7809 this.core.ParseForExtensionElements(node); 7761 this.Core.ParseForExtensionElements(node);
7810 7762
7811 this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Module, id, (YesNoType.Yes == primary)); 7763 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Module, id, (YesNoType.Yes == primary));
7812 } 7764 }
7813 7765
7814 /// <summary> 7766 /// <summary>
@@ -7834,31 +7786,31 @@ namespace WixToolset
7834 switch (attrib.Name.LocalName) 7786 switch (attrib.Name.LocalName)
7835 { 7787 {
7836 case "Advertise": 7788 case "Advertise":
7837 advertise = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 7789 advertise = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7838 break; 7790 break;
7839 case "Class": 7791 case "Class":
7840 classId = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 7792 classId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
7841 break; 7793 break;
7842 case "ContentType": 7794 case "ContentType":
7843 contentType = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7795 contentType = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7844 break; 7796 break;
7845 case "Default": 7797 case "Default":
7846 returnContentType = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 7798 returnContentType = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7847 break; 7799 break;
7848 default: 7800 default:
7849 this.core.UnexpectedAttribute(node, attrib); 7801 this.Core.UnexpectedAttribute(node, attrib);
7850 break; 7802 break;
7851 } 7803 }
7852 } 7804 }
7853 else 7805 else
7854 { 7806 {
7855 this.core.ParseExtensionAttribute(node, attrib); 7807 this.Core.ParseExtensionAttribute(node, attrib);
7856 } 7808 }
7857 } 7809 }
7858 7810
7859 if (null == contentType) 7811 if (null == contentType)
7860 { 7812 {
7861 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ContentType")); 7813 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ContentType"));
7862 } 7814 }
7863 7815
7864 // if the advertise state has not been set, default to non-advertised 7816 // if the advertise state has not been set, default to non-advertised
@@ -7867,34 +7819,34 @@ namespace WixToolset
7867 advertise = YesNoType.No; 7819 advertise = YesNoType.No;
7868 } 7820 }
7869 7821
7870 this.core.ParseForExtensionElements(node); 7822 this.Core.ParseForExtensionElements(node);
7871 7823
7872 if (YesNoType.Yes == advertise) 7824 if (YesNoType.Yes == advertise)
7873 { 7825 {
7874 if (YesNoType.Yes != parentAdvertised) 7826 if (YesNoType.Yes != parentAdvertised)
7875 { 7827 {
7876 this.core.OnMessage(WixErrors.AdvertiseStateMustMatch(sourceLineNumbers, advertise.ToString(), parentAdvertised.ToString())); 7828 this.Core.OnMessage(WixErrors.AdvertiseStateMustMatch(sourceLineNumbers, advertise.ToString(), parentAdvertised.ToString()));
7877 } 7829 }
7878 7830
7879 if (!this.core.EncounteredError) 7831 if (!this.Core.EncounteredError)
7880 { 7832 {
7881 Row row = this.core.CreateRow(sourceLineNumbers, "MIME"); 7833 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MIME);
7882 row[0] = contentType; 7834 row.Set(0, contentType);
7883 row[1] = extension; 7835 row.Set(1, extension);
7884 row[2] = classId; 7836 row.Set(2, classId);
7885 } 7837 }
7886 } 7838 }
7887 else if (YesNoType.No == advertise) 7839 else if (YesNoType.No == advertise)
7888 { 7840 {
7889 if (YesNoType.Yes == returnContentType && YesNoType.Yes == parentAdvertised) 7841 if (YesNoType.Yes == returnContentType && YesNoType.Yes == parentAdvertised)
7890 { 7842 {
7891 this.core.OnMessage(WixErrors.CannotDefaultMismatchedAdvertiseStates(sourceLineNumbers)); 7843 this.Core.OnMessage(WixErrors.CannotDefaultMismatchedAdvertiseStates(sourceLineNumbers));
7892 } 7844 }
7893 7845
7894 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("MIME\\Database\\Content Type\\", contentType), "Extension", String.Concat(".", extension), componentId); 7846 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("MIME\\Database\\Content Type\\", contentType), "Extension", String.Concat(".", extension), componentId);
7895 if (null != classId) 7847 if (null != classId)
7896 { 7848 {
7897 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("MIME\\Database\\Content Type\\", contentType), "CLSID", classId, componentId); 7849 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("MIME\\Database\\Content Type\\", contentType), "CLSID", classId, componentId);
7898 } 7850 }
7899 } 7851 }
7900 7852
@@ -7922,63 +7874,63 @@ namespace WixToolset
7922 switch (attrib.Name.LocalName) 7874 switch (attrib.Name.LocalName)
7923 { 7875 {
7924 case "Id": 7876 case "Id":
7925 this.activeName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 7877 this.activeName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7926 if ("PUT-MODULE-NAME-HERE" == this.activeName) 7878 if ("PUT-MODULE-NAME-HERE" == this.activeName)
7927 { 7879 {
7928 this.core.OnMessage(WixWarnings.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, this.activeName)); 7880 this.Core.OnMessage(WixWarnings.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, this.activeName));
7929 } 7881 }
7930 else 7882 else
7931 { 7883 {
7932 this.activeName = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 7884 this.activeName = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
7933 } 7885 }
7934 break; 7886 break;
7935 case "Codepage": 7887 case "Codepage":
7936 codepage = this.core.GetAttributeCodePageValue(sourceLineNumbers, attrib); 7888 codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
7937 break; 7889 break;
7938 case "Guid": 7890 case "Guid":
7939 moduleId = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 7891 moduleId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
7940 this.core.OnMessage(WixWarnings.DeprecatedModuleGuidAttribute(sourceLineNumbers)); 7892 this.Core.OnMessage(WixWarnings.DeprecatedModuleGuidAttribute(sourceLineNumbers));
7941 break; 7893 break;
7942 case "Language": 7894 case "Language":
7943 this.activeLanguage = this.core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 7895 this.activeLanguage = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
7944 break; 7896 break;
7945 case "Version": 7897 case "Version":
7946 version = this.core.GetAttributeVersionValue(sourceLineNumbers, attrib); 7898 version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
7947 break; 7899 break;
7948 default: 7900 default:
7949 this.core.UnexpectedAttribute(node, attrib); 7901 this.Core.UnexpectedAttribute(node, attrib);
7950 break; 7902 break;
7951 } 7903 }
7952 } 7904 }
7953 else 7905 else
7954 { 7906 {
7955 this.core.ParseExtensionAttribute(node, attrib); 7907 this.Core.ParseExtensionAttribute(node, attrib);
7956 } 7908 }
7957 } 7909 }
7958 7910
7959 if (null == this.activeName) 7911 if (null == this.activeName)
7960 { 7912 {
7961 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 7913 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
7962 } 7914 }
7963 7915
7964 if (null == this.activeLanguage) 7916 if (null == this.activeLanguage)
7965 { 7917 {
7966 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language")); 7918 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language"));
7967 } 7919 }
7968 7920
7969 if (null == version) 7921 if (null == version)
7970 { 7922 {
7971 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version")); 7923 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
7972 } 7924 }
7973 else if (!CompilerCore.IsValidModuleOrBundleVersion(version)) 7925 else if (!CompilerCore.IsValidModuleOrBundleVersion(version))
7974 { 7926 {
7975 this.core.OnMessage(WixWarnings.InvalidModuleOrBundleVersion(sourceLineNumbers, "Module", version)); 7927 this.Core.OnMessage(WixWarnings.InvalidModuleOrBundleVersion(sourceLineNumbers, "Module", version));
7976 } 7928 }
7977 7929
7978 try 7930 try
7979 { 7931 {
7980 this.compilingModule = true; // notice that we are actually building a Merge Module here 7932 this.compilingModule = true; // notice that we are actually building a Merge Module here
7981 this.core.CreateActiveSection(this.activeName, SectionType.Module, codepage); 7933 this.Core.CreateActiveSection(this.activeName, SectionType.Module, codepage, this.Context.CompilationId);
7982 7934
7983 foreach (XElement child in node.Elements()) 7935 foreach (XElement child in node.Elements())
7984 { 7936 {
@@ -8082,23 +8034,23 @@ namespace WixToolset
8082 this.ParseWixVariableElement(child); 8034 this.ParseWixVariableElement(child);
8083 break; 8035 break;
8084 default: 8036 default:
8085 this.core.UnexpectedElement(node, child); 8037 this.Core.UnexpectedElement(node, child);
8086 break; 8038 break;
8087 } 8039 }
8088 } 8040 }
8089 else 8041 else
8090 { 8042 {
8091 this.core.ParseExtensionElement(node, child); 8043 this.Core.ParseExtensionElement(node, child);
8092 } 8044 }
8093 } 8045 }
8094 8046
8095 8047
8096 if (!this.core.EncounteredError) 8048 if (!this.Core.EncounteredError)
8097 { 8049 {
8098 Row row = this.core.CreateRow(sourceLineNumbers, "ModuleSignature"); 8050 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ModuleSignature);
8099 row[0] = this.activeName; 8051 row.Set(0, this.activeName);
8100 row[1] = this.activeLanguage; 8052 row.Set(1, this.activeLanguage);
8101 row[2] = version; 8053 row.Set(2, version);
8102 } 8054 }
8103 } 8055 }
8104 finally 8056 finally
@@ -8132,49 +8084,49 @@ namespace WixToolset
8132 switch (attrib.Name.LocalName) 8084 switch (attrib.Name.LocalName)
8133 { 8085 {
8134 case "Id": 8086 case "Id":
8135 this.activeName = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 8087 this.activeName = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
8136 break; 8088 break;
8137 case "AllowMajorVersionMismatches": 8089 case "AllowMajorVersionMismatches":
8138 versionMismatches = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 8090 versionMismatches = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8139 break; 8091 break;
8140 case "AllowProductCodeMismatches": 8092 case "AllowProductCodeMismatches":
8141 productMismatches = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 8093 productMismatches = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8142 break; 8094 break;
8143 case "CleanWorkingFolder": 8095 case "CleanWorkingFolder":
8144 clean = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 8096 clean = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8145 break; 8097 break;
8146 case "Codepage": 8098 case "Codepage":
8147 codepage = this.core.GetAttributeCodePageValue(sourceLineNumbers, attrib); 8099 codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
8148 break; 8100 break;
8149 case "OutputPath": 8101 case "OutputPath":
8150 outputPath = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8102 outputPath = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8151 break; 8103 break;
8152 case "SourceList": 8104 case "SourceList":
8153 sourceList = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8105 sourceList = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8154 break; 8106 break;
8155 case "SymbolFlags": 8107 case "SymbolFlags":
8156 symbolFlags = String.Format(CultureInfo.InvariantCulture, "0x{0:x8}", this.core.GetAttributeLongValue(sourceLineNumbers, attrib, 0, uint.MaxValue)); 8108 symbolFlags = String.Format(CultureInfo.InvariantCulture, "0x{0:x8}", this.Core.GetAttributeLongValue(sourceLineNumbers, attrib, 0, uint.MaxValue));
8157 break; 8109 break;
8158 case "WholeFilesOnly": 8110 case "WholeFilesOnly":
8159 wholeFiles = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 8111 wholeFiles = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8160 break; 8112 break;
8161 default: 8113 default:
8162 this.core.UnexpectedAttribute(node, attrib); 8114 this.Core.UnexpectedAttribute(node, attrib);
8163 break; 8115 break;
8164 } 8116 }
8165 } 8117 }
8166 else 8118 else
8167 { 8119 {
8168 this.core.ParseExtensionAttribute(node, attrib); 8120 this.Core.ParseExtensionAttribute(node, attrib);
8169 } 8121 }
8170 } 8122 }
8171 8123
8172 if (null == this.activeName) 8124 if (null == this.activeName)
8173 { 8125 {
8174 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 8126 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
8175 } 8127 }
8176 8128
8177 this.core.CreateActiveSection(this.activeName, SectionType.PatchCreation, codepage); 8129 this.Core.CreateActiveSection(this.activeName, SectionType.PatchCreation, codepage, this.Context.CompilationId);
8178 8130
8179 foreach (XElement child in node.Elements()) 8131 foreach (XElement child in node.Elements())
8180 { 8132 {
@@ -8209,13 +8161,13 @@ namespace WixToolset
8209 targetProducts = String.Concat(targetProducts, targetProduct); 8161 targetProducts = String.Concat(targetProducts, targetProduct);
8210 break; 8162 break;
8211 default: 8163 default:
8212 this.core.UnexpectedElement(node, child); 8164 this.Core.UnexpectedElement(node, child);
8213 break; 8165 break;
8214 } 8166 }
8215 } 8167 }
8216 else 8168 else
8217 { 8169 {
8218 this.core.ParseExtensionElement(node, child); 8170 this.Core.ParseExtensionElement(node, child);
8219 } 8171 }
8220 } 8172 }
8221 8173
@@ -8272,43 +8224,43 @@ namespace WixToolset
8272 switch (attrib.Name.LocalName) 8224 switch (attrib.Name.LocalName)
8273 { 8225 {
8274 case "DiskId": 8226 case "DiskId":
8275 diskId = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); 8227 diskId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue);
8276 break; 8228 break;
8277 case "DiskPrompt": 8229 case "DiskPrompt":
8278 diskPrompt = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8230 diskPrompt = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8279 break; 8231 break;
8280 case "MediaSrcProp": 8232 case "MediaSrcProp":
8281 mediaSrcProp = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8233 mediaSrcProp = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8282 break; 8234 break;
8283 case "Name": 8235 case "Name":
8284 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8236 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8285 break; 8237 break;
8286 case "SequenceStart": 8238 case "SequenceStart":
8287 sequenceStart = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, int.MaxValue); 8239 sequenceStart = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, int.MaxValue);
8288 break; 8240 break;
8289 case "VolumeLabel": 8241 case "VolumeLabel":
8290 volumeLabel = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8242 volumeLabel = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8291 break; 8243 break;
8292 default: 8244 default:
8293 this.core.UnexpectedAttribute(node, attrib); 8245 this.Core.UnexpectedAttribute(node, attrib);
8294 break; 8246 break;
8295 } 8247 }
8296 } 8248 }
8297 else 8249 else
8298 { 8250 {
8299 this.core.ParseExtensionAttribute(node, attrib); 8251 this.Core.ParseExtensionAttribute(node, attrib);
8300 } 8252 }
8301 } 8253 }
8302 8254
8303 if (null == name) 8255 if (null == name)
8304 { 8256 {
8305 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 8257 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
8306 } 8258 }
8307 else if (0 < name.Length) 8259 else if (0 < name.Length)
8308 { 8260 {
8309 if (8 < name.Length) // check the length 8261 if (8 < name.Length) // check the length
8310 { 8262 {
8311 this.core.OnMessage(WixErrors.FamilyNameTooLong(sourceLineNumbers, node.Name.LocalName, "Name", name, name.Length)); 8263 this.Core.OnMessage(WixErrors.FamilyNameTooLong(sourceLineNumbers, node.Name.LocalName, "Name", name, name.Length));
8312 } 8264 }
8313 else // check for illegal characters 8265 else // check for illegal characters
8314 { 8266 {
@@ -8316,7 +8268,7 @@ namespace WixToolset
8316 { 8268 {
8317 if (!Char.IsLetterOrDigit(character) && '_' != character) 8269 if (!Char.IsLetterOrDigit(character) && '_' != character)
8318 { 8270 {
8319 this.core.OnMessage(WixErrors.IllegalFamilyName(sourceLineNumbers, node.Name.LocalName, "Name", name)); 8271 this.Core.OnMessage(WixErrors.IllegalFamilyName(sourceLineNumbers, node.Name.LocalName, "Name", name));
8320 } 8272 }
8321 } 8273 }
8322 } 8274 }
@@ -8338,32 +8290,32 @@ namespace WixToolset
8338 this.ParseProtectFileElement(child, name); 8290 this.ParseProtectFileElement(child, name);
8339 break; 8291 break;
8340 default: 8292 default:
8341 this.core.UnexpectedElement(node, child); 8293 this.Core.UnexpectedElement(node, child);
8342 break; 8294 break;
8343 } 8295 }
8344 } 8296 }
8345 else 8297 else
8346 { 8298 {
8347 this.core.ParseExtensionElement(node, child); 8299 this.Core.ParseExtensionElement(node, child);
8348 } 8300 }
8349 } 8301 }
8350 8302
8351 if (!this.core.EncounteredError) 8303 if (!this.Core.EncounteredError)
8352 { 8304 {
8353 Row row = this.core.CreateRow(sourceLineNumbers, "ImageFamilies"); 8305 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ImageFamilies);
8354 row[0] = name; 8306 row.Set(0, name);
8355 row[1] = mediaSrcProp; 8307 row.Set(1, mediaSrcProp);
8356 if (CompilerConstants.IntegerNotSet != diskId) 8308 if (CompilerConstants.IntegerNotSet != diskId)
8357 { 8309 {
8358 row[2] = diskId; 8310 row.Set(2, diskId);
8359 } 8311 }
8360 8312
8361 if (CompilerConstants.IntegerNotSet != sequenceStart) 8313 if (CompilerConstants.IntegerNotSet != sequenceStart)
8362 { 8314 {
8363 row[3] = sequenceStart; 8315 row.Set(3, sequenceStart);
8364 } 8316 }
8365 row[4] = diskPrompt; 8317 row.Set(4, diskPrompt);
8366 row[5] = volumeLabel; 8318 row.Set(5, volumeLabel);
8367 } 8319 }
8368 } 8320 }
8369 8321
@@ -8387,57 +8339,57 @@ namespace WixToolset
8387 switch (attrib.Name.LocalName) 8339 switch (attrib.Name.LocalName)
8388 { 8340 {
8389 case "Id": 8341 case "Id":
8390 upgrade = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8342 upgrade = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8391 if (13 < upgrade.Length) 8343 if (13 < upgrade.Length)
8392 { 8344 {
8393 this.core.OnMessage(WixErrors.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Id", upgrade, 13)); 8345 this.Core.OnMessage(WixErrors.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Id", upgrade, 13));
8394 } 8346 }
8395 break; 8347 break;
8396 case "SourceFile": 8348 case "SourceFile":
8397 case "src": 8349 case "src":
8398 if (null != sourceFile) 8350 if (null != sourceFile)
8399 { 8351 {
8400 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "SourceFile")); 8352 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "SourceFile"));
8401 } 8353 }
8402 8354
8403 if ("src" == attrib.Name.LocalName) 8355 if ("src" == attrib.Name.LocalName)
8404 { 8356 {
8405 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourceFile")); 8357 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourceFile"));
8406 } 8358 }
8407 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8359 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8408 break; 8360 break;
8409 case "SourcePatch": 8361 case "SourcePatch":
8410 case "srcPatch": 8362 case "srcPatch":
8411 if (null != sourcePatch) 8363 if (null != sourcePatch)
8412 { 8364 {
8413 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "srcPatch", "SourcePatch")); 8365 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "srcPatch", "SourcePatch"));
8414 } 8366 }
8415 8367
8416 if ("srcPatch" == attrib.Name.LocalName) 8368 if ("srcPatch" == attrib.Name.LocalName)
8417 { 8369 {
8418 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourcePatch")); 8370 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourcePatch"));
8419 } 8371 }
8420 sourcePatch = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8372 sourcePatch = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8421 break; 8373 break;
8422 default: 8374 default:
8423 this.core.UnexpectedAttribute(node, attrib); 8375 this.Core.UnexpectedAttribute(node, attrib);
8424 break; 8376 break;
8425 } 8377 }
8426 } 8378 }
8427 else 8379 else
8428 { 8380 {
8429 this.core.ParseExtensionAttribute(node, attrib); 8381 this.Core.ParseExtensionAttribute(node, attrib);
8430 } 8382 }
8431 } 8383 }
8432 8384
8433 if (null == upgrade) 8385 if (null == upgrade)
8434 { 8386 {
8435 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 8387 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
8436 } 8388 }
8437 8389
8438 if (null == sourceFile) 8390 if (null == sourceFile)
8439 { 8391 {
8440 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); 8392 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
8441 } 8393 }
8442 8394
8443 foreach (XElement child in node.Elements()) 8395 foreach (XElement child in node.Elements())
@@ -8456,24 +8408,24 @@ namespace WixToolset
8456 this.ParseUpgradeFileElement(child, upgrade); 8408 this.ParseUpgradeFileElement(child, upgrade);
8457 break; 8409 break;
8458 default: 8410 default:
8459 this.core.UnexpectedElement(node, child); 8411 this.Core.UnexpectedElement(node, child);
8460 break; 8412 break;
8461 } 8413 }
8462 } 8414 }
8463 else 8415 else
8464 { 8416 {
8465 this.core.ParseExtensionElement(node, child); 8417 this.Core.ParseExtensionElement(node, child);
8466 } 8418 }
8467 } 8419 }
8468 8420
8469 if (!this.core.EncounteredError) 8421 if (!this.Core.EncounteredError)
8470 { 8422 {
8471 Row row = this.core.CreateRow(sourceLineNumbers, "UpgradedImages"); 8423 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.UpgradedImages);
8472 row[0] = upgrade; 8424 row.Set(0, upgrade);
8473 row[1] = sourceFile; 8425 row.Set(1, sourceFile);
8474 row[2] = sourcePatch; 8426 row.Set(2, sourcePatch);
8475 row[3] = String.Join(";", symbols); 8427 row.Set(3, String.Join(";", symbols));
8476 row[4] = family; 8428 row.Set(4, family);
8477 } 8429 }
8478 } 8430 }
8479 8431
@@ -8498,31 +8450,31 @@ namespace WixToolset
8498 switch (attrib.Name.LocalName) 8450 switch (attrib.Name.LocalName)
8499 { 8451 {
8500 case "AllowIgnoreOnError": 8452 case "AllowIgnoreOnError":
8501 allowIgnoreOnError = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 8453 allowIgnoreOnError = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8502 break; 8454 break;
8503 case "File": 8455 case "File":
8504 file = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8456 file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8505 break; 8457 break;
8506 case "Ignore": 8458 case "Ignore":
8507 ignore = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 8459 ignore = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8508 break; 8460 break;
8509 case "WholeFile": 8461 case "WholeFile":
8510 wholeFile = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 8462 wholeFile = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8511 break; 8463 break;
8512 default: 8464 default:
8513 this.core.UnexpectedAttribute(node, attrib); 8465 this.Core.UnexpectedAttribute(node, attrib);
8514 break; 8466 break;
8515 } 8467 }
8516 } 8468 }
8517 else 8469 else
8518 { 8470 {
8519 this.core.ParseExtensionAttribute(node, attrib); 8471 this.Core.ParseExtensionAttribute(node, attrib);
8520 } 8472 }
8521 } 8473 }
8522 8474
8523 if (null == file) 8475 if (null == file)
8524 { 8476 {
8525 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File")); 8477 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File"));
8526 } 8478 }
8527 8479
8528 foreach (XElement child in node.Elements()) 8480 foreach (XElement child in node.Elements())
@@ -8535,32 +8487,32 @@ namespace WixToolset
8535 symbols.Add(this.ParseSymbolPathElement(child)); 8487 symbols.Add(this.ParseSymbolPathElement(child));
8536 break; 8488 break;
8537 default: 8489 default:
8538 this.core.UnexpectedElement(node, child); 8490 this.Core.UnexpectedElement(node, child);
8539 break; 8491 break;
8540 } 8492 }
8541 } 8493 }
8542 else 8494 else
8543 { 8495 {
8544 this.core.ParseExtensionElement(node, child); 8496 this.Core.ParseExtensionElement(node, child);
8545 } 8497 }
8546 } 8498 }
8547 8499
8548 if (!this.core.EncounteredError) 8500 if (!this.Core.EncounteredError)
8549 { 8501 {
8550 if (ignore) 8502 if (ignore)
8551 { 8503 {
8552 Row row = this.core.CreateRow(sourceLineNumbers, "UpgradedFilesToIgnore"); 8504 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.UpgradedFilesToIgnore);
8553 row[0] = upgrade; 8505 row.Set(0, upgrade);
8554 row[1] = file; 8506 row.Set(1, file);
8555 } 8507 }
8556 else 8508 else
8557 { 8509 {
8558 Row row = this.core.CreateRow(sourceLineNumbers, "UpgradedFiles_OptionalData"); 8510 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.UpgradedFiles_OptionalData);
8559 row[0] = upgrade; 8511 row.Set(0, upgrade);
8560 row[1] = file; 8512 row.Set(1, file);
8561 row[2] = String.Join(";", symbols); 8513 row.Set(2, String.Join(";", symbols));
8562 row[3] = allowIgnoreOnError ? 1 : 0; 8514 row.Set(3, allowIgnoreOnError ? 1 : 0);
8563 row[4] = wholeFile ? 1 : 0; 8515 row.Set(4, wholeFile ? 1 : 0);
8564 } 8516 }
8565 } 8517 }
8566 } 8518 }
@@ -8588,58 +8540,58 @@ namespace WixToolset
8588 switch (attrib.Name.LocalName) 8540 switch (attrib.Name.LocalName)
8589 { 8541 {
8590 case "Id": 8542 case "Id":
8591 target = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8543 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8592 if (target.Length > 13) 8544 if (target.Length > 13)
8593 { 8545 {
8594 this.core.OnMessage(WixErrors.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Id", target, 13)); 8546 this.Core.OnMessage(WixErrors.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Id", target, 13));
8595 } 8547 }
8596 break; 8548 break;
8597 case "IgnoreMissingFiles": 8549 case "IgnoreMissingFiles":
8598 ignore = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 8550 ignore = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8599 break; 8551 break;
8600 case "Order": 8552 case "Order":
8601 order = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, int.MinValue + 2, int.MaxValue); 8553 order = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, int.MinValue + 2, int.MaxValue);
8602 break; 8554 break;
8603 case "SourceFile": 8555 case "SourceFile":
8604 case "src": 8556 case "src":
8605 if (null != sourceFile) 8557 if (null != sourceFile)
8606 { 8558 {
8607 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "SourceFile")); 8559 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "SourceFile"));
8608 } 8560 }
8609 8561
8610 if ("src" == attrib.Name.LocalName) 8562 if ("src" == attrib.Name.LocalName)
8611 { 8563 {
8612 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourceFile")); 8564 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourceFile"));
8613 } 8565 }
8614 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8566 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8615 break; 8567 break;
8616 case "Validation": 8568 case "Validation":
8617 validation = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8569 validation = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8618 break; 8570 break;
8619 default: 8571 default:
8620 this.core.UnexpectedAttribute(node, attrib); 8572 this.Core.UnexpectedAttribute(node, attrib);
8621 break; 8573 break;
8622 } 8574 }
8623 } 8575 }
8624 else 8576 else
8625 { 8577 {
8626 this.core.ParseExtensionAttribute(node, attrib); 8578 this.Core.ParseExtensionAttribute(node, attrib);
8627 } 8579 }
8628 } 8580 }
8629 8581
8630 if (null == target) 8582 if (null == target)
8631 { 8583 {
8632 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 8584 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
8633 } 8585 }
8634 8586
8635 if (null == sourceFile) 8587 if (null == sourceFile)
8636 { 8588 {
8637 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); 8589 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
8638 } 8590 }
8639 8591
8640 if (CompilerConstants.IntegerNotSet == order) 8592 if (CompilerConstants.IntegerNotSet == order)
8641 { 8593 {
8642 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Order")); 8594 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Order"));
8643 } 8595 }
8644 8596
8645 foreach (XElement child in node.Elements()) 8597 foreach (XElement child in node.Elements())
@@ -8662,26 +8614,26 @@ namespace WixToolset
8662 this.ParseTargetFileElement(child, target, family); 8614 this.ParseTargetFileElement(child, target, family);
8663 break; 8615 break;
8664 default: 8616 default:
8665 this.core.UnexpectedElement(node, child); 8617 this.Core.UnexpectedElement(node, child);
8666 break; 8618 break;
8667 } 8619 }
8668 } 8620 }
8669 else 8621 else
8670 { 8622 {
8671 this.core.ParseExtensionElement(node, child); 8623 this.Core.ParseExtensionElement(node, child);
8672 } 8624 }
8673 } 8625 }
8674 8626
8675 if (!this.core.EncounteredError) 8627 if (!this.Core.EncounteredError)
8676 { 8628 {
8677 Row row = this.core.CreateRow(sourceLineNumbers, "TargetImages"); 8629 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.TargetImages);
8678 row[0] = target; 8630 row.Set(0, target);
8679 row[1] = sourceFile; 8631 row.Set(1, sourceFile);
8680 row[2] = symbols; 8632 row.Set(2, symbols);
8681 row[3] = upgrade; 8633 row.Set(3, upgrade);
8682 row[4] = order; 8634 row.Set(4, order);
8683 row[5] = validation; 8635 row.Set(5, validation);
8684 row[6] = ignore ? 1 : 0; 8636 row.Set(6, ignore ? 1 : 0);
8685 } 8637 }
8686 } 8638 }
8687 8639
@@ -8708,22 +8660,22 @@ namespace WixToolset
8708 switch (attrib.Name.LocalName) 8660 switch (attrib.Name.LocalName)
8709 { 8661 {
8710 case "Id": 8662 case "Id":
8711 file = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8663 file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8712 break; 8664 break;
8713 default: 8665 default:
8714 this.core.UnexpectedAttribute(node, attrib); 8666 this.Core.UnexpectedAttribute(node, attrib);
8715 break; 8667 break;
8716 } 8668 }
8717 } 8669 }
8718 else 8670 else
8719 { 8671 {
8720 this.core.ParseExtensionAttribute(node, attrib); 8672 this.Core.ParseExtensionAttribute(node, attrib);
8721 } 8673 }
8722 } 8674 }
8723 8675
8724 if (null == file) 8676 if (null == file)
8725 { 8677 {
8726 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 8678 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
8727 } 8679 }
8728 8680
8729 foreach (XElement child in node.Elements()) 8681 foreach (XElement child in node.Elements())
@@ -8742,34 +8694,34 @@ namespace WixToolset
8742 symbols = this.ParseSymbolPathElement(child); 8694 symbols = this.ParseSymbolPathElement(child);
8743 break; 8695 break;
8744 default: 8696 default:
8745 this.core.UnexpectedElement(node, child); 8697 this.Core.UnexpectedElement(node, child);
8746 break; 8698 break;
8747 } 8699 }
8748 } 8700 }
8749 else 8701 else
8750 { 8702 {
8751 this.core.ParseExtensionElement(node, child); 8703 this.Core.ParseExtensionElement(node, child);
8752 } 8704 }
8753 } 8705 }
8754 8706
8755 if (!this.core.EncounteredError) 8707 if (!this.Core.EncounteredError)
8756 { 8708 {
8757 Row row = this.core.CreateRow(sourceLineNumbers, "TargetFiles_OptionalData"); 8709 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.TargetFiles_OptionalData);
8758 row[0] = target; 8710 row.Set(0, target);
8759 row[1] = file; 8711 row.Set(1, file);
8760 row[2] = symbols; 8712 row.Set(2, symbols);
8761 row[3] = ignoreOffsets; 8713 row.Set(3, ignoreOffsets);
8762 row[4] = ignoreLengths; 8714 row.Set(4, ignoreLengths);
8763 8715
8764 if (null != protectOffsets) 8716 if (null != protectOffsets)
8765 { 8717 {
8766 row[5] = protectOffsets; 8718 row.Set(5, protectOffsets);
8767 8719
8768 Row row2 = this.core.CreateRow(sourceLineNumbers, "FamilyFileRanges"); 8720 var row2 = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.FamilyFileRanges);
8769 row2[0] = family; 8721 row2.Set(0, family);
8770 row2[1] = file; 8722 row2.Set(1, file);
8771 row2[2] = protectOffsets; 8723 row2.Set(2, protectOffsets);
8772 row2[3] = protectLengths; 8724 row2.Set(3, protectLengths);
8773 } 8725 }
8774 } 8726 }
8775 } 8727 }
@@ -8798,48 +8750,48 @@ namespace WixToolset
8798 switch (attrib.Name.LocalName) 8750 switch (attrib.Name.LocalName)
8799 { 8751 {
8800 case "File": 8752 case "File":
8801 file = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8753 file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8802 break; 8754 break;
8803 case "Order": 8755 case "Order":
8804 order = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, int.MinValue + 2, int.MaxValue); 8756 order = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, int.MinValue + 2, int.MaxValue);
8805 break; 8757 break;
8806 case "Source": 8758 case "Source":
8807 case "src": 8759 case "src":
8808 if (null != source) 8760 if (null != source)
8809 { 8761 {
8810 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "Source")); 8762 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "Source"));
8811 } 8763 }
8812 8764
8813 if ("src" == attrib.Name.LocalName) 8765 if ("src" == attrib.Name.LocalName)
8814 { 8766 {
8815 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Source")); 8767 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Source"));
8816 } 8768 }
8817 source = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8769 source = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8818 break; 8770 break;
8819 default: 8771 default:
8820 this.core.UnexpectedAttribute(node, attrib); 8772 this.Core.UnexpectedAttribute(node, attrib);
8821 break; 8773 break;
8822 } 8774 }
8823 } 8775 }
8824 else 8776 else
8825 { 8777 {
8826 this.core.ParseExtensionAttribute(node, attrib); 8778 this.Core.ParseExtensionAttribute(node, attrib);
8827 } 8779 }
8828 } 8780 }
8829 8781
8830 if (null == file) 8782 if (null == file)
8831 { 8783 {
8832 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File")); 8784 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File"));
8833 } 8785 }
8834 8786
8835 if (null == source) 8787 if (null == source)
8836 { 8788 {
8837 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Source")); 8789 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Source"));
8838 } 8790 }
8839 8791
8840 if (CompilerConstants.IntegerNotSet == order) 8792 if (CompilerConstants.IntegerNotSet == order)
8841 { 8793 {
8842 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Order")); 8794 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Order"));
8843 } 8795 }
8844 8796
8845 foreach (XElement child in node.Elements()) 8797 foreach (XElement child in node.Elements())
@@ -8858,42 +8810,42 @@ namespace WixToolset
8858 symbols = this.ParseSymbolPathElement(child); 8810 symbols = this.ParseSymbolPathElement(child);
8859 break; 8811 break;
8860 default: 8812 default:
8861 this.core.UnexpectedElement(node, child); 8813 this.Core.UnexpectedElement(node, child);
8862 break; 8814 break;
8863 } 8815 }
8864 } 8816 }
8865 else 8817 else
8866 { 8818 {
8867 this.core.ParseExtensionElement(node, child); 8819 this.Core.ParseExtensionElement(node, child);
8868 } 8820 }
8869 } 8821 }
8870 8822
8871 if (!this.core.EncounteredError) 8823 if (!this.Core.EncounteredError)
8872 { 8824 {
8873 Row row = this.core.CreateRow(sourceLineNumbers, "ExternalFiles"); 8825 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ExternalFiles);
8874 row[0] = family; 8826 row.Set(0, family);
8875 row[1] = file; 8827 row.Set(1, file);
8876 row[2] = source; 8828 row.Set(2, source);
8877 row[3] = symbols; 8829 row.Set(3, symbols);
8878 row[4] = ignoreOffsets; 8830 row.Set(4, ignoreOffsets);
8879 row[5] = ignoreLengths; 8831 row.Set(5, ignoreLengths);
8880 if (null != protectOffsets) 8832 if (null != protectOffsets)
8881 { 8833 {
8882 row[6] = protectOffsets; 8834 row.Set(6, protectOffsets);
8883 } 8835 }
8884 8836
8885 if (CompilerConstants.IntegerNotSet != order) 8837 if (CompilerConstants.IntegerNotSet != order)
8886 { 8838 {
8887 row[7] = order; 8839 row.Set(7, order);
8888 } 8840 }
8889 8841
8890 if (null != protectOffsets) 8842 if (null != protectOffsets)
8891 { 8843 {
8892 Row row2 = this.core.CreateRow(sourceLineNumbers, "FamilyFileRanges"); 8844 var row2 = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.FamilyFileRanges);
8893 row2[0] = family; 8845 row2.Set(0, family);
8894 row2[1] = file; 8846 row2.Set(1, file);
8895 row2[2] = protectOffsets; 8847 row2.Set(2, protectOffsets);
8896 row2[3] = protectLengths; 8848 row2.Set(3, protectLengths);
8897 } 8849 }
8898 } 8850 }
8899 } 8851 }
@@ -8917,22 +8869,22 @@ namespace WixToolset
8917 switch (attrib.Name.LocalName) 8869 switch (attrib.Name.LocalName)
8918 { 8870 {
8919 case "File": 8871 case "File":
8920 file = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8872 file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8921 break; 8873 break;
8922 default: 8874 default:
8923 this.core.UnexpectedAttribute(node, attrib); 8875 this.Core.UnexpectedAttribute(node, attrib);
8924 break; 8876 break;
8925 } 8877 }
8926 } 8878 }
8927 else 8879 else
8928 { 8880 {
8929 this.core.ParseExtensionAttribute(node, attrib); 8881 this.Core.ParseExtensionAttribute(node, attrib);
8930 } 8882 }
8931 } 8883 }
8932 8884
8933 if (null == file) 8885 if (null == file)
8934 { 8886 {
8935 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File")); 8887 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File"));
8936 } 8888 }
8937 8889
8938 foreach (XElement child in node.Elements()) 8890 foreach (XElement child in node.Elements())
@@ -8945,28 +8897,28 @@ namespace WixToolset
8945 this.ParseRangeElement(child, ref protectOffsets, ref protectLengths); 8897 this.ParseRangeElement(child, ref protectOffsets, ref protectLengths);
8946 break; 8898 break;
8947 default: 8899 default:
8948 this.core.UnexpectedElement(node, child); 8900 this.Core.UnexpectedElement(node, child);
8949 break; 8901 break;
8950 } 8902 }
8951 } 8903 }
8952 else 8904 else
8953 { 8905 {
8954 this.core.ParseExtensionElement(node, child); 8906 this.Core.ParseExtensionElement(node, child);
8955 } 8907 }
8956 } 8908 }
8957 8909
8958 if (null == protectOffsets || null == protectLengths) 8910 if (null == protectOffsets || null == protectLengths)
8959 { 8911 {
8960 this.core.OnMessage(WixErrors.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "ProtectRange")); 8912 this.Core.OnMessage(WixErrors.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "ProtectRange"));
8961 } 8913 }
8962 8914
8963 if (!this.core.EncounteredError) 8915 if (!this.Core.EncounteredError)
8964 { 8916 {
8965 Row row = this.core.CreateRow(sourceLineNumbers, "FamilyFileRanges"); 8917 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.FamilyFileRanges);
8966 row[0] = family; 8918 row.Set(0, family);
8967 row[1] = file; 8919 row.Set(1, file);
8968 row[2] = protectOffsets; 8920 row.Set(2, protectOffsets);
8969 row[3] = protectLengths; 8921 row.Set(3, protectLengths);
8970 } 8922 }
8971 } 8923 }
8972 8924
@@ -8989,33 +8941,33 @@ namespace WixToolset
8989 switch (attrib.Name.LocalName) 8941 switch (attrib.Name.LocalName)
8990 { 8942 {
8991 case "Length": 8943 case "Length":
8992 length = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8944 length = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8993 break; 8945 break;
8994 case "Offset": 8946 case "Offset":
8995 offset = this.core.GetAttributeValue(sourceLineNumbers, attrib); 8947 offset = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8996 break; 8948 break;
8997 default: 8949 default:
8998 this.core.UnexpectedAttribute(node, attrib); 8950 this.Core.UnexpectedAttribute(node, attrib);
8999 break; 8951 break;
9000 } 8952 }
9001 } 8953 }
9002 else 8954 else
9003 { 8955 {
9004 this.core.ParseExtensionAttribute(node, attrib); 8956 this.Core.ParseExtensionAttribute(node, attrib);
9005 } 8957 }
9006 } 8958 }
9007 8959
9008 if (null == length) 8960 if (null == length)
9009 { 8961 {
9010 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Length")); 8962 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Length"));
9011 } 8963 }
9012 8964
9013 if (null == offset) 8965 if (null == offset)
9014 { 8966 {
9015 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Offset")); 8967 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Offset"));
9016 } 8968 }
9017 8969
9018 this.core.ParseForExtensionElements(node); 8970 this.Core.ParseForExtensionElements(node);
9019 8971
9020 if (null != lengths) 8972 if (null != lengths)
9021 { 8973 {
@@ -9056,50 +9008,50 @@ namespace WixToolset
9056 { 9008 {
9057 case "Id": 9009 case "Id":
9058 case "Name": 9010 case "Name":
9059 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9011 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9060 break; 9012 break;
9061 case "Company": 9013 case "Company":
9062 company = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9014 company = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9063 break; 9015 break;
9064 case "Value": 9016 case "Value":
9065 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9017 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9066 break; 9018 break;
9067 default: 9019 default:
9068 this.core.UnexpectedAttribute(node, attrib); 9020 this.Core.UnexpectedAttribute(node, attrib);
9069 break; 9021 break;
9070 } 9022 }
9071 } 9023 }
9072 else 9024 else
9073 { 9025 {
9074 this.core.ParseExtensionAttribute(node, attrib); 9026 this.Core.ParseExtensionAttribute(node, attrib);
9075 } 9027 }
9076 } 9028 }
9077 9029
9078 if (null == name) 9030 if (null == name)
9079 { 9031 {
9080 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 9032 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
9081 } 9033 }
9082 9034
9083 if (null == value) 9035 if (null == value)
9084 { 9036 {
9085 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 9037 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
9086 } 9038 }
9087 9039
9088 this.core.ParseForExtensionElements(node); 9040 this.Core.ParseForExtensionElements(node);
9089 9041
9090 if (patch) 9042 if (patch)
9091 { 9043 {
9092 // /Patch/PatchProperty goes directly into MsiPatchMetadata table 9044 // /Patch/PatchProperty goes directly into MsiPatchMetadata table
9093 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9045 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9094 row[0] = company; 9046 row.Set(0, company);
9095 row[1] = name; 9047 row.Set(1, name);
9096 row[2] = value; 9048 row.Set(2, value);
9097 } 9049 }
9098 else 9050 else
9099 { 9051 {
9100 if (null != company) 9052 if (null != company)
9101 { 9053 {
9102 this.core.OnMessage(WixErrors.UnexpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Company")); 9054 this.Core.OnMessage(WixErrors.UnexpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Company"));
9103 } 9055 }
9104 this.ProcessProperties(sourceLineNumbers, name, value); 9056 this.ProcessProperties(sourceLineNumbers, name, value);
9105 } 9057 }
@@ -9124,68 +9076,68 @@ namespace WixToolset
9124 switch (attrib.Name.LocalName) 9076 switch (attrib.Name.LocalName)
9125 { 9077 {
9126 case "PatchFamily": 9078 case "PatchFamily":
9127 family = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 9079 family = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
9128 break; 9080 break;
9129 case "ProductCode": 9081 case "ProductCode":
9130 if (null != target) 9082 if (null != target)
9131 { 9083 {
9132 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Target", "TargetImage")); 9084 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Target", "TargetImage"));
9133 } 9085 }
9134 target = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 9086 target = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
9135 break; 9087 break;
9136 case "Target": 9088 case "Target":
9137 if (null != target) 9089 if (null != target)
9138 { 9090 {
9139 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "TargetImage", "ProductCode")); 9091 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "TargetImage", "ProductCode"));
9140 } 9092 }
9141 this.core.OnMessage(WixWarnings.DeprecatedPatchSequenceTargetAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); 9093 this.Core.OnMessage(WixWarnings.DeprecatedPatchSequenceTargetAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
9142 target = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9094 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9143 break; 9095 break;
9144 case "TargetImage": 9096 case "TargetImage":
9145 if (null != target) 9097 if (null != target)
9146 { 9098 {
9147 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Target", "ProductCode")); 9099 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Target", "ProductCode"));
9148 } 9100 }
9149 target = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9101 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9150 this.core.CreateSimpleReference(sourceLineNumbers, "TargetImages", target); 9102 this.Core.CreateSimpleReference(sourceLineNumbers, "TargetImages", target);
9151 break; 9103 break;
9152 case "Sequence": 9104 case "Sequence":
9153 sequence = this.core.GetAttributeVersionValue(sourceLineNumbers, attrib); 9105 sequence = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
9154 break; 9106 break;
9155 case "Supersede": 9107 case "Supersede":
9156 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 9108 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
9157 { 9109 {
9158 attributes |= 0x1; 9110 attributes |= 0x1;
9159 } 9111 }
9160 break; 9112 break;
9161 default: 9113 default:
9162 this.core.UnexpectedAttribute(node, attrib); 9114 this.Core.UnexpectedAttribute(node, attrib);
9163 break; 9115 break;
9164 } 9116 }
9165 } 9117 }
9166 else 9118 else
9167 { 9119 {
9168 this.core.ParseExtensionAttribute(node, attrib); 9120 this.Core.ParseExtensionAttribute(node, attrib);
9169 } 9121 }
9170 } 9122 }
9171 9123
9172 if (null == family) 9124 if (null == family)
9173 { 9125 {
9174 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PatchFamily")); 9126 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PatchFamily"));
9175 } 9127 }
9176 9128
9177 this.core.ParseForExtensionElements(node); 9129 this.Core.ParseForExtensionElements(node);
9178 9130
9179 if (!this.core.EncounteredError) 9131 if (!this.Core.EncounteredError)
9180 { 9132 {
9181 Row row = this.core.CreateRow(sourceLineNumbers, "PatchSequence"); 9133 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchSequence);
9182 row[0] = family; 9134 row.Set(0, family);
9183 row[1] = target; 9135 row.Set(1, target);
9184 if (!String.IsNullOrEmpty(sequence)) 9136 if (!String.IsNullOrEmpty(sequence))
9185 { 9137 {
9186 row[2] = sequence; 9138 row.Set(2, sequence);
9187 } 9139 }
9188 row[3] = attributes; 9140 row.Set(3, attributes);
9189 } 9141 }
9190 } 9142 }
9191 9143
@@ -9206,29 +9158,29 @@ namespace WixToolset
9206 switch (attrib.Name.LocalName) 9158 switch (attrib.Name.LocalName)
9207 { 9159 {
9208 case "Id": 9160 case "Id":
9209 id = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9161 id = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9210 if (id.Length > 0 && "*" != id) 9162 if (id.Length > 0 && "*" != id)
9211 { 9163 {
9212 id = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 9164 id = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
9213 } 9165 }
9214 break; 9166 break;
9215 default: 9167 default:
9216 this.core.UnexpectedAttribute(node, attrib); 9168 this.Core.UnexpectedAttribute(node, attrib);
9217 break; 9169 break;
9218 } 9170 }
9219 } 9171 }
9220 else 9172 else
9221 { 9173 {
9222 this.core.ParseExtensionAttribute(node, attrib); 9174 this.Core.ParseExtensionAttribute(node, attrib);
9223 } 9175 }
9224 } 9176 }
9225 9177
9226 if (null == id) 9178 if (null == id)
9227 { 9179 {
9228 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 9180 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
9229 } 9181 }
9230 9182
9231 this.core.ParseForExtensionElements(node); 9183 this.Core.ParseForExtensionElements(node);
9232 9184
9233 return id; 9185 return id;
9234 } 9186 }
@@ -9250,16 +9202,16 @@ namespace WixToolset
9250 switch (attrib.Name.LocalName) 9202 switch (attrib.Name.LocalName)
9251 { 9203 {
9252 case "Replace": 9204 case "Replace":
9253 replace = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 9205 replace = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
9254 break; 9206 break;
9255 default: 9207 default:
9256 this.core.UnexpectedAttribute(node, attrib); 9208 this.Core.UnexpectedAttribute(node, attrib);
9257 break; 9209 break;
9258 } 9210 }
9259 } 9211 }
9260 else 9212 else
9261 { 9213 {
9262 this.core.ParseExtensionAttribute(node, attrib); 9214 this.Core.ParseExtensionAttribute(node, attrib);
9263 } 9215 }
9264 } 9216 }
9265 9217
@@ -9273,7 +9225,7 @@ namespace WixToolset
9273 string id = this.ParseTargetProductCodeElement(child); 9225 string id = this.ParseTargetProductCodeElement(child);
9274 if (0 == String.CompareOrdinal("*", id)) 9226 if (0 == String.CompareOrdinal("*", id))
9275 { 9227 {
9276 this.core.OnMessage(WixErrors.IllegalAttributeValueWhenNested(sourceLineNumbers, child.Name.LocalName, "Id", id, node.Name.LocalName)); 9228 this.Core.OnMessage(WixErrors.IllegalAttributeValueWhenNested(sourceLineNumbers, child.Name.LocalName, "Id", id, node.Name.LocalName));
9277 } 9229 }
9278 else 9230 else
9279 { 9231 {
@@ -9281,29 +9233,29 @@ namespace WixToolset
9281 } 9233 }
9282 break; 9234 break;
9283 default: 9235 default:
9284 this.core.UnexpectedElement(node, child); 9236 this.Core.UnexpectedElement(node, child);
9285 break; 9237 break;
9286 } 9238 }
9287 } 9239 }
9288 else 9240 else
9289 { 9241 {
9290 this.core.ParseExtensionElement(node, child); 9242 this.Core.ParseExtensionElement(node, child);
9291 } 9243 }
9292 } 9244 }
9293 9245
9294 if (!this.core.EncounteredError) 9246 if (!this.Core.EncounteredError)
9295 { 9247 {
9296 // By default, target ProductCodes should be added. 9248 // By default, target ProductCodes should be added.
9297 if (!replace) 9249 if (!replace)
9298 { 9250 {
9299 Row row = this.core.CreateRow(sourceLineNumbers, "WixPatchTarget"); 9251 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchTarget);
9300 row[0] = "*"; 9252 row.Set(0, "*");
9301 } 9253 }
9302 9254
9303 foreach (string targetProductCode in targetProductCodes) 9255 foreach (string targetProductCode in targetProductCodes)
9304 { 9256 {
9305 Row row = this.core.CreateRow(sourceLineNumbers, "WixPatchTarget"); 9257 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchTarget);
9306 row[0] = targetProductCode; 9258 row.Set(0, targetProductCode);
9307 } 9259 }
9308 } 9260 }
9309 } 9261 }
@@ -9325,25 +9277,25 @@ namespace WixToolset
9325 switch (attrib.Name.LocalName) 9277 switch (attrib.Name.LocalName)
9326 { 9278 {
9327 case "Id": 9279 case "Id":
9328 id = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 9280 id = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
9329 break; 9281 break;
9330 default: 9282 default:
9331 this.core.UnexpectedAttribute(node, attrib); 9283 this.Core.UnexpectedAttribute(node, attrib);
9332 break; 9284 break;
9333 } 9285 }
9334 } 9286 }
9335 else 9287 else
9336 { 9288 {
9337 this.core.ParseExtensionAttribute(node, attrib); 9289 this.Core.ParseExtensionAttribute(node, attrib);
9338 } 9290 }
9339 } 9291 }
9340 9292
9341 if (null == id) 9293 if (null == id)
9342 { 9294 {
9343 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 9295 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
9344 } 9296 }
9345 9297
9346 this.core.ParseForExtensionElements(node); 9298 this.Core.ParseForExtensionElements(node);
9347 9299
9348 return id; 9300 return id;
9349 } 9301 }
@@ -9365,25 +9317,25 @@ namespace WixToolset
9365 switch (attrib.Name.LocalName) 9317 switch (attrib.Name.LocalName)
9366 { 9318 {
9367 case "Path": 9319 case "Path":
9368 path = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9320 path = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9369 break; 9321 break;
9370 default: 9322 default:
9371 this.core.UnexpectedAttribute(node, attrib); 9323 this.Core.UnexpectedAttribute(node, attrib);
9372 break; 9324 break;
9373 } 9325 }
9374 } 9326 }
9375 else 9327 else
9376 { 9328 {
9377 this.core.ParseExtensionAttribute(node, attrib); 9329 this.Core.ParseExtensionAttribute(node, attrib);
9378 } 9330 }
9379 } 9331 }
9380 9332
9381 if (null == path) 9333 if (null == path)
9382 { 9334 {
9383 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Path")); 9335 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Path"));
9384 } 9336 }
9385 9337
9386 this.core.ParseForExtensionElements(node); 9338 this.Core.ParseForExtensionElements(node);
9387 9339
9388 return path; 9340 return path;
9389 } 9341 }
@@ -9422,10 +9374,10 @@ namespace WixToolset
9422 switch (attrib.Name.LocalName) 9374 switch (attrib.Name.LocalName)
9423 { 9375 {
9424 case "Id": 9376 case "Id":
9425 patchId = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, true); 9377 patchId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true);
9426 break; 9378 break;
9427 case "Codepage": 9379 case "Codepage":
9428 codepage = this.core.GetAttributeCodePageValue(sourceLineNumbers, attrib); 9380 codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
9429 break; 9381 break;
9430 case "AllowMajorVersionMismatches": 9382 case "AllowMajorVersionMismatches":
9431 ////versionMismatches = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)); 9383 ////versionMismatches = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
@@ -9434,58 +9386,58 @@ namespace WixToolset
9434 ////productMismatches = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)); 9386 ////productMismatches = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
9435 break; 9387 break;
9436 case "AllowRemoval": 9388 case "AllowRemoval":
9437 allowRemoval = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)); 9389 allowRemoval = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
9438 break; 9390 break;
9439 case "Classification": 9391 case "Classification":
9440 classification = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9392 classification = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9441 break; 9393 break;
9442 case "ClientPatchId": 9394 case "ClientPatchId":
9443 clientPatchId = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9395 clientPatchId = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9444 break; 9396 break;
9445 case "Description": 9397 case "Description":
9446 description = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9398 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9447 break; 9399 break;
9448 case "DisplayName": 9400 case "DisplayName":
9449 displayName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9401 displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9450 break; 9402 break;
9451 case "Comments": 9403 case "Comments":
9452 comments = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9404 comments = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9453 break; 9405 break;
9454 case "Manufacturer": 9406 case "Manufacturer":
9455 manufacturer = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9407 manufacturer = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9456 break; 9408 break;
9457 case "MinorUpdateTargetRTM": 9409 case "MinorUpdateTargetRTM":
9458 minorUpdateTargetRTM = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 9410 minorUpdateTargetRTM = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
9459 break; 9411 break;
9460 case "MoreInfoURL": 9412 case "MoreInfoURL":
9461 moreInfoUrl = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9413 moreInfoUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9462 break; 9414 break;
9463 case "OptimizedInstallMode": 9415 case "OptimizedInstallMode":
9464 optimizedInstallMode = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 9416 optimizedInstallMode = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
9465 break; 9417 break;
9466 case "TargetProductName": 9418 case "TargetProductName":
9467 targetProductName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9419 targetProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9468 break; 9420 break;
9469 case "ApiPatchingSymbolNoImagehlpFlag": 9421 case "ApiPatchingSymbolNoImagehlpFlag":
9470 apiPatchingSymbolFlags |= (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_IMAGEHLP : 0; 9422 apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_IMAGEHLP : 0;
9471 break; 9423 break;
9472 case "ApiPatchingSymbolNoFailuresFlag": 9424 case "ApiPatchingSymbolNoFailuresFlag":
9473 apiPatchingSymbolFlags |= (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_FAILURES : 0; 9425 apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_FAILURES : 0;
9474 break; 9426 break;
9475 case "ApiPatchingSymbolUndecoratedTooFlag": 9427 case "ApiPatchingSymbolUndecoratedTooFlag":
9476 apiPatchingSymbolFlags |= (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_UNDECORATED_TOO : 0; 9428 apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_UNDECORATED_TOO : 0;
9477 break; 9429 break;
9478 case "OptimizePatchSizeForLargeFiles": 9430 case "OptimizePatchSizeForLargeFiles":
9479 optimizePatchSizeForLargeFiles = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)); 9431 optimizePatchSizeForLargeFiles = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
9480 break; 9432 break;
9481 default: 9433 default:
9482 this.core.UnexpectedAttribute(node, attrib); 9434 this.Core.UnexpectedAttribute(node, attrib);
9483 break; 9435 break;
9484 } 9436 }
9485 } 9437 }
9486 else 9438 else
9487 { 9439 {
9488 this.core.ParseExtensionAttribute(node, attrib); 9440 this.Core.ParseExtensionAttribute(node, attrib);
9489 } 9441 }
9490 } 9442 }
9491 9443
@@ -9498,11 +9450,11 @@ namespace WixToolset
9498 9450
9499 if (null == this.activeName) 9451 if (null == this.activeName)
9500 { 9452 {
9501 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 9453 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
9502 } 9454 }
9503 if (null == classification) 9455 if (null == classification)
9504 { 9456 {
9505 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Classification")); 9457 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Classification"));
9506 } 9458 }
9507 if (null == clientPatchId) 9459 if (null == clientPatchId)
9508 { 9460 {
@@ -9510,18 +9462,18 @@ namespace WixToolset
9510 } 9462 }
9511 if (null == description) 9463 if (null == description)
9512 { 9464 {
9513 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description")); 9465 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description"));
9514 } 9466 }
9515 if (null == displayName) 9467 if (null == displayName)
9516 { 9468 {
9517 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayName")); 9469 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayName"));
9518 } 9470 }
9519 if (null == manufacturer) 9471 if (null == manufacturer)
9520 { 9472 {
9521 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer")); 9473 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer"));
9522 } 9474 }
9523 9475
9524 this.core.CreateActiveSection(this.activeName, SectionType.Patch, codepage); 9476 this.Core.CreateActiveSection(this.activeName, SectionType.Patch, codepage, this.Context.CompilationId);
9525 9477
9526 foreach (XElement child in node.Elements()) 9478 foreach (XElement child in node.Elements())
9527 { 9479 {
@@ -9557,118 +9509,118 @@ namespace WixToolset
9557 this.ParseTargetProductCodesElement(child); 9509 this.ParseTargetProductCodesElement(child);
9558 break; 9510 break;
9559 default: 9511 default:
9560 this.core.UnexpectedElement(node, child); 9512 this.Core.UnexpectedElement(node, child);
9561 break; 9513 break;
9562 } 9514 }
9563 } 9515 }
9564 else 9516 else
9565 { 9517 {
9566 this.core.ParseExtensionElement(node, child); 9518 this.Core.ParseExtensionElement(node, child);
9567 } 9519 }
9568 } 9520 }
9569 9521
9570 9522
9571 if (!this.core.EncounteredError) 9523 if (!this.Core.EncounteredError)
9572 { 9524 {
9573 Row patchIdRow = this.core.CreateRow(sourceLineNumbers, "WixPatchId"); 9525 var patchIdRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchId);
9574 patchIdRow[0] = patchId; 9526 patchIdRow.Set(0, patchId);
9575 patchIdRow[1] = clientPatchId; 9527 patchIdRow.Set(1, clientPatchId);
9576 patchIdRow[2] = optimizePatchSizeForLargeFiles ? 1 : 0; 9528 patchIdRow.Set(2, optimizePatchSizeForLargeFiles ? 1 : 0);
9577 patchIdRow[3] = apiPatchingSymbolFlags; 9529 patchIdRow.Set(3, apiPatchingSymbolFlags);
9578 9530
9579 if (allowRemoval) 9531 if (allowRemoval)
9580 { 9532 {
9581 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9533 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9582 row[0] = null; 9534 row.Set(0, null);
9583 row[1] = "AllowRemoval"; 9535 row.Set(1, "AllowRemoval");
9584 row[2] = allowRemoval ? "1" : "0"; 9536 row.Set(2, allowRemoval ? "1" : "0");
9585 } 9537 }
9586 9538
9587 if (null != classification) 9539 if (null != classification)
9588 { 9540 {
9589 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9541 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9590 row[0] = null; 9542 row.Set(0, null);
9591 row[1] = "Classification"; 9543 row.Set(1, "Classification");
9592 row[2] = classification; 9544 row.Set(2, classification);
9593 } 9545 }
9594 9546
9595 // always generate the CreationTimeUTC 9547 // always generate the CreationTimeUTC
9596 { 9548 {
9597 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9549 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9598 row[0] = null; 9550 row.Set(0, null);
9599 row[1] = "CreationTimeUTC"; 9551 row.Set(1, "CreationTimeUTC");
9600 row[2] = DateTime.UtcNow.ToString("MM-dd-yy HH:mm", CultureInfo.InvariantCulture); 9552 row.Set(2, DateTime.UtcNow.ToString("MM-dd-yy HH:mm", CultureInfo.InvariantCulture));
9601 } 9553 }
9602 9554
9603 if (null != description) 9555 if (null != description)
9604 { 9556 {
9605 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9557 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9606 row[0] = null; 9558 row.Set(0, null);
9607 row[1] = "Description"; 9559 row.Set(1, "Description");
9608 row[2] = description; 9560 row.Set(2, description);
9609 } 9561 }
9610 9562
9611 if (null != displayName) 9563 if (null != displayName)
9612 { 9564 {
9613 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9565 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9614 row[0] = null; 9566 row.Set(0, null);
9615 row[1] = "DisplayName"; 9567 row.Set(1, "DisplayName");
9616 row[2] = displayName; 9568 row.Set(2, displayName);
9617 } 9569 }
9618 9570
9619 if (null != manufacturer) 9571 if (null != manufacturer)
9620 { 9572 {
9621 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9573 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9622 row[0] = null; 9574 row.Set(0, null);
9623 row[1] = "ManufacturerName"; 9575 row.Set(1, "ManufacturerName");
9624 row[2] = manufacturer; 9576 row.Set(2, manufacturer);
9625 } 9577 }
9626 9578
9627 if (YesNoType.NotSet != minorUpdateTargetRTM) 9579 if (YesNoType.NotSet != minorUpdateTargetRTM)
9628 { 9580 {
9629 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9581 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9630 row[0] = null; 9582 row.Set(0, null);
9631 row[1] = "MinorUpdateTargetRTM"; 9583 row.Set(1, "MinorUpdateTargetRTM");
9632 row[2] = YesNoType.Yes == minorUpdateTargetRTM ? "1" : "0"; 9584 row.Set(2, YesNoType.Yes == minorUpdateTargetRTM ? "1" : "0");
9633 } 9585 }
9634 9586
9635 if (null != moreInfoUrl) 9587 if (null != moreInfoUrl)
9636 { 9588 {
9637 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9589 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9638 row[0] = null; 9590 row.Set(0, null);
9639 row[1] = "MoreInfoURL"; 9591 row.Set(1, "MoreInfoURL");
9640 row[2] = moreInfoUrl; 9592 row.Set(2, moreInfoUrl);
9641 } 9593 }
9642 9594
9643 if (CompilerConstants.IntegerNotSet != optimizeCA) 9595 if (CompilerConstants.IntegerNotSet != optimizeCA)
9644 { 9596 {
9645 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9597 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9646 row[0] = null; 9598 row.Set(0, null);
9647 row[1] = "OptimizeCA"; 9599 row.Set(1, "OptimizeCA");
9648 row[2] = optimizeCA.ToString(CultureInfo.InvariantCulture); 9600 row.Set(2, optimizeCA.ToString(CultureInfo.InvariantCulture));
9649 } 9601 }
9650 9602
9651 if (YesNoType.NotSet != optimizedInstallMode) 9603 if (YesNoType.NotSet != optimizedInstallMode)
9652 { 9604 {
9653 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9605 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9654 row[0] = null; 9606 row.Set(0, null);
9655 row[1] = "OptimizedInstallMode"; 9607 row.Set(1, "OptimizedInstallMode");
9656 row[2] = YesNoType.Yes == optimizedInstallMode ? "1" : "0"; 9608 row.Set(2, YesNoType.Yes == optimizedInstallMode ? "1" : "0");
9657 } 9609 }
9658 9610
9659 if (null != targetProductName) 9611 if (null != targetProductName)
9660 { 9612 {
9661 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchMetadata"); 9613 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9662 row[0] = null; 9614 row.Set(0, null);
9663 row[1] = "TargetProductName"; 9615 row.Set(1, "TargetProductName");
9664 row[2] = targetProductName; 9616 row.Set(2, targetProductName);
9665 } 9617 }
9666 9618
9667 if (null != comments) 9619 if (null != comments)
9668 { 9620 {
9669 Row row = this.core.CreateRow(sourceLineNumbers, "WixPatchMetadata"); 9621 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchMetadata);
9670 row[0] = "Comments"; 9622 row.Set(0, "Comments");
9671 row[1] = comments; 9623 row.Set(1, comments);
9672 } 9624 }
9673 } 9625 }
9674 // TODO: do something with versionMismatches and productMismatches 9626 // TODO: do something with versionMismatches and productMismatches
@@ -9693,44 +9645,44 @@ namespace WixToolset
9693 switch (attrib.Name.LocalName) 9645 switch (attrib.Name.LocalName)
9694 { 9646 {
9695 case "Id": 9647 case "Id":
9696 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 9648 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
9697 break; 9649 break;
9698 case "ProductCode": 9650 case "ProductCode":
9699 productCode = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 9651 productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
9700 break; 9652 break;
9701 case "Version": 9653 case "Version":
9702 version = this.core.GetAttributeVersionValue(sourceLineNumbers, attrib); 9654 version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
9703 break; 9655 break;
9704 case "Supersede": 9656 case "Supersede":
9705 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 9657 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
9706 { 9658 {
9707 attributes |= 0x1; 9659 attributes |= 0x1;
9708 } 9660 }
9709 break; 9661 break;
9710 default: 9662 default:
9711 this.core.UnexpectedAttribute(node, attrib); 9663 this.Core.UnexpectedAttribute(node, attrib);
9712 break; 9664 break;
9713 } 9665 }
9714 } 9666 }
9715 else 9667 else
9716 { 9668 {
9717 this.core.ParseExtensionAttribute(node, attrib); 9669 this.Core.ParseExtensionAttribute(node, attrib);
9718 } 9670 }
9719 } 9671 }
9720 9672
9721 if (null == id) 9673 if (null == id)
9722 { 9674 {
9723 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 9675 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
9724 id = Identifier.Invalid; 9676 id = Identifier.Invalid;
9725 } 9677 }
9726 9678
9727 if (String.IsNullOrEmpty(version)) 9679 if (String.IsNullOrEmpty(version))
9728 { 9680 {
9729 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version")); 9681 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
9730 } 9682 }
9731 else if (!CompilerCore.IsValidProductVersion(version)) 9683 else if (!CompilerCore.IsValidProductVersion(version))
9732 { 9684 {
9733 this.core.OnMessage(WixErrors.InvalidProductVersion(sourceLineNumbers, version)); 9685 this.Core.OnMessage(WixErrors.InvalidProductVersion(sourceLineNumbers, version));
9734 } 9686 }
9735 9687
9736 // find unexpected child elements 9688 // find unexpected child elements
@@ -9771,27 +9723,27 @@ namespace WixToolset
9771 this.ParsePatchChildRefElement(child, "WixUI"); 9723 this.ParsePatchChildRefElement(child, "WixUI");
9772 break; 9724 break;
9773 default: 9725 default:
9774 this.core.UnexpectedElement(node, child); 9726 this.Core.UnexpectedElement(node, child);
9775 break; 9727 break;
9776 } 9728 }
9777 } 9729 }
9778 else 9730 else
9779 { 9731 {
9780 this.core.ParseExtensionElement(node, child); 9732 this.Core.ParseExtensionElement(node, child);
9781 } 9733 }
9782 } 9734 }
9783 9735
9784 9736
9785 if (!this.core.EncounteredError) 9737 if (!this.Core.EncounteredError)
9786 { 9738 {
9787 Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchSequence", id); 9739 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchSequence, id);
9788 row[1] = productCode; 9740 row.Set(1, productCode);
9789 row[2] = version; 9741 row.Set(2, version);
9790 row[3] = attributes; 9742 row.Set(3, attributes);
9791 9743
9792 if (ComplexReferenceParentType.Unknown != parentType) 9744 if (ComplexReferenceParentType.Unknown != parentType)
9793 { 9745 {
9794 this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamily, id.Id, ComplexReferenceParentType.Patch == parentType); 9746 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamily, id.Id, ComplexReferenceParentType.Patch == parentType);
9795 } 9747 }
9796 } 9748 }
9797 } 9749 }
@@ -9809,22 +9761,22 @@ namespace WixToolset
9809 { 9761 {
9810 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) 9762 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
9811 { 9763 {
9812 this.core.UnexpectedAttribute(node, attrib); 9764 this.Core.UnexpectedAttribute(node, attrib);
9813 } 9765 }
9814 else 9766 else
9815 { 9767 {
9816 this.core.ParseExtensionAttribute(node, attrib); 9768 this.Core.ParseExtensionAttribute(node, attrib);
9817 } 9769 }
9818 } 9770 }
9819 9771
9820 this.core.ParseForExtensionElements(node); 9772 this.Core.ParseForExtensionElements(node);
9821 9773
9822 // Always warn when using the All element. 9774 // Always warn when using the All element.
9823 this.core.OnMessage(WixWarnings.AllChangesIncludedInPatch(sourceLineNumbers)); 9775 this.Core.OnMessage(WixWarnings.AllChangesIncludedInPatch(sourceLineNumbers));
9824 9776
9825 if (!this.core.EncounteredError) 9777 if (!this.Core.EncounteredError)
9826 { 9778 {
9827 this.core.CreatePatchFamilyChildReference(sourceLineNumbers, "*", "*"); 9779 this.Core.CreatePatchFamilyChildReference(sourceLineNumbers, "*", "*");
9828 } 9780 }
9829 } 9781 }
9830 9782
@@ -9845,29 +9797,29 @@ namespace WixToolset
9845 switch (attrib.Name.LocalName) 9797 switch (attrib.Name.LocalName)
9846 { 9798 {
9847 case "Id": 9799 case "Id":
9848 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 9800 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
9849 break; 9801 break;
9850 default: 9802 default:
9851 this.core.UnexpectedAttribute(node, attrib); 9803 this.Core.UnexpectedAttribute(node, attrib);
9852 break; 9804 break;
9853 } 9805 }
9854 } 9806 }
9855 else 9807 else
9856 { 9808 {
9857 this.core.ParseExtensionAttribute(node, attrib); 9809 this.Core.ParseExtensionAttribute(node, attrib);
9858 } 9810 }
9859 } 9811 }
9860 9812
9861 if (null == id) 9813 if (null == id)
9862 { 9814 {
9863 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 9815 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
9864 } 9816 }
9865 9817
9866 this.core.ParseForExtensionElements(node); 9818 this.Core.ParseForExtensionElements(node);
9867 9819
9868 if (!this.core.EncounteredError) 9820 if (!this.Core.EncounteredError)
9869 { 9821 {
9870 this.core.CreatePatchFamilyChildReference(sourceLineNumbers, tableName, id); 9822 this.Core.CreatePatchFamilyChildReference(sourceLineNumbers, tableName, id);
9871 } 9823 }
9872 } 9824 }
9873 9825
@@ -9890,27 +9842,27 @@ namespace WixToolset
9890 switch (attrib.Name.LocalName) 9842 switch (attrib.Name.LocalName)
9891 { 9843 {
9892 case "Id": 9844 case "Id":
9893 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 9845 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
9894 break; 9846 break;
9895 default: 9847 default:
9896 this.core.UnexpectedAttribute(node, attrib); 9848 this.Core.UnexpectedAttribute(node, attrib);
9897 break; 9849 break;
9898 } 9850 }
9899 } 9851 }
9900 else 9852 else
9901 { 9853 {
9902 this.core.ParseExtensionAttribute(node, attrib); 9854 this.Core.ParseExtensionAttribute(node, attrib);
9903 } 9855 }
9904 } 9856 }
9905 9857
9906 if (null == id) 9858 if (null == id)
9907 { 9859 {
9908 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 9860 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
9909 id = Identifier.Invalid; 9861 id = Identifier.Invalid;
9910 } 9862 }
9911 else if (27 < id.Id.Length) 9863 else if (27 < id.Id.Length)
9912 { 9864 {
9913 this.core.OnMessage(WixErrors.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, 27)); 9865 this.Core.OnMessage(WixErrors.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Id", id.Id, 27));
9914 } 9866 }
9915 9867
9916 foreach (XElement child in node.Elements()) 9868 foreach (XElement child in node.Elements())
@@ -9923,7 +9875,7 @@ namespace WixToolset
9923 if (parsedValidate) 9875 if (parsedValidate)
9924 { 9876 {
9925 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); 9877 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
9926 this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName)); 9878 this.Core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName));
9927 } 9879 }
9928 else 9880 else
9929 { 9881 {
@@ -9932,21 +9884,21 @@ namespace WixToolset
9932 } 9884 }
9933 break; 9885 break;
9934 default: 9886 default:
9935 this.core.UnexpectedElement(node, child); 9887 this.Core.UnexpectedElement(node, child);
9936 break; 9888 break;
9937 } 9889 }
9938 } 9890 }
9939 else 9891 else
9940 { 9892 {
9941 this.core.ParseExtensionElement(node, child); 9893 this.Core.ParseExtensionElement(node, child);
9942 } 9894 }
9943 } 9895 }
9944 9896
9945 if (!this.core.EncounteredError) 9897 if (!this.Core.EncounteredError)
9946 { 9898 {
9947 Row row = this.core.CreateRow(sourceLineNumbers, "WixPatchBaseline", id); 9899 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchBaseline, id);
9948 row[1] = diskId; 9900 row.Set(1, diskId);
9949 row[2] = (int)validationFlags; 9901 row.Set(2, (int)validationFlags);
9950 } 9902 }
9951 } 9903 }
9952 9904
@@ -9966,7 +9918,7 @@ namespace WixToolset
9966 switch (attrib.Name.LocalName) 9918 switch (attrib.Name.LocalName)
9967 { 9919 {
9968 case "ProductId": 9920 case "ProductId":
9969 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 9921 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
9970 { 9922 {
9971 validationFlags |= TransformFlags.ValidateProduct; 9923 validationFlags |= TransformFlags.ValidateProduct;
9972 } 9924 }
@@ -9976,7 +9928,7 @@ namespace WixToolset
9976 } 9928 }
9977 break; 9929 break;
9978 case "ProductLanguage": 9930 case "ProductLanguage":
9979 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 9931 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
9980 { 9932 {
9981 validationFlags |= TransformFlags.ValidateLanguage; 9933 validationFlags |= TransformFlags.ValidateLanguage;
9982 } 9934 }
@@ -9986,7 +9938,7 @@ namespace WixToolset
9986 } 9938 }
9987 break; 9939 break;
9988 case "ProductVersion": 9940 case "ProductVersion":
9989 string check = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9941 string check = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9990 validationFlags &= ~TransformFlags.ProductVersionMask; 9942 validationFlags &= ~TransformFlags.ProductVersionMask;
9991 Wix.Validate.ProductVersionType productVersionType = Wix.Validate.ParseProductVersionType(check); 9943 Wix.Validate.ProductVersionType productVersionType = Wix.Validate.ParseProductVersionType(check);
9992 switch (productVersionType) 9944 switch (productVersionType)
@@ -10001,12 +9953,12 @@ namespace WixToolset
10001 validationFlags |= TransformFlags.ValidateUpdateVersion; 9953 validationFlags |= TransformFlags.ValidateUpdateVersion;
10002 break; 9954 break;
10003 default: 9955 default:
10004 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Version", check, "Major", "Minor", "Update")); 9956 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Version", check, "Major", "Minor", "Update"));
10005 break; 9957 break;
10006 } 9958 }
10007 break; 9959 break;
10008 case "ProductVersionOperator": 9960 case "ProductVersionOperator":
10009 string op = this.core.GetAttributeValue(sourceLineNumbers, attrib); 9961 string op = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10010 validationFlags &= ~TransformFlags.ProductVersionOperatorMask; 9962 validationFlags &= ~TransformFlags.ProductVersionOperatorMask;
10011 Wix.Validate.ProductVersionOperatorType opType = Wix.Validate.ParseProductVersionOperatorType(op); 9963 Wix.Validate.ProductVersionOperatorType opType = Wix.Validate.ParseProductVersionOperatorType(op);
10012 switch (opType) 9964 switch (opType)
@@ -10027,12 +9979,12 @@ namespace WixToolset
10027 validationFlags |= TransformFlags.ValidateNewGreaterBaseVersion; 9979 validationFlags |= TransformFlags.ValidateNewGreaterBaseVersion;
10028 break; 9980 break;
10029 default: 9981 default:
10030 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Operator", op, "Lesser", "LesserOrEqual", "Equal", "GreaterOrEqual", "Greater")); 9982 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Operator", op, "Lesser", "LesserOrEqual", "Equal", "GreaterOrEqual", "Greater"));
10031 break; 9983 break;
10032 } 9984 }
10033 break; 9985 break;
10034 case "UpgradeCode": 9986 case "UpgradeCode":
10035 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 9987 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10036 { 9988 {
10037 validationFlags |= TransformFlags.ValidateUpgradeCode; 9989 validationFlags |= TransformFlags.ValidateUpgradeCode;
10038 } 9990 }
@@ -10042,7 +9994,7 @@ namespace WixToolset
10042 } 9994 }
10043 break; 9995 break;
10044 case "IgnoreAddExistingRow": 9996 case "IgnoreAddExistingRow":
10045 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 9997 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10046 { 9998 {
10047 validationFlags |= TransformFlags.ErrorAddExistingRow; 9999 validationFlags |= TransformFlags.ErrorAddExistingRow;
10048 } 10000 }
@@ -10052,7 +10004,7 @@ namespace WixToolset
10052 } 10004 }
10053 break; 10005 break;
10054 case "IgnoreAddExistingTable": 10006 case "IgnoreAddExistingTable":
10055 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 10007 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10056 { 10008 {
10057 validationFlags |= TransformFlags.ErrorAddExistingTable; 10009 validationFlags |= TransformFlags.ErrorAddExistingTable;
10058 } 10010 }
@@ -10062,7 +10014,7 @@ namespace WixToolset
10062 } 10014 }
10063 break; 10015 break;
10064 case "IgnoreDeleteMissingRow": 10016 case "IgnoreDeleteMissingRow":
10065 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 10017 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10066 { 10018 {
10067 validationFlags |= TransformFlags.ErrorDeleteMissingRow; 10019 validationFlags |= TransformFlags.ErrorDeleteMissingRow;
10068 } 10020 }
@@ -10072,7 +10024,7 @@ namespace WixToolset
10072 } 10024 }
10073 break; 10025 break;
10074 case "IgnoreDeleteMissingTable": 10026 case "IgnoreDeleteMissingTable":
10075 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 10027 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10076 { 10028 {
10077 validationFlags |= TransformFlags.ErrorDeleteMissingTable; 10029 validationFlags |= TransformFlags.ErrorDeleteMissingTable;
10078 } 10030 }
@@ -10082,7 +10034,7 @@ namespace WixToolset
10082 } 10034 }
10083 break; 10035 break;
10084 case "IgnoreUpdateMissingRow": 10036 case "IgnoreUpdateMissingRow":
10085 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 10037 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10086 { 10038 {
10087 validationFlags |= TransformFlags.ErrorUpdateMissingRow; 10039 validationFlags |= TransformFlags.ErrorUpdateMissingRow;
10088 } 10040 }
@@ -10092,7 +10044,7 @@ namespace WixToolset
10092 } 10044 }
10093 break; 10045 break;
10094 case "IgnoreChangingCodePage": 10046 case "IgnoreChangingCodePage":
10095 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 10047 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10096 { 10048 {
10097 validationFlags |= TransformFlags.ErrorChangeCodePage; 10049 validationFlags |= TransformFlags.ErrorChangeCodePage;
10098 } 10050 }
@@ -10102,13 +10054,13 @@ namespace WixToolset
10102 } 10054 }
10103 break; 10055 break;
10104 default: 10056 default:
10105 this.core.UnexpectedAttribute(node, attrib); 10057 this.Core.UnexpectedAttribute(node, attrib);
10106 break; 10058 break;
10107 } 10059 }
10108 } 10060 }
10109 else 10061 else
10110 { 10062 {
10111 this.core.ParseExtensionAttribute(node, attrib); 10063 this.Core.ParseExtensionAttribute(node, attrib);
10112 } 10064 }
10113 } 10065 }
10114 10066
@@ -10122,11 +10074,11 @@ namespace WixToolset
10122 /// <param name="value">Value of the property.</param> 10074 /// <param name="value">Value of the property.</param>
10123 private void ProcessProperties(SourceLineNumber sourceLineNumbers, string name, string value) 10075 private void ProcessProperties(SourceLineNumber sourceLineNumbers, string name, string value)
10124 { 10076 {
10125 if (!this.core.EncounteredError) 10077 if (!this.Core.EncounteredError)
10126 { 10078 {
10127 Row row = this.core.CreateRow(sourceLineNumbers, "Properties"); 10079 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Properties);
10128 row[0] = name; 10080 row.Set(0, name);
10129 row[1] = value; 10081 row.Set(1, value);
10130 } 10082 }
10131 } 10083 }
10132 10084
@@ -10148,47 +10100,47 @@ namespace WixToolset
10148 switch (attrib.Name.LocalName) 10100 switch (attrib.Name.LocalName)
10149 { 10101 {
10150 case "RequiredId": 10102 case "RequiredId":
10151 requiredId = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 10103 requiredId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
10152 break; 10104 break;
10153 case "RequiredLanguage": 10105 case "RequiredLanguage":
10154 requiredLanguage = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 10106 requiredLanguage = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
10155 break; 10107 break;
10156 case "RequiredVersion": 10108 case "RequiredVersion":
10157 requiredVersion = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10109 requiredVersion = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10158 break; 10110 break;
10159 default: 10111 default:
10160 this.core.UnexpectedAttribute(node, attrib); 10112 this.Core.UnexpectedAttribute(node, attrib);
10161 break; 10113 break;
10162 } 10114 }
10163 } 10115 }
10164 else 10116 else
10165 { 10117 {
10166 this.core.ParseExtensionAttribute(node, attrib); 10118 this.Core.ParseExtensionAttribute(node, attrib);
10167 } 10119 }
10168 } 10120 }
10169 10121
10170 if (null == requiredId) 10122 if (null == requiredId)
10171 { 10123 {
10172 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "RequiredId")); 10124 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "RequiredId"));
10173 requiredId = String.Empty; 10125 requiredId = String.Empty;
10174 } 10126 }
10175 10127
10176 if (CompilerConstants.IntegerNotSet == requiredLanguage) 10128 if (CompilerConstants.IntegerNotSet == requiredLanguage)
10177 { 10129 {
10178 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "RequiredLanguage")); 10130 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "RequiredLanguage"));
10179 requiredLanguage = CompilerConstants.IllegalInteger; 10131 requiredLanguage = CompilerConstants.IllegalInteger;
10180 } 10132 }
10181 10133
10182 this.core.ParseForExtensionElements(node); 10134 this.Core.ParseForExtensionElements(node);
10183 10135
10184 if (!this.core.EncounteredError) 10136 if (!this.Core.EncounteredError)
10185 { 10137 {
10186 Row row = this.core.CreateRow(sourceLineNumbers, "ModuleDependency"); 10138 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ModuleDependency);
10187 row[0] = this.activeName; 10139 row.Set(0, this.activeName);
10188 row[1] = this.activeLanguage; 10140 row.Set(1, this.activeLanguage);
10189 row[2] = requiredId; 10141 row.Set(2, requiredId);
10190 row[3] = requiredLanguage.ToString(CultureInfo.InvariantCulture); 10142 row.Set(3, requiredLanguage.ToString(CultureInfo.InvariantCulture));
10191 row[4] = requiredVersion; 10143 row.Set(4, requiredVersion);
10192 } 10144 }
10193 } 10145 }
10194 10146
@@ -10213,40 +10165,40 @@ namespace WixToolset
10213 switch (attrib.Name.LocalName) 10165 switch (attrib.Name.LocalName)
10214 { 10166 {
10215 case "ExcludedId": 10167 case "ExcludedId":
10216 excludedId = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 10168 excludedId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
10217 break; 10169 break;
10218 case "ExcludeExceptLanguage": 10170 case "ExcludeExceptLanguage":
10219 excludeExceptLanguage = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 10171 excludeExceptLanguage = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
10220 break; 10172 break;
10221 case "ExcludeLanguage": 10173 case "ExcludeLanguage":
10222 excludeLanguage = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 10174 excludeLanguage = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
10223 break; 10175 break;
10224 case "ExcludedMaxVersion": 10176 case "ExcludedMaxVersion":
10225 excludedMaxVersion = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10177 excludedMaxVersion = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10226 break; 10178 break;
10227 case "ExcludedMinVersion": 10179 case "ExcludedMinVersion":
10228 excludedMinVersion = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10180 excludedMinVersion = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10229 break; 10181 break;
10230 default: 10182 default:
10231 this.core.UnexpectedAttribute(node, attrib); 10183 this.Core.UnexpectedAttribute(node, attrib);
10232 break; 10184 break;
10233 } 10185 }
10234 } 10186 }
10235 else 10187 else
10236 { 10188 {
10237 this.core.ParseExtensionAttribute(node, attrib); 10189 this.Core.ParseExtensionAttribute(node, attrib);
10238 } 10190 }
10239 } 10191 }
10240 10192
10241 if (null == excludedId) 10193 if (null == excludedId)
10242 { 10194 {
10243 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ExcludedId")); 10195 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ExcludedId"));
10244 excludedId = String.Empty; 10196 excludedId = String.Empty;
10245 } 10197 }
10246 10198
10247 if (CompilerConstants.IntegerNotSet != excludeExceptLanguage && CompilerConstants.IntegerNotSet != excludeLanguage) 10199 if (CompilerConstants.IntegerNotSet != excludeExceptLanguage && CompilerConstants.IntegerNotSet != excludeLanguage)
10248 { 10200 {
10249 this.core.OnMessage(WixErrors.IllegalModuleExclusionLanguageAttributes(sourceLineNumbers)); 10201 this.Core.OnMessage(WixErrors.IllegalModuleExclusionLanguageAttributes(sourceLineNumbers));
10250 } 10202 }
10251 else if (CompilerConstants.IntegerNotSet != excludeExceptLanguage) 10203 else if (CompilerConstants.IntegerNotSet != excludeExceptLanguage)
10252 { 10204 {
@@ -10257,17 +10209,17 @@ namespace WixToolset
10257 excludedLanguageField = Convert.ToString(excludeLanguage, CultureInfo.InvariantCulture); 10209 excludedLanguageField = Convert.ToString(excludeLanguage, CultureInfo.InvariantCulture);
10258 } 10210 }
10259 10211
10260 this.core.ParseForExtensionElements(node); 10212 this.Core.ParseForExtensionElements(node);
10261 10213
10262 if (!this.core.EncounteredError) 10214 if (!this.Core.EncounteredError)
10263 { 10215 {
10264 Row row = this.core.CreateRow(sourceLineNumbers, "ModuleExclusion"); 10216 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ModuleExclusion);
10265 row[0] = this.activeName; 10217 row.Set(0, this.activeName);
10266 row[1] = this.activeLanguage; 10218 row.Set(1, this.activeLanguage);
10267 row[2] = excludedId; 10219 row.Set(2, excludedId);
10268 row[3] = excludedLanguageField; 10220 row.Set(3, excludedLanguageField);
10269 row[4] = excludedMinVersion; 10221 row.Set(4, excludedMinVersion);
10270 row[5] = excludedMaxVersion; 10222 row.Set(5, excludedMaxVersion);
10271 } 10223 }
10272 } 10224 }
10273 10225
@@ -10296,22 +10248,22 @@ namespace WixToolset
10296 switch (attrib.Name.LocalName) 10248 switch (attrib.Name.LocalName)
10297 { 10249 {
10298 case "Name": 10250 case "Name":
10299 name = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 10251 name = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
10300 break; 10252 break;
10301 case "ContextData": 10253 case "ContextData":
10302 contextData = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10254 contextData = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10303 break; 10255 break;
10304 case "Description": 10256 case "Description":
10305 description = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10257 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10306 break; 10258 break;
10307 case "DefaultValue": 10259 case "DefaultValue":
10308 defaultValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10260 defaultValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10309 break; 10261 break;
10310 case "DisplayName": 10262 case "DisplayName":
10311 displayName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10263 displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10312 break; 10264 break;
10313 case "Format": 10265 case "Format":
10314 string formatStr = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10266 string formatStr = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10315 if (0 < formatStr.Length) 10267 if (0 < formatStr.Length)
10316 { 10268 {
10317 Wix.Configuration.FormatType formatType = Wix.Configuration.ParseFormatType(formatStr); 10269 Wix.Configuration.FormatType formatType = Wix.Configuration.ParseFormatType(formatStr);
@@ -10330,70 +10282,70 @@ namespace WixToolset
10330 format = 3; 10282 format = 3;
10331 break; 10283 break;
10332 default: 10284 default:
10333 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Format", formatStr, "Text", "Key", "Integer", "Bitfield")); 10285 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Format", formatStr, "Text", "Key", "Integer", "Bitfield"));
10334 break; 10286 break;
10335 } 10287 }
10336 } 10288 }
10337 break; 10289 break;
10338 case "HelpKeyword": 10290 case "HelpKeyword":
10339 helpKeyword = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10291 helpKeyword = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10340 break; 10292 break;
10341 case "HelpLocation": 10293 case "HelpLocation":
10342 helpLocation = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10294 helpLocation = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10343 break; 10295 break;
10344 case "KeyNoOrphan": 10296 case "KeyNoOrphan":
10345 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 10297 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10346 { 10298 {
10347 attributes |= MsiInterop.MsidbMsmConfigurableOptionKeyNoOrphan; 10299 attributes |= MsiInterop.MsidbMsmConfigurableOptionKeyNoOrphan;
10348 } 10300 }
10349 break; 10301 break;
10350 case "NonNullable": 10302 case "NonNullable":
10351 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 10303 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10352 { 10304 {
10353 attributes |= MsiInterop.MsidbMsmConfigurableOptionNonNullable; 10305 attributes |= MsiInterop.MsidbMsmConfigurableOptionNonNullable;
10354 } 10306 }
10355 break; 10307 break;
10356 case "Type": 10308 case "Type":
10357 type = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10309 type = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10358 break; 10310 break;
10359 default: 10311 default:
10360 this.core.UnexpectedAttribute(node, attrib); 10312 this.Core.UnexpectedAttribute(node, attrib);
10361 break; 10313 break;
10362 } 10314 }
10363 } 10315 }
10364 else 10316 else
10365 { 10317 {
10366 this.core.ParseExtensionAttribute(node, attrib); 10318 this.Core.ParseExtensionAttribute(node, attrib);
10367 } 10319 }
10368 } 10320 }
10369 10321
10370 if (null == name) 10322 if (null == name)
10371 { 10323 {
10372 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 10324 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
10373 name = String.Empty; 10325 name = String.Empty;
10374 } 10326 }
10375 10327
10376 if (CompilerConstants.IntegerNotSet == format) 10328 if (CompilerConstants.IntegerNotSet == format)
10377 { 10329 {
10378 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Format")); 10330 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Format"));
10379 format = CompilerConstants.IllegalInteger; 10331 format = CompilerConstants.IllegalInteger;
10380 } 10332 }
10381 10333
10382 this.core.ParseForExtensionElements(node); 10334 this.Core.ParseForExtensionElements(node);
10383 10335
10384 if (!this.core.EncounteredError) 10336 if (!this.Core.EncounteredError)
10385 { 10337 {
10386 Row row = this.core.CreateRow(sourceLineNumbers, "ModuleConfiguration"); 10338 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ModuleConfiguration);
10387 row[0] = name; 10339 row.Set(0, name);
10388 row[1] = format; 10340 row.Set(1, format);
10389 row[2] = type; 10341 row.Set(2, type);
10390 row[3] = contextData; 10342 row.Set(3, contextData);
10391 row[4] = defaultValue; 10343 row.Set(4, defaultValue);
10392 row[5] = attributes; 10344 row.Set(5, attributes);
10393 row[6] = displayName; 10345 row.Set(6, displayName);
10394 row[7] = description; 10346 row.Set(7, description);
10395 row[8] = helpLocation; 10347 row.Set(8, helpLocation);
10396 row[9] = helpKeyword; 10348 row.Set(9, helpKeyword);
10397 } 10349 }
10398 } 10350 }
10399 10351
@@ -10416,54 +10368,54 @@ namespace WixToolset
10416 switch (attrib.Name.LocalName) 10368 switch (attrib.Name.LocalName)
10417 { 10369 {
10418 case "Column": 10370 case "Column":
10419 column = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 10371 column = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
10420 break; 10372 break;
10421 case "Row": 10373 case "Row":
10422 rowKeys = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10374 rowKeys = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10423 break; 10375 break;
10424 case "Table": 10376 case "Table":
10425 table = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 10377 table = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
10426 break; 10378 break;
10427 case "Value": 10379 case "Value":
10428 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10380 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10429 break; 10381 break;
10430 default: 10382 default:
10431 this.core.UnexpectedAttribute(node, attrib); 10383 this.Core.UnexpectedAttribute(node, attrib);
10432 break; 10384 break;
10433 } 10385 }
10434 } 10386 }
10435 else 10387 else
10436 { 10388 {
10437 this.core.ParseExtensionAttribute(node, attrib); 10389 this.Core.ParseExtensionAttribute(node, attrib);
10438 } 10390 }
10439 } 10391 }
10440 10392
10441 if (null == column) 10393 if (null == column)
10442 { 10394 {
10443 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Column")); 10395 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Column"));
10444 column = String.Empty; 10396 column = String.Empty;
10445 } 10397 }
10446 10398
10447 if (null == table) 10399 if (null == table)
10448 { 10400 {
10449 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Table")); 10401 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Table"));
10450 table = String.Empty; 10402 table = String.Empty;
10451 } 10403 }
10452 10404
10453 if (null == rowKeys) 10405 if (null == rowKeys)
10454 { 10406 {
10455 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Row")); 10407 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Row"));
10456 } 10408 }
10457 10409
10458 this.core.ParseForExtensionElements(node); 10410 this.Core.ParseForExtensionElements(node);
10459 10411
10460 if (!this.core.EncounteredError) 10412 if (!this.Core.EncounteredError)
10461 { 10413 {
10462 Row row = this.core.CreateRow(sourceLineNumbers, "ModuleSubstitution"); 10414 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ModuleSubstitution);
10463 row[0] = table; 10415 row.Set(0, table);
10464 row[1] = rowKeys; 10416 row.Set(1, rowKeys);
10465 row[2] = column; 10417 row.Set(2, column);
10466 row[3] = value; 10418 row.Set(3, value);
10467 } 10419 }
10468 } 10420 }
10469 10421
@@ -10483,30 +10435,30 @@ namespace WixToolset
10483 switch (attrib.Name.LocalName) 10435 switch (attrib.Name.LocalName)
10484 { 10436 {
10485 case "Id": 10437 case "Id":
10486 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 10438 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
10487 break; 10439 break;
10488 default: 10440 default:
10489 this.core.UnexpectedAttribute(node, attrib); 10441 this.Core.UnexpectedAttribute(node, attrib);
10490 break; 10442 break;
10491 } 10443 }
10492 } 10444 }
10493 else 10445 else
10494 { 10446 {
10495 this.core.ParseExtensionAttribute(node, attrib); 10447 this.Core.ParseExtensionAttribute(node, attrib);
10496 } 10448 }
10497 } 10449 }
10498 10450
10499 if (null == id) 10451 if (null == id)
10500 { 10452 {
10501 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 10453 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
10502 } 10454 }
10503 10455
10504 this.core.ParseForExtensionElements(node); 10456 this.Core.ParseForExtensionElements(node);
10505 10457
10506 if (!this.core.EncounteredError) 10458 if (!this.Core.EncounteredError)
10507 { 10459 {
10508 Row row = this.core.CreateRow(sourceLineNumbers, "ModuleIgnoreTable"); 10460 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ModuleIgnoreTable);
10509 row[0] = id; 10461 row.Set(0, id);
10510 } 10462 }
10511 } 10463 }
10512 10464
@@ -10517,7 +10469,7 @@ namespace WixToolset
10517 /// <param name="componentId">Identifier of parent component.</param> 10469 /// <param name="componentId">Identifier of parent component.</param>
10518 /// <param name="fileId">Default identifer for driver/translator file.</param> 10470 /// <param name="fileId">Default identifer for driver/translator file.</param>
10519 /// <param name="table">Table we're processing for.</param> 10471 /// <param name="table">Table we're processing for.</param>
10520 private void ParseODBCDriverOrTranslator(XElement node, string componentId, string fileId, TableDefinition table) 10472 private void ParseODBCDriverOrTranslator(XElement node, string componentId, string fileId, TupleDefinitionType tableName)
10521 { 10473 {
10522 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 10474 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
10523 Identifier id = null; 10475 Identifier id = null;
@@ -10532,42 +10484,42 @@ namespace WixToolset
10532 switch (attrib.Name.LocalName) 10484 switch (attrib.Name.LocalName)
10533 { 10485 {
10534 case "Id": 10486 case "Id":
10535 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 10487 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
10536 break; 10488 break;
10537 case "File": 10489 case "File":
10538 driver = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 10490 driver = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
10539 this.core.CreateSimpleReference(sourceLineNumbers, "File", driver); 10491 this.Core.CreateSimpleReference(sourceLineNumbers, "File", driver);
10540 break; 10492 break;
10541 case "Name": 10493 case "Name":
10542 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10494 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10543 break; 10495 break;
10544 case "SetupFile": 10496 case "SetupFile":
10545 setup = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 10497 setup = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
10546 this.core.CreateSimpleReference(sourceLineNumbers, "File", setup); 10498 this.Core.CreateSimpleReference(sourceLineNumbers, "File", setup);
10547 break; 10499 break;
10548 default: 10500 default:
10549 this.core.UnexpectedAttribute(node, attrib); 10501 this.Core.UnexpectedAttribute(node, attrib);
10550 break; 10502 break;
10551 } 10503 }
10552 } 10504 }
10553 else 10505 else
10554 { 10506 {
10555 this.core.ParseExtensionAttribute(node, attrib); 10507 this.Core.ParseExtensionAttribute(node, attrib);
10556 } 10508 }
10557 } 10509 }
10558 10510
10559 if (null == name) 10511 if (null == name)
10560 { 10512 {
10561 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 10513 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
10562 } 10514 }
10563 10515
10564 if (null == id) 10516 if (null == id)
10565 { 10517 {
10566 id = this.core.CreateIdentifier("odb", name, fileId, setup); 10518 id = this.Core.CreateIdentifier("odb", name, fileId, setup);
10567 } 10519 }
10568 10520
10569 // drivers have a few possible children 10521 // drivers have a few possible children
10570 if ("ODBCDriver" == table.Name) 10522 if (TupleDefinitionType.ODBCDriver == tableName)
10571 { 10523 {
10572 // process any data sources for the driver 10524 // process any data sources for the driver
10573 foreach (XElement child in node.Elements()) 10525 foreach (XElement child in node.Elements())
@@ -10581,31 +10533,31 @@ namespace WixToolset
10581 this.ParseODBCDataSource(child, componentId, name, out ignoredKeyPath); 10533 this.ParseODBCDataSource(child, componentId, name, out ignoredKeyPath);
10582 break; 10534 break;
10583 case "Property": 10535 case "Property":
10584 this.ParseODBCProperty(child, id.Id, "ODBCAttribute"); 10536 this.ParseODBCProperty(child, id.Id, TupleDefinitionType.ODBCAttribute);
10585 break; 10537 break;
10586 default: 10538 default:
10587 this.core.UnexpectedElement(node, child); 10539 this.Core.UnexpectedElement(node, child);
10588 break; 10540 break;
10589 } 10541 }
10590 } 10542 }
10591 else 10543 else
10592 { 10544 {
10593 this.core.ParseExtensionElement(node, child); 10545 this.Core.ParseExtensionElement(node, child);
10594 } 10546 }
10595 } 10547 }
10596 } 10548 }
10597 else 10549 else
10598 { 10550 {
10599 this.core.ParseForExtensionElements(node); 10551 this.Core.ParseForExtensionElements(node);
10600 } 10552 }
10601 10553
10602 if (!this.core.EncounteredError) 10554 if (!this.Core.EncounteredError)
10603 { 10555 {
10604 Row row = this.core.CreateRow(sourceLineNumbers, table.Name, id); 10556 var row = this.Core.CreateRow(sourceLineNumbers, tableName, id);
10605 row[1] = componentId; 10557 row.Set(1, componentId);
10606 row[2] = name; 10558 row.Set(2, name);
10607 row[3] = driver; 10559 row.Set(3, driver);
10608 row[4] = setup; 10560 row.Set(4, setup);
10609 } 10561 }
10610 } 10562 }
10611 10563
@@ -10615,7 +10567,7 @@ namespace WixToolset
10615 /// <param name="node">Element to parse.</param> 10567 /// <param name="node">Element to parse.</param>
10616 /// <param name="parentId">Identifier of parent driver or translator.</param> 10568 /// <param name="parentId">Identifier of parent driver or translator.</param>
10617 /// <param name="tableName">Name of the table to create property in.</param> 10569 /// <param name="tableName">Name of the table to create property in.</param>
10618 private void ParseODBCProperty(XElement node, string parentId, string tableName) 10570 private void ParseODBCProperty(XElement node, string parentId, TupleDefinitionType tableName)
10619 { 10571 {
10620 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 10572 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
10621 string id = null; 10573 string id = null;
@@ -10628,35 +10580,35 @@ namespace WixToolset
10628 switch (attrib.Name.LocalName) 10580 switch (attrib.Name.LocalName)
10629 { 10581 {
10630 case "Id": 10582 case "Id":
10631 id = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10583 id = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10632 break; 10584 break;
10633 case "Value": 10585 case "Value":
10634 propertyValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10586 propertyValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10635 break; 10587 break;
10636 default: 10588 default:
10637 this.core.UnexpectedAttribute(node, attrib); 10589 this.Core.UnexpectedAttribute(node, attrib);
10638 break; 10590 break;
10639 } 10591 }
10640 } 10592 }
10641 else 10593 else
10642 { 10594 {
10643 this.core.ParseExtensionAttribute(node, attrib); 10595 this.Core.ParseExtensionAttribute(node, attrib);
10644 } 10596 }
10645 } 10597 }
10646 10598
10647 if (null == id) 10599 if (null == id)
10648 { 10600 {
10649 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 10601 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
10650 } 10602 }
10651 10603
10652 this.core.ParseForExtensionElements(node); 10604 this.Core.ParseForExtensionElements(node);
10653 10605
10654 if (!this.core.EncounteredError) 10606 if (!this.Core.EncounteredError)
10655 { 10607 {
10656 Row row = this.core.CreateRow(sourceLineNumbers, tableName); 10608 var row = this.Core.CreateRow(sourceLineNumbers, tableName);
10657 row[0] = parentId; 10609 row.Set(0, parentId);
10658 row[1] = id; 10610 row.Set(1, id);
10659 row[2] = propertyValue; 10611 row.Set(2, propertyValue);
10660 } 10612 }
10661 } 10613 }
10662 10614
@@ -10683,19 +10635,19 @@ namespace WixToolset
10683 switch (attrib.Name.LocalName) 10635 switch (attrib.Name.LocalName)
10684 { 10636 {
10685 case "Id": 10637 case "Id":
10686 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 10638 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
10687 break; 10639 break;
10688 case "DriverName": 10640 case "DriverName":
10689 driverName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10641 driverName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10690 break; 10642 break;
10691 case "KeyPath": 10643 case "KeyPath":
10692 keyPath = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 10644 keyPath = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
10693 break; 10645 break;
10694 case "Name": 10646 case "Name":
10695 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10647 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10696 break; 10648 break;
10697 case "Registration": 10649 case "Registration":
10698 string registrationValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10650 string registrationValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10699 if (0 < registrationValue.Length) 10651 if (0 < registrationValue.Length)
10700 { 10652 {
10701 Wix.ODBCDataSource.RegistrationType registrationType = Wix.ODBCDataSource.ParseRegistrationType(registrationValue); 10653 Wix.ODBCDataSource.RegistrationType registrationType = Wix.ODBCDataSource.ParseRegistrationType(registrationValue);
@@ -10708,31 +10660,31 @@ namespace WixToolset
10708 registration = 1; 10660 registration = 1;
10709 break; 10661 break;
10710 default: 10662 default:
10711 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Registration", registrationValue, "machine", "user")); 10663 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Registration", registrationValue, "machine", "user"));
10712 break; 10664 break;
10713 } 10665 }
10714 } 10666 }
10715 break; 10667 break;
10716 default: 10668 default:
10717 this.core.UnexpectedAttribute(node, attrib); 10669 this.Core.UnexpectedAttribute(node, attrib);
10718 break; 10670 break;
10719 } 10671 }
10720 } 10672 }
10721 else 10673 else
10722 { 10674 {
10723 this.core.ParseExtensionAttribute(node, attrib); 10675 this.Core.ParseExtensionAttribute(node, attrib);
10724 } 10676 }
10725 } 10677 }
10726 10678
10727 if (CompilerConstants.IntegerNotSet == registration) 10679 if (CompilerConstants.IntegerNotSet == registration)
10728 { 10680 {
10729 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Registration")); 10681 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Registration"));
10730 registration = CompilerConstants.IllegalInteger; 10682 registration = CompilerConstants.IllegalInteger;
10731 } 10683 }
10732 10684
10733 if (null == id) 10685 if (null == id)
10734 { 10686 {
10735 id = this.core.CreateIdentifier("odc", name, driverName, registration.ToString()); 10687 id = this.Core.CreateIdentifier("odc", name, driverName, registration.ToString());
10736 } 10688 }
10737 10689
10738 foreach (XElement child in node.Elements()) 10690 foreach (XElement child in node.Elements())
@@ -10742,26 +10694,26 @@ namespace WixToolset
10742 switch (child.Name.LocalName) 10694 switch (child.Name.LocalName)
10743 { 10695 {
10744 case "Property": 10696 case "Property":
10745 this.ParseODBCProperty(child, id.Id, "ODBCSourceAttribute"); 10697 this.ParseODBCProperty(child, id.Id, TupleDefinitionType.ODBCSourceAttribute);
10746 break; 10698 break;
10747 default: 10699 default:
10748 this.core.UnexpectedElement(node, child); 10700 this.Core.UnexpectedElement(node, child);
10749 break; 10701 break;
10750 } 10702 }
10751 } 10703 }
10752 else 10704 else
10753 { 10705 {
10754 this.core.ParseExtensionElement(node, child); 10706 this.Core.ParseExtensionElement(node, child);
10755 } 10707 }
10756 } 10708 }
10757 10709
10758 if (!this.core.EncounteredError) 10710 if (!this.Core.EncounteredError)
10759 { 10711 {
10760 Row row = this.core.CreateRow(sourceLineNumbers, "ODBCDataSource", id); 10712 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ODBCDataSource, id);
10761 row[1] = componentId; 10713 row.Set(1, componentId);
10762 row[2] = name; 10714 row.Set(2, name);
10763 row[3] = driverName; 10715 row.Set(3, driverName);
10764 row[4] = registration; 10716 row.Set(4, registration);
10765 } 10717 }
10766 10718
10767 possibleKeyPath = id.Id; 10719 possibleKeyPath = id.Id;
@@ -10789,7 +10741,7 @@ namespace WixToolset
10789 string platformValue = null; 10741 string platformValue = null;
10790 YesNoDefaultType security = YesNoDefaultType.Default; 10742 YesNoDefaultType security = YesNoDefaultType.Default;
10791 int sourceBits = (this.compilingModule ? 2 : 0); 10743 int sourceBits = (this.compilingModule ? 2 : 0);
10792 Row row; 10744 IntermediateTuple row;
10793 bool installPrivilegeSeen = false; 10745 bool installPrivilegeSeen = false;
10794 bool installScopeSeen = false; 10746 bool installScopeSeen = false;
10795 10747
@@ -10821,34 +10773,34 @@ namespace WixToolset
10821 switch (attrib.Name.LocalName) 10773 switch (attrib.Name.LocalName)
10822 { 10774 {
10823 case "Id": 10775 case "Id":
10824 packageCode = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, this.compilingProduct); 10776 packageCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, this.compilingProduct);
10825 break; 10777 break;
10826 case "AdminImage": 10778 case "AdminImage":
10827 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 10779 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10828 { 10780 {
10829 sourceBits = sourceBits | 4; 10781 sourceBits = sourceBits | 4;
10830 } 10782 }
10831 break; 10783 break;
10832 case "Comments": 10784 case "Comments":
10833 comments = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10785 comments = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10834 break; 10786 break;
10835 case "Compressed": 10787 case "Compressed":
10836 // merge modules must always be compressed, so this attribute is invalid 10788 // merge modules must always be compressed, so this attribute is invalid
10837 if (this.compilingModule) 10789 if (this.compilingModule)
10838 { 10790 {
10839 this.core.OnMessage(WixWarnings.DeprecatedPackageCompressedAttribute(sourceLineNumbers)); 10791 this.Core.OnMessage(WixWarnings.DeprecatedPackageCompressedAttribute(sourceLineNumbers));
10840 // this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "Compressed", "Module")); 10792 // this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "Compressed", "Module"));
10841 } 10793 }
10842 else if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 10794 else if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10843 { 10795 {
10844 sourceBits = sourceBits | 2; 10796 sourceBits = sourceBits | 2;
10845 } 10797 }
10846 break; 10798 break;
10847 case "Description": 10799 case "Description":
10848 packageName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10800 packageName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10849 break; 10801 break;
10850 case "InstallPrivileges": 10802 case "InstallPrivileges":
10851 string installPrivileges = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10803 string installPrivileges = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10852 if (0 < installPrivileges.Length) 10804 if (0 < installPrivileges.Length)
10853 { 10805 {
10854 installPrivilegeSeen = true; 10806 installPrivilegeSeen = true;
@@ -10862,13 +10814,13 @@ namespace WixToolset
10862 sourceBits = sourceBits | 8; 10814 sourceBits = sourceBits | 8;
10863 break; 10815 break;
10864 default: 10816 default:
10865 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, installPrivileges, "elevated", "limited")); 10817 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, installPrivileges, "elevated", "limited"));
10866 break; 10818 break;
10867 } 10819 }
10868 } 10820 }
10869 break; 10821 break;
10870 case "InstallScope": 10822 case "InstallScope":
10871 string installScope = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10823 string installScope = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10872 if (0 < installScope.Length) 10824 if (0 < installScope.Length)
10873 { 10825 {
10874 installScopeSeen = true; 10826 installScopeSeen = true;
@@ -10876,47 +10828,47 @@ namespace WixToolset
10876 switch (installScopeType) 10828 switch (installScopeType)
10877 { 10829 {
10878 case Wix.Package.InstallScopeType.perMachine: 10830 case Wix.Package.InstallScopeType.perMachine:
10879 row = this.core.CreateRow(sourceLineNumbers, "Property"); 10831 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Property);
10880 row[0] = "ALLUSERS"; 10832 row.Set(0, "ALLUSERS");
10881 row[1] = "1"; 10833 row.Set(1, "1");
10882 break; 10834 break;
10883 case Wix.Package.InstallScopeType.perUser: 10835 case Wix.Package.InstallScopeType.perUser:
10884 sourceBits = sourceBits | 8; 10836 sourceBits = sourceBits | 8;
10885 break; 10837 break;
10886 default: 10838 default:
10887 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, installScope, "perMachine", "perUser")); 10839 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, installScope, "perMachine", "perUser"));
10888 break; 10840 break;
10889 } 10841 }
10890 } 10842 }
10891 break; 10843 break;
10892 case "InstallerVersion": 10844 case "InstallerVersion":
10893 msiVersion = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 10845 msiVersion = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
10894 break; 10846 break;
10895 case "Keywords": 10847 case "Keywords":
10896 keywords = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10848 keywords = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10897 break; 10849 break;
10898 case "Languages": 10850 case "Languages":
10899 packageLanguages = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10851 packageLanguages = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10900 break; 10852 break;
10901 case "Manufacturer": 10853 case "Manufacturer":
10902 packageAuthor = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10854 packageAuthor = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10903 if ("PUT-COMPANY-NAME-HERE" == packageAuthor) 10855 if ("PUT-COMPANY-NAME-HERE" == packageAuthor)
10904 { 10856 {
10905 this.core.OnMessage(WixWarnings.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, packageAuthor)); 10857 this.Core.OnMessage(WixWarnings.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, packageAuthor));
10906 } 10858 }
10907 break; 10859 break;
10908 case "Platform": 10860 case "Platform":
10909 if (null != platformValue) 10861 if (null != platformValue)
10910 { 10862 {
10911 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Platforms")); 10863 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Platforms"));
10912 } 10864 }
10913 10865
10914 platformValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10866 platformValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10915 Wix.Package.PlatformType platformType = Wix.Package.ParsePlatformType(platformValue); 10867 Wix.Package.PlatformType platformType = Wix.Package.ParsePlatformType(platformValue);
10916 switch (platformType) 10868 switch (platformType)
10917 { 10869 {
10918 case Wix.Package.PlatformType.intel: 10870 case Wix.Package.PlatformType.intel:
10919 this.core.OnMessage(WixWarnings.DeprecatedAttributeValue(sourceLineNumbers, platformValue, node.Name.LocalName, attrib.Name.LocalName, "x86")); 10871 this.Core.OnMessage(WixWarnings.DeprecatedAttributeValue(sourceLineNumbers, platformValue, node.Name.LocalName, attrib.Name.LocalName, "x86"));
10920 goto case Wix.Package.PlatformType.x86; 10872 goto case Wix.Package.PlatformType.x86;
10921 case Wix.Package.PlatformType.x86: 10873 case Wix.Package.PlatformType.x86:
10922 platform = "Intel"; 10874 platform = "Intel";
@@ -10925,7 +10877,7 @@ namespace WixToolset
10925 platform = "x64"; 10877 platform = "x64";
10926 break; 10878 break;
10927 case Wix.Package.PlatformType.intel64: 10879 case Wix.Package.PlatformType.intel64:
10928 this.core.OnMessage(WixWarnings.DeprecatedAttributeValue(sourceLineNumbers, platformValue, node.Name.LocalName, attrib.Name.LocalName, "ia64")); 10880 this.Core.OnMessage(WixWarnings.DeprecatedAttributeValue(sourceLineNumbers, platformValue, node.Name.LocalName, attrib.Name.LocalName, "ia64"));
10929 goto case Wix.Package.PlatformType.ia64; 10881 goto case Wix.Package.PlatformType.ia64;
10930 case Wix.Package.PlatformType.ia64: 10882 case Wix.Package.PlatformType.ia64:
10931 platform = "Intel64"; 10883 platform = "Intel64";
@@ -10934,71 +10886,71 @@ namespace WixToolset
10934 platform = "Arm"; 10886 platform = "Arm";
10935 break; 10887 break;
10936 default: 10888 default:
10937 this.core.OnMessage(WixErrors.InvalidPlatformValue(sourceLineNumbers, platformValue)); 10889 this.Core.OnMessage(WixErrors.InvalidPlatformValue(sourceLineNumbers, platformValue));
10938 break; 10890 break;
10939 } 10891 }
10940 break; 10892 break;
10941 case "Platforms": 10893 case "Platforms":
10942 if (null != platformValue) 10894 if (null != platformValue)
10943 { 10895 {
10944 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Platform")); 10896 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Platform"));
10945 } 10897 }
10946 10898
10947 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Platform")); 10899 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Platform"));
10948 platformValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 10900 platformValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
10949 platform = platformValue; 10901 platform = platformValue;
10950 break; 10902 break;
10951 case "ReadOnly": 10903 case "ReadOnly":
10952 security = this.core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); 10904 security = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
10953 break; 10905 break;
10954 case "ShortNames": 10906 case "ShortNames":
10955 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 10907 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
10956 { 10908 {
10957 sourceBits = sourceBits | 1; 10909 sourceBits = sourceBits | 1;
10958 this.useShortFileNames = true; 10910 this.useShortFileNames = true;
10959 } 10911 }
10960 break; 10912 break;
10961 case "SummaryCodepage": 10913 case "SummaryCodepage":
10962 codepage = this.core.GetAttributeLocalizableCodePageValue(sourceLineNumbers, attrib, true); 10914 codepage = this.Core.GetAttributeLocalizableCodePageValue(sourceLineNumbers, attrib, true);
10963 break; 10915 break;
10964 default: 10916 default:
10965 this.core.UnexpectedAttribute(node, attrib); 10917 this.Core.UnexpectedAttribute(node, attrib);
10966 break; 10918 break;
10967 } 10919 }
10968 } 10920 }
10969 else 10921 else
10970 { 10922 {
10971 this.core.ParseExtensionAttribute(node, attrib); 10923 this.Core.ParseExtensionAttribute(node, attrib);
10972 } 10924 }
10973 } 10925 }
10974 10926
10975 if (installPrivilegeSeen && installScopeSeen) 10927 if (installPrivilegeSeen && installScopeSeen)
10976 { 10928 {
10977 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "InstallPrivileges", "InstallScope")); 10929 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "InstallPrivileges", "InstallScope"));
10978 } 10930 }
10979 10931
10980 if ((0 != String.Compare(platform, "Intel", StringComparison.OrdinalIgnoreCase)) && 200 > msiVersion) 10932 if ((0 != String.Compare(platform, "Intel", StringComparison.OrdinalIgnoreCase)) && 200 > msiVersion)
10981 { 10933 {
10982 msiVersion = 200; 10934 msiVersion = 200;
10983 this.core.OnMessage(WixWarnings.RequiresMsi200for64bitPackage(sourceLineNumbers)); 10935 this.Core.OnMessage(WixWarnings.RequiresMsi200for64bitPackage(sourceLineNumbers));
10984 } 10936 }
10985 10937
10986 if ((0 == String.Compare(platform, "Arm", StringComparison.OrdinalIgnoreCase)) && 500 > msiVersion) 10938 if ((0 == String.Compare(platform, "Arm", StringComparison.OrdinalIgnoreCase)) && 500 > msiVersion)
10987 { 10939 {
10988 msiVersion = 500; 10940 msiVersion = 500;
10989 this.core.OnMessage(WixWarnings.RequiresMsi500forArmPackage(sourceLineNumbers)); 10941 this.Core.OnMessage(WixWarnings.RequiresMsi500forArmPackage(sourceLineNumbers));
10990 } 10942 }
10991 10943
10992 if (null == packageAuthor) 10944 if (null == packageAuthor)
10993 { 10945 {
10994 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer")); 10946 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer"));
10995 } 10947 }
10996 10948
10997 if (this.compilingModule) 10949 if (this.compilingModule)
10998 { 10950 {
10999 if (null == packageCode) 10951 if (null == packageCode)
11000 { 10952 {
11001 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 10953 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
11002 } 10954 }
11003 10955
11004 // merge modules use the modularization guid as the package code 10956 // merge modules use the modularization guid as the package code
@@ -11019,66 +10971,66 @@ namespace WixToolset
11019 10971
11020 if ("*" != packageCode) 10972 if ("*" != packageCode)
11021 { 10973 {
11022 this.core.OnMessage(WixWarnings.PackageCodeSet(sourceLineNumbers)); 10974 this.Core.OnMessage(WixWarnings.PackageCodeSet(sourceLineNumbers));
11023 } 10975 }
11024 } 10976 }
11025 10977
11026 this.core.ParseForExtensionElements(node); 10978 this.Core.ParseForExtensionElements(node);
11027 10979
11028 if (!this.core.EncounteredError) 10980 if (!this.Core.EncounteredError)
11029 { 10981 {
11030 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 10982 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11031 row[0] = 1; 10983 row.Set(0, 1);
11032 row[1] = codepage; 10984 row.Set(1, codepage);
11033 10985
11034 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 10986 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11035 row[0] = 2; 10987 row.Set(0, 2);
11036 row[1] = "Installation Database"; 10988 row.Set(1, "Installation Database");
11037 10989
11038 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 10990 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11039 row[0] = 3; 10991 row.Set(0, 3);
11040 row[1] = packageName; 10992 row.Set(1, packageName);
11041 10993
11042 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 10994 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11043 row[0] = 4; 10995 row.Set(0, 4);
11044 row[1] = packageAuthor; 10996 row.Set(1, packageAuthor);
11045 10997
11046 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 10998 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11047 row[0] = 5; 10999 row.Set(0, 5);
11048 row[1] = keywords; 11000 row.Set(1, keywords);
11049 11001
11050 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11002 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11051 row[0] = 6; 11003 row.Set(0, 6);
11052 row[1] = comments; 11004 row.Set(1, comments);
11053 11005
11054 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11006 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11055 row[0] = 7; 11007 row.Set(0, 7);
11056 row[1] = String.Format(CultureInfo.InvariantCulture, "{0};{1}", platform, packageLanguages); 11008 row.Set(1, String.Format(CultureInfo.InvariantCulture, "{0};{1}", platform, packageLanguages));
11057 11009
11058 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11010 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11059 row[0] = 9; 11011 row.Set(0, 9);
11060 row[1] = packageCode; 11012 row.Set(1, packageCode);
11061 11013
11062 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11014 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11063 row[0] = 14; 11015 row.Set(0, 14);
11064 row[1] = msiVersion.ToString(CultureInfo.InvariantCulture); 11016 row.Set(1, msiVersion.ToString(CultureInfo.InvariantCulture));
11065 11017
11066 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11018 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11067 row[0] = 15; 11019 row.Set(0, 15);
11068 row[1] = sourceBits.ToString(CultureInfo.InvariantCulture); 11020 row.Set(1, sourceBits.ToString(CultureInfo.InvariantCulture));
11069 11021
11070 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11022 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11071 row[0] = 19; 11023 row.Set(0, 19);
11072 switch (security) 11024 switch (security)
11073 { 11025 {
11074 case YesNoDefaultType.No: // no restriction 11026 case YesNoDefaultType.No: // no restriction
11075 row[1] = "0"; 11027 row.Set(1, "0");
11076 break; 11028 break;
11077 case YesNoDefaultType.Default: // read-only recommended 11029 case YesNoDefaultType.Default: // read-only recommended
11078 row[1] = "2"; 11030 row.Set(1, "2");
11079 break; 11031 break;
11080 case YesNoDefaultType.Yes: // read-only enforced 11032 case YesNoDefaultType.Yes: // read-only enforced
11081 row[1] = "4"; 11033 row.Set(1, "4");
11082 break; 11034 break;
11083 } 11035 }
11084 } 11036 }
@@ -11110,79 +11062,79 @@ namespace WixToolset
11110 switch (attrib.Name.LocalName) 11062 switch (attrib.Name.LocalName)
11111 { 11063 {
11112 case "AllowRemoval": 11064 case "AllowRemoval":
11113 allowRemoval = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 11065 allowRemoval = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
11114 break; 11066 break;
11115 case "Classification": 11067 case "Classification":
11116 classification = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11068 classification = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11117 break; 11069 break;
11118 case "CreationTimeUTC": 11070 case "CreationTimeUTC":
11119 creationTimeUtc = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11071 creationTimeUtc = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11120 break; 11072 break;
11121 case "Description": 11073 case "Description":
11122 description = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11074 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11123 break; 11075 break;
11124 case "DisplayName": 11076 case "DisplayName":
11125 displayName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11077 displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11126 break; 11078 break;
11127 case "ManufacturerName": 11079 case "ManufacturerName":
11128 manufacturerName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11080 manufacturerName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11129 break; 11081 break;
11130 case "MinorUpdateTargetRTM": 11082 case "MinorUpdateTargetRTM":
11131 minorUpdateTargetRTM = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11083 minorUpdateTargetRTM = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11132 break; 11084 break;
11133 case "MoreInfoURL": 11085 case "MoreInfoURL":
11134 moreInfoUrl = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11086 moreInfoUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11135 break; 11087 break;
11136 case "OptimizedInstallMode": 11088 case "OptimizedInstallMode":
11137 optimizedInstallMode = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 11089 optimizedInstallMode = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
11138 break; 11090 break;
11139 case "TargetProductName": 11091 case "TargetProductName":
11140 targetProductName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11092 targetProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11141 break; 11093 break;
11142 default: 11094 default:
11143 this.core.UnexpectedAttribute(node, attrib); 11095 this.Core.UnexpectedAttribute(node, attrib);
11144 break; 11096 break;
11145 } 11097 }
11146 } 11098 }
11147 else 11099 else
11148 { 11100 {
11149 this.core.ParseExtensionAttribute(node, attrib); 11101 this.Core.ParseExtensionAttribute(node, attrib);
11150 } 11102 }
11151 } 11103 }
11152 11104
11153 if (YesNoType.NotSet == allowRemoval) 11105 if (YesNoType.NotSet == allowRemoval)
11154 { 11106 {
11155 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "AllowRemoval")); 11107 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "AllowRemoval"));
11156 } 11108 }
11157 11109
11158 if (null == classification) 11110 if (null == classification)
11159 { 11111 {
11160 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Classification")); 11112 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Classification"));
11161 } 11113 }
11162 11114
11163 if (null == description) 11115 if (null == description)
11164 { 11116 {
11165 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description")); 11117 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description"));
11166 } 11118 }
11167 11119
11168 if (null == displayName) 11120 if (null == displayName)
11169 { 11121 {
11170 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayName")); 11122 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayName"));
11171 } 11123 }
11172 11124
11173 if (null == manufacturerName) 11125 if (null == manufacturerName)
11174 { 11126 {
11175 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ManufacturerName")); 11127 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ManufacturerName"));
11176 } 11128 }
11177 11129
11178 if (null == moreInfoUrl) 11130 if (null == moreInfoUrl)
11179 { 11131 {
11180 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "MoreInfoURL")); 11132 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "MoreInfoURL"));
11181 } 11133 }
11182 11134
11183 if (null == targetProductName) 11135 if (null == targetProductName)
11184 { 11136 {
11185 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "TargetProductName")); 11137 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "TargetProductName"));
11186 } 11138 }
11187 11139
11188 foreach (XElement child in node.Elements()) 11140 foreach (XElement child in node.Elements())
@@ -11198,104 +11150,104 @@ namespace WixToolset
11198 optimizeCA = this.ParseOptimizeCustomActionsElement(child); 11150 optimizeCA = this.ParseOptimizeCustomActionsElement(child);
11199 break; 11151 break;
11200 default: 11152 default:
11201 this.core.UnexpectedElement(node, child); 11153 this.Core.UnexpectedElement(node, child);
11202 break; 11154 break;
11203 } 11155 }
11204 } 11156 }
11205 else 11157 else
11206 { 11158 {
11207 this.core.ParseExtensionElement(node, child); 11159 this.Core.ParseExtensionElement(node, child);
11208 } 11160 }
11209 } 11161 }
11210 11162
11211 if (!this.core.EncounteredError) 11163 if (!this.Core.EncounteredError)
11212 { 11164 {
11213 if (YesNoType.NotSet != allowRemoval) 11165 if (YesNoType.NotSet != allowRemoval)
11214 { 11166 {
11215 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11167 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11216 row[0] = null; 11168 row.Set(0, null);
11217 row[1] = "AllowRemoval"; 11169 row.Set(1, "AllowRemoval");
11218 row[2] = YesNoType.Yes == allowRemoval ? "1" : "0"; 11170 row.Set(2, YesNoType.Yes == allowRemoval ? "1" : "0");
11219 } 11171 }
11220 11172
11221 if (null != classification) 11173 if (null != classification)
11222 { 11174 {
11223 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11175 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11224 row[0] = null; 11176 row.Set(0, null);
11225 row[1] = "Classification"; 11177 row.Set(1, "Classification");
11226 row[2] = classification; 11178 row.Set(2, classification);
11227 } 11179 }
11228 11180
11229 if (null != creationTimeUtc) 11181 if (null != creationTimeUtc)
11230 { 11182 {
11231 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11183 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11232 row[0] = null; 11184 row.Set(0, null);
11233 row[1] = "CreationTimeUTC"; 11185 row.Set(1, "CreationTimeUTC");
11234 row[2] = creationTimeUtc; 11186 row.Set(2, creationTimeUtc);
11235 } 11187 }
11236 11188
11237 if (null != description) 11189 if (null != description)
11238 { 11190 {
11239 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11191 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11240 row[0] = null; 11192 row.Set(0, null);
11241 row[1] = "Description"; 11193 row.Set(1, "Description");
11242 row[2] = description; 11194 row.Set(2, description);
11243 } 11195 }
11244 11196
11245 if (null != displayName) 11197 if (null != displayName)
11246 { 11198 {
11247 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11199 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11248 row[0] = null; 11200 row.Set(0, null);
11249 row[1] = "DisplayName"; 11201 row.Set(1, "DisplayName");
11250 row[2] = displayName; 11202 row.Set(2, displayName);
11251 } 11203 }
11252 11204
11253 if (null != manufacturerName) 11205 if (null != manufacturerName)
11254 { 11206 {
11255 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11207 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11256 row[0] = null; 11208 row.Set(0, null);
11257 row[1] = "ManufacturerName"; 11209 row.Set(1, "ManufacturerName");
11258 row[2] = manufacturerName; 11210 row.Set(2, manufacturerName);
11259 } 11211 }
11260 11212
11261 if (null != minorUpdateTargetRTM) 11213 if (null != minorUpdateTargetRTM)
11262 { 11214 {
11263 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11215 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11264 row[0] = null; 11216 row.Set(0, null);
11265 row[1] = "MinorUpdateTargetRTM"; 11217 row.Set(1, "MinorUpdateTargetRTM");
11266 row[2] = minorUpdateTargetRTM; 11218 row.Set(2, minorUpdateTargetRTM);
11267 } 11219 }
11268 11220
11269 if (null != moreInfoUrl) 11221 if (null != moreInfoUrl)
11270 { 11222 {
11271 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11223 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11272 row[0] = null; 11224 row.Set(0, null);
11273 row[1] = "MoreInfoURL"; 11225 row.Set(1, "MoreInfoURL");
11274 row[2] = moreInfoUrl; 11226 row.Set(2, moreInfoUrl);
11275 } 11227 }
11276 11228
11277 if (CompilerConstants.IntegerNotSet != optimizeCA) 11229 if (CompilerConstants.IntegerNotSet != optimizeCA)
11278 { 11230 {
11279 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11231 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11280 row[0] = null; 11232 row.Set(0, null);
11281 row[1] = "OptimizeCA"; 11233 row.Set(1, "OptimizeCA");
11282 row[2] = optimizeCA.ToString(CultureInfo.InvariantCulture); 11234 row.Set(2, optimizeCA.ToString(CultureInfo.InvariantCulture));
11283 } 11235 }
11284 11236
11285 if (YesNoType.NotSet != optimizedInstallMode) 11237 if (YesNoType.NotSet != optimizedInstallMode)
11286 { 11238 {
11287 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11239 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11288 row[0] = null; 11240 row.Set(0, null);
11289 row[1] = "OptimizedInstallMode"; 11241 row.Set(1, "OptimizedInstallMode");
11290 row[2] = YesNoType.Yes == optimizedInstallMode ? "1" : "0"; 11242 row.Set(2, YesNoType.Yes == optimizedInstallMode ? "1" : "0");
11291 } 11243 }
11292 11244
11293 if (null != targetProductName) 11245 if (null != targetProductName)
11294 { 11246 {
11295 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11247 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11296 row[0] = null; 11248 row.Set(0, null);
11297 row[1] = "TargetProductName"; 11249 row.Set(1, "TargetProductName");
11298 row[2] = targetProductName; 11250 row.Set(2, targetProductName);
11299 } 11251 }
11300 } 11252 }
11301 } 11253 }
@@ -11318,48 +11270,48 @@ namespace WixToolset
11318 switch (attrib.Name.LocalName) 11270 switch (attrib.Name.LocalName)
11319 { 11271 {
11320 case "Company": 11272 case "Company":
11321 company = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11273 company = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11322 break; 11274 break;
11323 case "Property": 11275 case "Property":
11324 property = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11276 property = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11325 break; 11277 break;
11326 case "Value": 11278 case "Value":
11327 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11279 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11328 break; 11280 break;
11329 default: 11281 default:
11330 this.core.UnexpectedAttribute(node, attrib); 11282 this.Core.UnexpectedAttribute(node, attrib);
11331 break; 11283 break;
11332 } 11284 }
11333 } 11285 }
11334 else 11286 else
11335 { 11287 {
11336 this.core.ParseExtensionAttribute(node, attrib); 11288 this.Core.ParseExtensionAttribute(node, attrib);
11337 } 11289 }
11338 } 11290 }
11339 11291
11340 if (null == company) 11292 if (null == company)
11341 { 11293 {
11342 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Company")); 11294 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Company"));
11343 } 11295 }
11344 11296
11345 if (null == property) 11297 if (null == property)
11346 { 11298 {
11347 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property")); 11299 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property"));
11348 } 11300 }
11349 11301
11350 if (null == value) 11302 if (null == value)
11351 { 11303 {
11352 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 11304 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
11353 } 11305 }
11354 11306
11355 this.core.ParseForExtensionElements(node); 11307 this.Core.ParseForExtensionElements(node);
11356 11308
11357 if (!this.core.EncounteredError) 11309 if (!this.Core.EncounteredError)
11358 { 11310 {
11359 Row row = this.core.CreateRow(sourceLineNumbers, "PatchMetadata"); 11311 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
11360 row[0] = company; 11312 row.Set(0, company);
11361 row[1] = property; 11313 row.Set(1, property);
11362 row[2] = value; 11314 row.Set(2, value);
11363 } 11315 }
11364 } 11316 }
11365 11317
@@ -11380,31 +11332,31 @@ namespace WixToolset
11380 switch (attrib.Name.LocalName) 11332 switch (attrib.Name.LocalName)
11381 { 11333 {
11382 case "SkipAssignment": 11334 case "SkipAssignment":
11383 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 11335 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
11384 { 11336 {
11385 optimizeCA |= OptimizeCA.SkipAssignment; 11337 optimizeCA |= OptimizeCA.SkipAssignment;
11386 } 11338 }
11387 break; 11339 break;
11388 case "SkipImmediate": 11340 case "SkipImmediate":
11389 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 11341 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
11390 { 11342 {
11391 optimizeCA |= OptimizeCA.SkipImmediate; 11343 optimizeCA |= OptimizeCA.SkipImmediate;
11392 } 11344 }
11393 break; 11345 break;
11394 case "SkipDeferred": 11346 case "SkipDeferred":
11395 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 11347 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
11396 { 11348 {
11397 optimizeCA |= OptimizeCA.SkipDeferred; 11349 optimizeCA |= OptimizeCA.SkipDeferred;
11398 } 11350 }
11399 break; 11351 break;
11400 default: 11352 default:
11401 this.core.UnexpectedAttribute(node, attrib); 11353 this.Core.UnexpectedAttribute(node, attrib);
11402 break; 11354 break;
11403 } 11355 }
11404 } 11356 }
11405 else 11357 else
11406 { 11358 {
11407 this.core.ParseExtensionAttribute(node, attrib); 11359 this.Core.ParseExtensionAttribute(node, attrib);
11408 } 11360 }
11409 } 11361 }
11410 11362
@@ -11433,118 +11385,118 @@ namespace WixToolset
11433 switch (attrib.Name.LocalName) 11385 switch (attrib.Name.LocalName)
11434 { 11386 {
11435 case "AdminImage": 11387 case "AdminImage":
11436 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); 11388 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
11437 break; 11389 break;
11438 case "Comments": 11390 case "Comments":
11439 comments = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11391 comments = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11440 break; 11392 break;
11441 case "Compressed": 11393 case "Compressed":
11442 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); 11394 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
11443 break; 11395 break;
11444 case "Description": 11396 case "Description":
11445 packageName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11397 packageName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11446 break; 11398 break;
11447 case "Keywords": 11399 case "Keywords":
11448 keywords = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11400 keywords = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11449 break; 11401 break;
11450 case "Languages": 11402 case "Languages":
11451 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); 11403 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
11452 break; 11404 break;
11453 case "Manufacturer": 11405 case "Manufacturer":
11454 packageAuthor = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11406 packageAuthor = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11455 break; 11407 break;
11456 case "Platforms": 11408 case "Platforms":
11457 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); 11409 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
11458 break; 11410 break;
11459 case "ReadOnly": 11411 case "ReadOnly":
11460 security = this.core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); 11412 security = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
11461 break; 11413 break;
11462 case "ShortNames": 11414 case "ShortNames":
11463 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); 11415 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
11464 break; 11416 break;
11465 case "SummaryCodepage": 11417 case "SummaryCodepage":
11466 codepage = this.core.GetAttributeLocalizableCodePageValue(sourceLineNumbers, attrib); 11418 codepage = this.Core.GetAttributeLocalizableCodePageValue(sourceLineNumbers, attrib);
11467 break; 11419 break;
11468 default: 11420 default:
11469 this.core.UnexpectedAttribute(node, attrib); 11421 this.Core.UnexpectedAttribute(node, attrib);
11470 break; 11422 break;
11471 } 11423 }
11472 } 11424 }
11473 else 11425 else
11474 { 11426 {
11475 this.core.ParseExtensionAttribute(node, attrib); 11427 this.Core.ParseExtensionAttribute(node, attrib);
11476 } 11428 }
11477 } 11429 }
11478 11430
11479 this.core.ParseForExtensionElements(node); 11431 this.Core.ParseForExtensionElements(node);
11480 11432
11481 if (!this.core.EncounteredError) 11433 if (!this.Core.EncounteredError)
11482 { 11434 {
11483 // PID_CODEPAGE 11435 // PID_CODEPAGE
11484 Row row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11436 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11485 row[0] = 1; 11437 row.Set(0, 1);
11486 row[1] = codepage; 11438 row.Set(1, codepage);
11487 11439
11488 // PID_TITLE 11440 // PID_TITLE
11489 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11441 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11490 row[0] = 2; 11442 row.Set(0, 2);
11491 row[1] = "Patch"; 11443 row.Set(1, "Patch");
11492 11444
11493 // PID_SUBJECT 11445 // PID_SUBJECT
11494 if (null != packageName) 11446 if (null != packageName)
11495 { 11447 {
11496 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11448 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11497 row[0] = 3; 11449 row.Set(0, 3);
11498 row[1] = packageName; 11450 row.Set(1, packageName);
11499 } 11451 }
11500 11452
11501 // PID_AUTHOR 11453 // PID_AUTHOR
11502 if (null != packageAuthor) 11454 if (null != packageAuthor)
11503 { 11455 {
11504 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11456 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11505 row[0] = 4; 11457 row.Set(0, 4);
11506 row[1] = packageAuthor; 11458 row.Set(1, packageAuthor);
11507 } 11459 }
11508 11460
11509 // PID_KEYWORDS 11461 // PID_KEYWORDS
11510 if (null != keywords) 11462 if (null != keywords)
11511 { 11463 {
11512 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11464 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11513 row[0] = 5; 11465 row.Set(0, 5);
11514 row[1] = keywords; 11466 row.Set(1, keywords);
11515 } 11467 }
11516 11468
11517 // PID_COMMENTS 11469 // PID_COMMENTS
11518 if (null != comments) 11470 if (null != comments)
11519 { 11471 {
11520 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11472 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11521 row[0] = 6; 11473 row.Set(0, 6);
11522 row[1] = comments; 11474 row.Set(1, comments);
11523 } 11475 }
11524 11476
11525 // PID_PAGECOUNT 11477 // PID_PAGECOUNT
11526 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11478 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11527 row[0] = 14; 11479 row.Set(0, 14);
11528 row[1] = msiVersion.ToString(CultureInfo.InvariantCulture); 11480 row.Set(1, msiVersion.ToString(CultureInfo.InvariantCulture));
11529 11481
11530 // PID_WORDCOUNT 11482 // PID_WORDCOUNT
11531 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11483 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11532 row[0] = 15; 11484 row.Set(0, 15);
11533 row[1] = "0"; 11485 row.Set(1, "0");
11534 11486
11535 // PID_SECURITY 11487 // PID_SECURITY
11536 row = this.core.CreateRow(sourceLineNumbers, "_SummaryInformation"); 11488 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
11537 row[0] = 19; 11489 row.Set(0, 19);
11538 switch (security) 11490 switch (security)
11539 { 11491 {
11540 case YesNoDefaultType.No: // no restriction 11492 case YesNoDefaultType.No: // no restriction
11541 row[1] = "0"; 11493 row.Set(1, "0");
11542 break; 11494 break;
11543 case YesNoDefaultType.Default: // read-only recommended 11495 case YesNoDefaultType.Default: // read-only recommended
11544 row[1] = "2"; 11496 row.Set(1, "2");
11545 break; 11497 break;
11546 case YesNoDefaultType.Yes: // read-only enforced 11498 case YesNoDefaultType.Yes: // read-only enforced
11547 row[1] = "4"; 11499 row.Set(1, "4");
11548 break; 11500 break;
11549 } 11501 }
11550 } 11502 }
@@ -11559,7 +11511,7 @@ namespace WixToolset
11559 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 11511 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
11560 string name = null; 11512 string name = null;
11561 11513
11562 this.core.OnMessage(WixWarnings.DeprecatedIgnoreModularizationElement(sourceLineNumbers)); 11514 this.Core.OnMessage(WixWarnings.DeprecatedIgnoreModularizationElement(sourceLineNumbers));
11563 11515
11564 foreach (XAttribute attrib in node.Attributes()) 11516 foreach (XAttribute attrib in node.Attributes())
11565 { 11517 {
@@ -11568,33 +11520,33 @@ namespace WixToolset
11568 switch (attrib.Name.LocalName) 11520 switch (attrib.Name.LocalName)
11569 { 11521 {
11570 case "Name": 11522 case "Name":
11571 name = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 11523 name = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
11572 break; 11524 break;
11573 case "Type": 11525 case "Type":
11574 // this is actually not used 11526 // this is actually not used
11575 break; 11527 break;
11576 default: 11528 default:
11577 this.core.UnexpectedAttribute(node, attrib); 11529 this.Core.UnexpectedAttribute(node, attrib);
11578 break; 11530 break;
11579 } 11531 }
11580 } 11532 }
11581 else 11533 else
11582 { 11534 {
11583 this.core.ParseExtensionAttribute(node, attrib); 11535 this.Core.ParseExtensionAttribute(node, attrib);
11584 } 11536 }
11585 } 11537 }
11586 11538
11587 if (null == name) 11539 if (null == name)
11588 { 11540 {
11589 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 11541 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
11590 } 11542 }
11591 11543
11592 this.core.ParseForExtensionElements(node); 11544 this.Core.ParseForExtensionElements(node);
11593 11545
11594 if (!this.core.EncounteredError) 11546 if (!this.Core.EncounteredError)
11595 { 11547 {
11596 Row row = this.core.CreateRow(sourceLineNumbers, "WixSuppressModularization"); 11548 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSuppressModularization);
11597 row[0] = name; 11549 row.Set(0, name);
11598 } 11550 }
11599 } 11551 }
11600 11552
@@ -11625,7 +11577,7 @@ namespace WixToolset
11625 specialPermissions = Common.RegistryPermissions; 11577 specialPermissions = Common.RegistryPermissions;
11626 break; 11578 break;
11627 default: 11579 default:
11628 this.core.UnexpectedElement(node.Parent, node); 11580 this.Core.UnexpectedElement(node.Parent, node);
11629 return; // stop processing this element since no valid permissions are available 11581 return; // stop processing this element since no valid permissions are available
11630 } 11582 }
11631 11583
@@ -11636,10 +11588,10 @@ namespace WixToolset
11636 switch (attrib.Name.LocalName) 11588 switch (attrib.Name.LocalName)
11637 { 11589 {
11638 case "Domain": 11590 case "Domain":
11639 domain = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11591 domain = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11640 break; 11592 break;
11641 case "User": 11593 case "User":
11642 user = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11594 user = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11643 break; 11595 break;
11644 case "FileAllRights": 11596 case "FileAllRights":
11645 // match the WinNT.h mask FILE_ALL_ACCESS for value 0x001F01FF (aka 1 1111 0000 0001 1111 1111 or 2032127) 11597 // match the WinNT.h mask FILE_ALL_ACCESS for value 0x001F01FF (aka 1 1111 0000 0001 1111 1111 or 2032127)
@@ -11650,14 +11602,14 @@ namespace WixToolset
11650 bits[0] = bits[1] = bits[2] = bits[3] = bits[4] = bits[5] = bits[6] = bits[7] = bits[8] = bits[9] = bits[10] = bits[11] = bits[12] = bits[13] = bits[14] = bits[15] = true; 11602 bits[0] = bits[1] = bits[2] = bits[3] = bits[4] = bits[5] = bits[6] = bits[7] = bits[8] = bits[9] = bits[10] = bits[11] = bits[12] = bits[13] = bits[14] = bits[15] = true;
11651 break; 11603 break;
11652 default: 11604 default:
11653 YesNoType attribValue = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 11605 YesNoType attribValue = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
11654 if (!this.core.TrySetBitFromName(Common.StandardPermissions, attrib.Name.LocalName, attribValue, bits, 16)) 11606 if (!this.Core.TrySetBitFromName(Common.StandardPermissions, attrib.Name.LocalName, attribValue, bits, 16))
11655 { 11607 {
11656 if (!this.core.TrySetBitFromName(Common.GenericPermissions, attrib.Name.LocalName, attribValue, bits, 28)) 11608 if (!this.Core.TrySetBitFromName(Common.GenericPermissions, attrib.Name.LocalName, attribValue, bits, 28))
11657 { 11609 {
11658 if (!this.core.TrySetBitFromName(specialPermissions, attrib.Name.LocalName, attribValue, bits, 0)) 11610 if (!this.Core.TrySetBitFromName(specialPermissions, attrib.Name.LocalName, attribValue, bits, 0))
11659 { 11611 {
11660 this.core.UnexpectedAttribute(node, attrib); 11612 this.Core.UnexpectedAttribute(node, attrib);
11661 break; 11613 break;
11662 } 11614 }
11663 } 11615 }
@@ -11667,32 +11619,32 @@ namespace WixToolset
11667 } 11619 }
11668 else 11620 else
11669 { 11621 {
11670 this.core.ParseExtensionAttribute(node, attrib); 11622 this.Core.ParseExtensionAttribute(node, attrib);
11671 } 11623 }
11672 } 11624 }
11673 11625
11674 permission = this.core.CreateIntegerFromBitArray(bits); 11626 permission = this.Core.CreateIntegerFromBitArray(bits);
11675 11627
11676 if (null == user) 11628 if (null == user)
11677 { 11629 {
11678 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "User")); 11630 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "User"));
11679 } 11631 }
11680 11632
11681 if (int.MinValue == permission) // just GENERIC_READ, which is MSI_NULL 11633 if (int.MinValue == permission) // just GENERIC_READ, which is MSI_NULL
11682 { 11634 {
11683 this.core.OnMessage(WixErrors.GenericReadNotAllowed(sourceLineNumbers)); 11635 this.Core.OnMessage(WixErrors.GenericReadNotAllowed(sourceLineNumbers));
11684 } 11636 }
11685 11637
11686 this.core.ParseForExtensionElements(node); 11638 this.Core.ParseForExtensionElements(node);
11687 11639
11688 if (!this.core.EncounteredError) 11640 if (!this.Core.EncounteredError)
11689 { 11641 {
11690 Row row = this.core.CreateRow(sourceLineNumbers, "LockPermissions"); 11642 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.LockPermissions);
11691 row[0] = objectId; 11643 row.Set(0, objectId);
11692 row[1] = tableName; 11644 row.Set(1, tableName);
11693 row[2] = domain; 11645 row.Set(2, domain);
11694 row[3] = user; 11646 row.Set(3, user);
11695 row[4] = permission; 11647 row.Set(4, permission);
11696 } 11648 }
11697 } 11649 }
11698 11650
@@ -11717,7 +11669,7 @@ namespace WixToolset
11717 case "ServiceInstall": 11669 case "ServiceInstall":
11718 break; 11670 break;
11719 default: 11671 default:
11720 this.core.UnexpectedElement(node.Parent, node); 11672 this.Core.UnexpectedElement(node.Parent, node);
11721 return; // stop processing this element since nothing will be valid. 11673 return; // stop processing this element since nothing will be valid.
11722 } 11674 }
11723 11675
@@ -11728,30 +11680,30 @@ namespace WixToolset
11728 switch (attrib.Name.LocalName) 11680 switch (attrib.Name.LocalName)
11729 { 11681 {
11730 case "Id": 11682 case "Id":
11731 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 11683 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
11732 break; 11684 break;
11733 case "Sddl": 11685 case "Sddl":
11734 sddl = this.core.GetAttributeValue(sourceLineNumbers, attrib); 11686 sddl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
11735 break; 11687 break;
11736 default: 11688 default:
11737 this.core.UnexpectedAttribute(node, attrib); 11689 this.Core.UnexpectedAttribute(node, attrib);
11738 break; 11690 break;
11739 } 11691 }
11740 } 11692 }
11741 else 11693 else
11742 { 11694 {
11743 this.core.ParseExtensionAttribute(node, attrib); 11695 this.Core.ParseExtensionAttribute(node, attrib);
11744 } 11696 }
11745 } 11697 }
11746 11698
11747 if (null == sddl) 11699 if (null == sddl)
11748 { 11700 {
11749 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Sddl")); 11701 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Sddl"));
11750 } 11702 }
11751 11703
11752 if (null == id) 11704 if (null == id)
11753 { 11705 {
11754 id = this.core.CreateIdentifier("pme", objectId, tableName, sddl); 11706 id = this.Core.CreateIdentifier("pme", objectId, tableName, sddl);
11755 } 11707 }
11756 11708
11757 foreach (XElement child in node.Elements()) 11709 foreach (XElement child in node.Elements())
@@ -11764,29 +11716,29 @@ namespace WixToolset
11764 if (null != condition) 11716 if (null != condition)
11765 { 11717 {
11766 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 11718 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
11767 this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName)); 11719 this.Core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName));
11768 } 11720 }
11769 11721
11770 condition = this.ParseConditionElement(child, node.Name.LocalName, null, null); 11722 condition = this.ParseConditionElement(child, node.Name.LocalName, null, null);
11771 break; 11723 break;
11772 default: 11724 default:
11773 this.core.UnexpectedElement(node, child); 11725 this.Core.UnexpectedElement(node, child);
11774 break; 11726 break;
11775 } 11727 }
11776 } 11728 }
11777 else 11729 else
11778 { 11730 {
11779 this.core.ParseExtensionElement(node, child); 11731 this.Core.ParseExtensionElement(node, child);
11780 } 11732 }
11781 } 11733 }
11782 11734
11783 if (!this.core.EncounteredError) 11735 if (!this.Core.EncounteredError)
11784 { 11736 {
11785 Row row = this.core.CreateRow(sourceLineNumbers, "MsiLockPermissionsEx", id); 11737 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiLockPermissionsEx, id);
11786 row[1] = objectId; 11738 row.Set(1, objectId);
11787 row[2] = tableName; 11739 row.Set(2, tableName);
11788 row[3] = sddl; 11740 row.Set(3, sddl);
11789 row[4] = condition; 11741 row.Set(4, condition);
11790 } 11742 }
11791 } 11743 }
11792 11744
@@ -11815,84 +11767,84 @@ namespace WixToolset
11815 switch (attrib.Name.LocalName) 11767 switch (attrib.Name.LocalName)
11816 { 11768 {
11817 case "Id": 11769 case "Id":
11818 productCode = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, true); 11770 productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true);
11819 break; 11771 break;
11820 case "Codepage": 11772 case "Codepage":
11821 codepage = this.core.GetAttributeCodePageValue(sourceLineNumbers, attrib); 11773 codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
11822 break; 11774 break;
11823 case "Language": 11775 case "Language":
11824 this.activeLanguage = this.core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 11776 this.activeLanguage = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
11825 break; 11777 break;
11826 case "Manufacturer": 11778 case "Manufacturer":
11827 manufacturer = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters); 11779 manufacturer = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters);
11828 if ("PUT-COMPANY-NAME-HERE" == manufacturer) 11780 if ("PUT-COMPANY-NAME-HERE" == manufacturer)
11829 { 11781 {
11830 this.core.OnMessage(WixWarnings.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, manufacturer)); 11782 this.Core.OnMessage(WixWarnings.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, manufacturer));
11831 } 11783 }
11832 break; 11784 break;
11833 case "Name": 11785 case "Name":
11834 this.activeName = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters); 11786 this.activeName = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters);
11835 if ("PUT-PRODUCT-NAME-HERE" == this.activeName) 11787 if ("PUT-PRODUCT-NAME-HERE" == this.activeName)
11836 { 11788 {
11837 this.core.OnMessage(WixWarnings.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, this.activeName)); 11789 this.Core.OnMessage(WixWarnings.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, this.activeName));
11838 } 11790 }
11839 break; 11791 break;
11840 case "UpgradeCode": 11792 case "UpgradeCode":
11841 upgradeCode = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 11793 upgradeCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
11842 break; 11794 break;
11843 case "Version": // if the attribute is valid version, use the attribute value as is (so "1.0000.01.01" would *not* get translated to "1.0.1.1"). 11795 case "Version": // if the attribute is valid version, use the attribute value as is (so "1.0000.01.01" would *not* get translated to "1.0.1.1").
11844 string verifiedVersion = this.core.GetAttributeVersionValue(sourceLineNumbers, attrib); 11796 string verifiedVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
11845 if (!String.IsNullOrEmpty(verifiedVersion)) 11797 if (!String.IsNullOrEmpty(verifiedVersion))
11846 { 11798 {
11847 version = attrib.Value; 11799 version = attrib.Value;
11848 } 11800 }
11849 break; 11801 break;
11850 default: 11802 default:
11851 this.core.UnexpectedAttribute(node, attrib); 11803 this.Core.UnexpectedAttribute(node, attrib);
11852 break; 11804 break;
11853 } 11805 }
11854 } 11806 }
11855 else 11807 else
11856 { 11808 {
11857 this.core.ParseExtensionAttribute(node, attrib); 11809 this.Core.ParseExtensionAttribute(node, attrib);
11858 } 11810 }
11859 } 11811 }
11860 11812
11861 if (null == productCode) 11813 if (null == productCode)
11862 { 11814 {
11863 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 11815 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
11864 } 11816 }
11865 11817
11866 if (null == this.activeLanguage) 11818 if (null == this.activeLanguage)
11867 { 11819 {
11868 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language")); 11820 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language"));
11869 } 11821 }
11870 11822
11871 if (null == manufacturer) 11823 if (null == manufacturer)
11872 { 11824 {
11873 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer")); 11825 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer"));
11874 } 11826 }
11875 11827
11876 if (null == this.activeName) 11828 if (null == this.activeName)
11877 { 11829 {
11878 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 11830 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
11879 } 11831 }
11880 11832
11881 if (null == upgradeCode) 11833 if (null == upgradeCode)
11882 { 11834 {
11883 this.core.OnMessage(WixWarnings.MissingUpgradeCode(sourceLineNumbers)); 11835 this.Core.OnMessage(WixWarnings.MissingUpgradeCode(sourceLineNumbers));
11884 } 11836 }
11885 11837
11886 if (null == version) 11838 if (null == version)
11887 { 11839 {
11888 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version")); 11840 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
11889 } 11841 }
11890 else if (!CompilerCore.IsValidProductVersion(version)) 11842 else if (!CompilerCore.IsValidProductVersion(version))
11891 { 11843 {
11892 this.core.OnMessage(WixErrors.InvalidProductVersion(sourceLineNumbers, version)); 11844 this.Core.OnMessage(WixErrors.InvalidProductVersion(sourceLineNumbers, version));
11893 } 11845 }
11894 11846
11895 if (this.core.EncounteredError) 11847 if (this.Core.EncounteredError)
11896 { 11848 {
11897 return; 11849 return;
11898 } 11850 }
@@ -11900,7 +11852,7 @@ namespace WixToolset
11900 try 11852 try
11901 { 11853 {
11902 this.compilingProduct = true; 11854 this.compilingProduct = true;
11903 this.core.CreateActiveSection(productCode, SectionType.Product, codepage); 11855 this.Core.CreateActiveSection(productCode, SectionType.Product, codepage, this.Context.CompilationId);
11904 11856
11905 this.AddProperty(sourceLineNumbers, new Identifier("Manufacturer", AccessModifier.Public), manufacturer, false, false, false, true); 11857 this.AddProperty(sourceLineNumbers, new Identifier("Manufacturer", AccessModifier.Public), manufacturer, false, false, false, true);
11906 this.AddProperty(sourceLineNumbers, new Identifier("ProductCode", AccessModifier.Public), productCode, false, false, false, true); 11858 this.AddProperty(sourceLineNumbers, new Identifier("ProductCode", AccessModifier.Public), productCode, false, false, false, true);
@@ -12045,21 +11997,21 @@ namespace WixToolset
12045 this.ParseWixVariableElement(child); 11997 this.ParseWixVariableElement(child);
12046 break; 11998 break;
12047 default: 11999 default:
12048 this.core.UnexpectedElement(node, child); 12000 this.Core.UnexpectedElement(node, child);
12049 break; 12001 break;
12050 } 12002 }
12051 } 12003 }
12052 else 12004 else
12053 { 12005 {
12054 this.core.ParseExtensionElement(node, child); 12006 this.Core.ParseExtensionElement(node, child);
12055 } 12007 }
12056 } 12008 }
12057 12009
12058 if (!this.core.EncounteredError) 12010 if (!this.Core.EncounteredError)
12059 { 12011 {
12060 if (null != symbols) 12012 if (null != symbols)
12061 { 12013 {
12062 WixDeltaPatchSymbolPathsRow symbolRow = (WixDeltaPatchSymbolPathsRow)this.core.CreateRow(sourceLineNumbers, "WixDeltaPatchSymbolPaths"); 12014 var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths);
12063 symbolRow.Id = productCode; 12015 symbolRow.Id = productCode;
12064 symbolRow.Type = SymbolPathType.Product; 12016 symbolRow.Type = SymbolPathType.Product;
12065 symbolRow.SymbolPaths = symbols; 12017 symbolRow.SymbolPaths = symbols;
@@ -12100,37 +12052,37 @@ namespace WixToolset
12100 switch (attrib.Name.LocalName) 12052 switch (attrib.Name.LocalName)
12101 { 12053 {
12102 case "Id": 12054 case "Id":
12103 progId = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12055 progId = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12104 break; 12056 break;
12105 case "Advertise": 12057 case "Advertise":
12106 progIdAdvertise = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 12058 progIdAdvertise = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
12107 break; 12059 break;
12108 case "Description": 12060 case "Description":
12109 description = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 12061 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
12110 break; 12062 break;
12111 case "Icon": 12063 case "Icon":
12112 icon = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 12064 icon = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
12113 break; 12065 break;
12114 case "IconIndex": 12066 case "IconIndex":
12115 iconIndex = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, short.MinValue + 1, short.MaxValue); 12067 iconIndex = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, short.MinValue + 1, short.MaxValue);
12116 break; 12068 break;
12117 case "NoOpen": 12069 case "NoOpen":
12118 noOpen = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 12070 noOpen = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
12119 break; 12071 break;
12120 default: 12072 default:
12121 this.core.UnexpectedAttribute(node, attrib); 12073 this.Core.UnexpectedAttribute(node, attrib);
12122 break; 12074 break;
12123 } 12075 }
12124 } 12076 }
12125 else 12077 else
12126 { 12078 {
12127 this.core.ParseExtensionAttribute(node, attrib); 12079 this.Core.ParseExtensionAttribute(node, attrib);
12128 } 12080 }
12129 } 12081 }
12130 12082
12131 if ((YesNoType.No == advertise && YesNoType.Yes == progIdAdvertise) || (YesNoType.Yes == advertise && YesNoType.No == progIdAdvertise)) 12083 if ((YesNoType.No == advertise && YesNoType.Yes == progIdAdvertise) || (YesNoType.Yes == advertise && YesNoType.No == progIdAdvertise))
12132 { 12084 {
12133 this.core.OnMessage(WixErrors.AdvertiseStateMustMatch(sourceLineNumbers, advertise.ToString(), progIdAdvertise.ToString())); 12085 this.Core.OnMessage(WixErrors.AdvertiseStateMustMatch(sourceLineNumbers, advertise.ToString(), progIdAdvertise.ToString()));
12134 } 12086 }
12135 else 12087 else
12136 { 12088 {
@@ -12144,7 +12096,7 @@ namespace WixToolset
12144 12096
12145 if (null != parent && (null != icon || CompilerConstants.IntegerNotSet != iconIndex)) 12097 if (null != parent && (null != icon || CompilerConstants.IntegerNotSet != iconIndex))
12146 { 12098 {
12147 this.core.OnMessage(WixErrors.VersionIndependentProgIdsCannotHaveIcons(sourceLineNumbers)); 12099 this.Core.OnMessage(WixErrors.VersionIndependentProgIdsCannotHaveIcons(sourceLineNumbers));
12148 } 12100 }
12149 12101
12150 YesNoType firstProgIdForNestedClass = YesNoType.Yes; 12102 YesNoType firstProgIdForNestedClass = YesNoType.Yes;
@@ -12176,70 +12128,70 @@ namespace WixToolset
12176 else 12128 else
12177 { 12129 {
12178 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); 12130 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
12179 this.core.OnMessage(WixErrors.ProgIdNestedTooDeep(childSourceLineNumbers)); 12131 this.Core.OnMessage(WixErrors.ProgIdNestedTooDeep(childSourceLineNumbers));
12180 } 12132 }
12181 break; 12133 break;
12182 default: 12134 default:
12183 this.core.UnexpectedElement(node, child); 12135 this.Core.UnexpectedElement(node, child);
12184 break; 12136 break;
12185 } 12137 }
12186 } 12138 }
12187 else 12139 else
12188 { 12140 {
12189 this.core.ParseExtensionElement(node, child); 12141 this.Core.ParseExtensionElement(node, child);
12190 } 12142 }
12191 } 12143 }
12192 12144
12193 if (YesNoType.Yes == advertise) 12145 if (YesNoType.Yes == advertise)
12194 { 12146 {
12195 if (!this.core.EncounteredError) 12147 if (!this.Core.EncounteredError)
12196 { 12148 {
12197 Row row = this.core.CreateRow(sourceLineNumbers, "ProgId"); 12149 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ProgId);
12198 row[0] = progId; 12150 row.Set(0, progId);
12199 row[1] = parent; 12151 row.Set(1, parent);
12200 row[2] = classId; 12152 row.Set(2, classId);
12201 row[3] = description; 12153 row.Set(3, description);
12202 if (null != icon) 12154 if (null != icon)
12203 { 12155 {
12204 row[4] = icon; 12156 row.Set(4, icon);
12205 this.core.CreateSimpleReference(sourceLineNumbers, "Icon", icon); 12157 this.Core.CreateSimpleReference(sourceLineNumbers, "Icon", icon);
12206 } 12158 }
12207 12159
12208 if (CompilerConstants.IntegerNotSet != iconIndex) 12160 if (CompilerConstants.IntegerNotSet != iconIndex)
12209 { 12161 {
12210 row[5] = iconIndex; 12162 row.Set(5, iconIndex);
12211 } 12163 }
12212 12164
12213 this.core.EnsureTable(sourceLineNumbers, "Class"); 12165 this.Core.EnsureTable(sourceLineNumbers, "Class");
12214 } 12166 }
12215 } 12167 }
12216 else if (YesNoType.No == advertise) 12168 else if (YesNoType.No == advertise)
12217 { 12169 {
12218 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, progId, String.Empty, description, componentId); 12170 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, progId, String.Empty, description, componentId);
12219 if (null != classId) 12171 if (null != classId)
12220 { 12172 {
12221 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(progId, "\\CLSID"), String.Empty, classId, componentId); 12173 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(progId, "\\CLSID"), String.Empty, classId, componentId);
12222 if (null != parent) // if this is a version independent ProgId 12174 if (null != parent) // if this is a version independent ProgId
12223 { 12175 {
12224 if (YesNoType.Yes == firstProgIdForClass) 12176 if (YesNoType.Yes == firstProgIdForClass)
12225 { 12177 {
12226 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\VersionIndependentProgID"), String.Empty, progId, componentId); 12178 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\VersionIndependentProgID"), String.Empty, progId, componentId);
12227 } 12179 }
12228 12180
12229 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(progId, "\\CurVer"), String.Empty, parent, componentId); 12181 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(progId, "\\CurVer"), String.Empty, parent, componentId);
12230 } 12182 }
12231 else 12183 else
12232 { 12184 {
12233 if (YesNoType.Yes == firstProgIdForClass) 12185 if (YesNoType.Yes == firstProgIdForClass)
12234 { 12186 {
12235 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\ProgID"), String.Empty, progId, componentId); 12187 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\ProgID"), String.Empty, progId, componentId);
12236 } 12188 }
12237 } 12189 }
12238 } 12190 }
12239 12191
12240 if (null != icon) // ProgId's Default Icon 12192 if (null != icon) // ProgId's Default Icon
12241 { 12193 {
12242 this.core.CreateSimpleReference(sourceLineNumbers, "File", icon); 12194 this.Core.CreateSimpleReference(sourceLineNumbers, "File", icon);
12243 12195
12244 icon = String.Format(CultureInfo.InvariantCulture, "\"[#{0}]\"", icon); 12196 icon = String.Format(CultureInfo.InvariantCulture, "\"[#{0}]\"", icon);
12245 12197
@@ -12248,19 +12200,19 @@ namespace WixToolset
12248 icon = String.Concat(icon, ",", iconIndex); 12200 icon = String.Concat(icon, ",", iconIndex);
12249 } 12201 }
12250 12202
12251 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(progId, "\\DefaultIcon"), String.Empty, icon, componentId); 12203 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(progId, "\\DefaultIcon"), String.Empty, icon, componentId);
12252 } 12204 }
12253 } 12205 }
12254 12206
12255 if (null != noOpen) 12207 if (null != noOpen)
12256 { 12208 {
12257 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, progId, "NoOpen", noOpen, componentId); // ProgId NoOpen name 12209 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, progId, "NoOpen", noOpen, componentId); // ProgId NoOpen name
12258 } 12210 }
12259 12211
12260 // raise an error for an orphaned ProgId 12212 // raise an error for an orphaned ProgId
12261 if (YesNoType.Yes == advertise && !foundExtension && null == parent && null == classId) 12213 if (YesNoType.Yes == advertise && !foundExtension && null == parent && null == classId)
12262 { 12214 {
12263 this.core.OnMessage(WixWarnings.OrphanedProgId(sourceLineNumbers, progId)); 12215 this.Core.OnMessage(WixWarnings.OrphanedProgId(sourceLineNumbers, progId));
12264 } 12216 }
12265 12217
12266 return progId; 12218 return progId;
@@ -12288,58 +12240,58 @@ namespace WixToolset
12288 switch (attrib.Name.LocalName) 12240 switch (attrib.Name.LocalName)
12289 { 12241 {
12290 case "Id": 12242 case "Id":
12291 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 12243 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
12292 break; 12244 break;
12293 case "Admin": 12245 case "Admin":
12294 admin = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 12246 admin = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
12295 break; 12247 break;
12296 case "ComplianceCheck": 12248 case "ComplianceCheck":
12297 complianceCheck = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 12249 complianceCheck = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
12298 break; 12250 break;
12299 case "Hidden": 12251 case "Hidden":
12300 hidden = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 12252 hidden = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
12301 break; 12253 break;
12302 case "Secure": 12254 case "Secure":
12303 secure = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 12255 secure = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
12304 break; 12256 break;
12305 case "SuppressModularization": 12257 case "SuppressModularization":
12306 suppressModularization = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 12258 suppressModularization = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
12307 break; 12259 break;
12308 case "Value": 12260 case "Value":
12309 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12261 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12310 break; 12262 break;
12311 default: 12263 default:
12312 this.core.UnexpectedAttribute(node, attrib); 12264 this.Core.UnexpectedAttribute(node, attrib);
12313 break; 12265 break;
12314 } 12266 }
12315 } 12267 }
12316 else 12268 else
12317 { 12269 {
12318 this.core.ParseExtensionAttribute(node, attrib); 12270 this.Core.ParseExtensionAttribute(node, attrib);
12319 } 12271 }
12320 } 12272 }
12321 12273
12322 if (null == id) 12274 if (null == id)
12323 { 12275 {
12324 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 12276 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
12325 id = Identifier.Invalid; 12277 id = Identifier.Invalid;
12326 } 12278 }
12327 else if ("ProductID" == id.Id) 12279 else if ("ProductID" == id.Id)
12328 { 12280 {
12329 this.core.OnMessage(WixWarnings.ProductIdAuthored(sourceLineNumbers)); 12281 this.Core.OnMessage(WixWarnings.ProductIdAuthored(sourceLineNumbers));
12330 } 12282 }
12331 else if ("SecureCustomProperties" == id.Id || "AdminProperties" == id.Id || "MsiHiddenProperties" == id.Id) 12283 else if ("SecureCustomProperties" == id.Id || "AdminProperties" == id.Id || "MsiHiddenProperties" == id.Id)
12332 { 12284 {
12333 this.core.OnMessage(WixErrors.CannotAuthorSpecialProperties(sourceLineNumbers, id.Id)); 12285 this.Core.OnMessage(WixErrors.CannotAuthorSpecialProperties(sourceLineNumbers, id.Id));
12334 } 12286 }
12335 12287
12336 string innerText = this.core.GetTrimmedInnerText(node); 12288 string innerText = this.Core.GetTrimmedInnerText(node);
12337 if (null != value) 12289 if (null != value)
12338 { 12290 {
12339 // cannot specify both the value attribute and inner text 12291 // cannot specify both the value attribute and inner text
12340 if (!String.IsNullOrEmpty(innerText)) 12292 if (!String.IsNullOrEmpty(innerText))
12341 { 12293 {
12342 this.core.OnMessage(WixErrors.IllegalAttributeWithInnerText(sourceLineNumbers, node.Name.LocalName, "Value")); 12294 this.Core.OnMessage(WixErrors.IllegalAttributeWithInnerText(sourceLineNumbers, node.Name.LocalName, "Value"));
12343 } 12295 }
12344 } 12296 }
12345 else // value attribute not specified, use inner text if any. 12297 else // value attribute not specified, use inner text if any.
@@ -12349,7 +12301,7 @@ namespace WixToolset
12349 12301
12350 if ("ErrorDialog" == id.Id) 12302 if ("ErrorDialog" == id.Id)
12351 { 12303 {
12352 this.core.CreateSimpleReference(sourceLineNumbers, "Dialog", value); 12304 this.Core.CreateSimpleReference(sourceLineNumbers, "Dialog", value);
12353 } 12305 }
12354 12306
12355 foreach (XElement child in node.Elements()) 12307 foreach (XElement child in node.Elements())
@@ -12377,14 +12329,14 @@ namespace WixToolset
12377 // If we're doing CCP then there must be a signature. 12329 // If we're doing CCP then there must be a signature.
12378 if (complianceCheck && 0 == signatures.Count) 12330 if (complianceCheck && 0 == signatures.Count)
12379 { 12331 {
12380 this.core.OnMessage(WixErrors.SearchElementRequiredWithAttribute(sourceLineNumbers, node.Name.LocalName, "ComplianceCheck", "yes")); 12332 this.Core.OnMessage(WixErrors.SearchElementRequiredWithAttribute(sourceLineNumbers, node.Name.LocalName, "ComplianceCheck", "yes"));
12381 } 12333 }
12382 12334
12383 foreach (string sig in signatures) 12335 foreach (string sig in signatures)
12384 { 12336 {
12385 if (complianceCheck && !this.core.EncounteredError) 12337 if (complianceCheck && !this.Core.EncounteredError)
12386 { 12338 {
12387 this.core.CreateRow(sourceLineNumbers, "CCPSearch", new Identifier(sig, AccessModifier.Private)); 12339 this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CCPSearch, new Identifier(sig, AccessModifier.Private));
12388 } 12340 }
12389 12341
12390 this.AddAppSearch(sourceLineNumbers, id, sig); 12342 this.AddAppSearch(sourceLineNumbers, id, sig);
@@ -12401,7 +12353,7 @@ namespace WixToolset
12401 // the element. 12353 // the element.
12402 if (String.IsNullOrEmpty(value) && !admin && !secure && !hidden) 12354 if (String.IsNullOrEmpty(value) && !admin && !secure && !hidden)
12403 { 12355 {
12404 this.core.OnMessage(WixWarnings.PropertyUseless(sourceLineNumbers, id.Id)); 12356 this.Core.OnMessage(WixWarnings.PropertyUseless(sourceLineNumbers, id.Id));
12405 } 12357 }
12406 else // there is a value and/or a flag set, do that. 12358 else // there is a value and/or a flag set, do that.
12407 { 12359 {
@@ -12409,11 +12361,11 @@ namespace WixToolset
12409 } 12361 }
12410 } 12362 }
12411 12363
12412 if (!this.core.EncounteredError && YesNoType.Yes == suppressModularization) 12364 if (!this.Core.EncounteredError && YesNoType.Yes == suppressModularization)
12413 { 12365 {
12414 this.core.OnMessage(WixWarnings.PropertyModularizationSuppressed(sourceLineNumbers)); 12366 this.Core.OnMessage(WixWarnings.PropertyModularizationSuppressed(sourceLineNumbers));
12415 12367
12416 this.core.CreateRow(sourceLineNumbers, "WixSuppressModularization", id); 12368 this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSuppressModularization, id);
12417 } 12369 }
12418 } 12370 }
12419 12371
@@ -12450,11 +12402,11 @@ namespace WixToolset
12450 switch (attrib.Name.LocalName) 12402 switch (attrib.Name.LocalName)
12451 { 12403 {
12452 case "Id": 12404 case "Id":
12453 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 12405 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
12454 break; 12406 break;
12455 case "Action": 12407 case "Action":
12456 this.core.OnMessage(WixWarnings.DeprecatedRegistryKeyActionAttribute(sourceLineNumbers)); 12408 this.Core.OnMessage(WixWarnings.DeprecatedRegistryKeyActionAttribute(sourceLineNumbers));
12457 action = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12409 action = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12458 if (0 < action.Length) 12410 if (0 < action.Length)
12459 { 12411 {
12460 actionType = Wix.RegistryKey.ParseActionType(action); 12412 actionType = Wix.RegistryKey.ParseActionType(action);
@@ -12470,19 +12422,19 @@ namespace WixToolset
12470 case Wix.RegistryKey.ActionType.none: 12422 case Wix.RegistryKey.ActionType.none:
12471 break; 12423 break;
12472 default: 12424 default:
12473 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, action, "create", "createAndRemoveOnUninstall", "none")); 12425 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, action, "create", "createAndRemoveOnUninstall", "none"));
12474 break; 12426 break;
12475 } 12427 }
12476 } 12428 }
12477 break; 12429 break;
12478 case "ForceCreateOnInstall": 12430 case "ForceCreateOnInstall":
12479 forceCreateOnInstall = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 12431 forceCreateOnInstall = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
12480 break; 12432 break;
12481 case "ForceDeleteOnUninstall": 12433 case "ForceDeleteOnUninstall":
12482 forceDeleteOnUninstall = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 12434 forceDeleteOnUninstall = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
12483 break; 12435 break;
12484 case "Key": 12436 case "Key":
12485 key = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12437 key = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12486 if (null != parentKey) 12438 if (null != parentKey)
12487 { 12439 {
12488 key = Path.Combine(parentKey, key); 12440 key = Path.Combine(parentKey, key);
@@ -12491,19 +12443,19 @@ namespace WixToolset
12491 case "Root": 12443 case "Root":
12492 if (CompilerConstants.IntegerNotSet != root) 12444 if (CompilerConstants.IntegerNotSet != root)
12493 { 12445 {
12494 this.core.OnMessage(WixErrors.RegistryRootInvalid(sourceLineNumbers)); 12446 this.Core.OnMessage(WixErrors.RegistryRootInvalid(sourceLineNumbers));
12495 } 12447 }
12496 12448
12497 root = this.core.GetAttributeMsidbRegistryRootValue(sourceLineNumbers, attrib, true); 12449 root = this.Core.GetAttributeMsidbRegistryRootValue(sourceLineNumbers, attrib, true);
12498 break; 12450 break;
12499 default: 12451 default:
12500 this.core.UnexpectedAttribute(node, attrib); 12452 this.Core.UnexpectedAttribute(node, attrib);
12501 break; 12453 break;
12502 } 12454 }
12503 } 12455 }
12504 else 12456 else
12505 { 12457 {
12506 this.core.ParseExtensionAttribute(node, attrib); 12458 this.Core.ParseExtensionAttribute(node, attrib);
12507 } 12459 }
12508 } 12460 }
12509 12461
@@ -12514,26 +12466,26 @@ namespace WixToolset
12514 // generate the identifier if it wasn't provided 12466 // generate the identifier if it wasn't provided
12515 if (null == id) 12467 if (null == id)
12516 { 12468 {
12517 id = this.core.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), LowercaseOrNull(key), LowercaseOrNull(name)); 12469 id = this.Core.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), LowercaseOrNull(key), LowercaseOrNull(name));
12518 } 12470 }
12519 } 12471 }
12520 else // does not generate a Registry row, so no Id should be present 12472 else // does not generate a Registry row, so no Id should be present
12521 { 12473 {
12522 if (null != id) 12474 if (null != id)
12523 { 12475 {
12524 this.core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "Id", "ForceCreateOnInstall", "ForceDeleteOnUninstall", "yes", true)); 12476 this.Core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "Id", "ForceCreateOnInstall", "ForceDeleteOnUninstall", "yes", true));
12525 } 12477 }
12526 } 12478 }
12527 12479
12528 if (CompilerConstants.IntegerNotSet == root) 12480 if (CompilerConstants.IntegerNotSet == root)
12529 { 12481 {
12530 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root")); 12482 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root"));
12531 root = CompilerConstants.IllegalInteger; 12483 root = CompilerConstants.IllegalInteger;
12532 } 12484 }
12533 12485
12534 if (null == key) 12486 if (null == key)
12535 { 12487 {
12536 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); 12488 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
12537 key = String.Empty; // set the key to something to prevent null reference exceptions 12489 key = String.Empty; // set the key to something to prevent null reference exceptions
12538 } 12490 }
12539 12491
@@ -12550,7 +12502,7 @@ namespace WixToolset
12550 { 12502 {
12551 if (YesNoType.Yes == keyPath) 12503 if (YesNoType.Yes == keyPath)
12552 { 12504 {
12553 this.core.OnMessage(WixErrors.ComponentMultipleKeyPaths(sourceLineNumbers, child.Name.LocalName, "KeyPath", "yes", "File", "RegistryValue", "ODBCDataSource")); 12505 this.Core.OnMessage(WixErrors.ComponentMultipleKeyPaths(sourceLineNumbers, child.Name.LocalName, "KeyPath", "yes", "File", "RegistryValue", "ODBCDataSource"));
12554 } 12506 }
12555 12507
12556 possibleKeyPath = possibleChildKeyPath; // the child is the key path 12508 possibleKeyPath = possibleChildKeyPath; // the child is the key path
@@ -12566,7 +12518,7 @@ namespace WixToolset
12566 { 12518 {
12567 if (YesNoType.Yes == keyPath) 12519 if (YesNoType.Yes == keyPath)
12568 { 12520 {
12569 this.core.OnMessage(WixErrors.ComponentMultipleKeyPaths(sourceLineNumbers, child.Name.LocalName, "KeyPath", "yes", "File", "RegistryValue", "ODBCDataSource")); 12521 this.Core.OnMessage(WixErrors.ComponentMultipleKeyPaths(sourceLineNumbers, child.Name.LocalName, "KeyPath", "yes", "File", "RegistryValue", "ODBCDataSource"));
12570 } 12522 }
12571 12523
12572 possibleKeyPath = possibleChildKeyPath; // the child is the key path 12524 possibleKeyPath = possibleChildKeyPath; // the child is the key path
@@ -12580,38 +12532,38 @@ namespace WixToolset
12580 case "Permission": 12532 case "Permission":
12581 if (!forceCreateOnInstall) 12533 if (!forceCreateOnInstall)
12582 { 12534 {
12583 this.core.OnMessage(WixErrors.UnexpectedElementWithAttributeValue(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, "ForceCreateOnInstall", "yes")); 12535 this.Core.OnMessage(WixErrors.UnexpectedElementWithAttributeValue(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, "ForceCreateOnInstall", "yes"));
12584 } 12536 }
12585 this.ParsePermissionElement(child, id.Id, "Registry"); 12537 this.ParsePermissionElement(child, id.Id, "Registry");
12586 break; 12538 break;
12587 case "PermissionEx": 12539 case "PermissionEx":
12588 if (!forceCreateOnInstall) 12540 if (!forceCreateOnInstall)
12589 { 12541 {
12590 this.core.OnMessage(WixErrors.UnexpectedElementWithAttributeValue(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, "ForceCreateOnInstall", "yes")); 12542 this.Core.OnMessage(WixErrors.UnexpectedElementWithAttributeValue(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, "ForceCreateOnInstall", "yes"));
12591 } 12543 }
12592 this.ParsePermissionExElement(child, id.Id, "Registry"); 12544 this.ParsePermissionExElement(child, id.Id, "Registry");
12593 break; 12545 break;
12594 default: 12546 default:
12595 this.core.UnexpectedElement(node, child); 12547 this.Core.UnexpectedElement(node, child);
12596 break; 12548 break;
12597 } 12549 }
12598 } 12550 }
12599 else 12551 else
12600 { 12552 {
12601 Dictionary<string, string> context = new Dictionary<string, string>() { { "RegistryId", id.Id }, { "ComponentId", componentId }, { "Win64", win64Component.ToString() } }; 12553 Dictionary<string, string> context = new Dictionary<string, string>() { { "RegistryId", id.Id }, { "ComponentId", componentId }, { "Win64", win64Component.ToString() } };
12602 this.core.ParseExtensionElement(node, child, context); 12554 this.Core.ParseExtensionElement(node, child, context);
12603 } 12555 }
12604 } 12556 }
12605 12557
12606 12558
12607 if (!this.core.EncounteredError && null != name) 12559 if (!this.Core.EncounteredError && null != name)
12608 { 12560 {
12609 Row row = this.core.CreateRow(sourceLineNumbers, "Registry", id); 12561 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Registry, id);
12610 row[1] = root; 12562 row.Set(1, root);
12611 row[2] = key; 12563 row.Set(2, key);
12612 row[3] = name; 12564 row.Set(3, name);
12613 row[4] = null; 12565 row.Set(4, null);
12614 row[5] = componentId; 12566 row.Set(5, componentId);
12615 } 12567 }
12616 12568
12617 return keyPath; 12569 return keyPath;
@@ -12653,20 +12605,20 @@ namespace WixToolset
12653 switch (attrib.Name.LocalName) 12605 switch (attrib.Name.LocalName)
12654 { 12606 {
12655 case "Id": 12607 case "Id":
12656 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 12608 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
12657 break; 12609 break;
12658 case "Action": 12610 case "Action":
12659 action = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12611 action = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12660 if (0 < action.Length) 12612 if (0 < action.Length)
12661 { 12613 {
12662 if (!Wix.RegistryValue.TryParseActionType(action, out actionType)) 12614 if (!Wix.RegistryValue.TryParseActionType(action, out actionType))
12663 { 12615 {
12664 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, action, "append", "prepend", "write")); 12616 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, action, "append", "prepend", "write"));
12665 } 12617 }
12666 } 12618 }
12667 break; 12619 break;
12668 case "Key": 12620 case "Key":
12669 key = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12621 key = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12670 if (null != parentKey) 12622 if (null != parentKey)
12671 { 12623 {
12672 if (parentKey.EndsWith("\\", StringComparison.Ordinal)) 12624 if (parentKey.EndsWith("\\", StringComparison.Ordinal))
@@ -12680,68 +12632,68 @@ namespace WixToolset
12680 } 12632 }
12681 break; 12633 break;
12682 case "KeyPath": 12634 case "KeyPath":
12683 keyPath = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 12635 keyPath = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
12684 break; 12636 break;
12685 case "Name": 12637 case "Name":
12686 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12638 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12687 break; 12639 break;
12688 case "Root": 12640 case "Root":
12689 if (CompilerConstants.IntegerNotSet != root) 12641 if (CompilerConstants.IntegerNotSet != root)
12690 { 12642 {
12691 this.core.OnMessage(WixErrors.RegistryRootInvalid(sourceLineNumbers)); 12643 this.Core.OnMessage(WixErrors.RegistryRootInvalid(sourceLineNumbers));
12692 } 12644 }
12693 12645
12694 root = this.core.GetAttributeMsidbRegistryRootValue(sourceLineNumbers, attrib, true); 12646 root = this.Core.GetAttributeMsidbRegistryRootValue(sourceLineNumbers, attrib, true);
12695 break; 12647 break;
12696 case "Type": 12648 case "Type":
12697 type = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12649 type = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12698 if (0 < type.Length) 12650 if (0 < type.Length)
12699 { 12651 {
12700 if (!Wix.RegistryValue.TryParseTypeType(type, out typeType)) 12652 if (!Wix.RegistryValue.TryParseTypeType(type, out typeType))
12701 { 12653 {
12702 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, type, "binary", "expandable", "integer", "multiString", "string")); 12654 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, type, "binary", "expandable", "integer", "multiString", "string"));
12703 } 12655 }
12704 } 12656 }
12705 break; 12657 break;
12706 case "Value": 12658 case "Value":
12707 value = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 12659 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
12708 break; 12660 break;
12709 default: 12661 default:
12710 this.core.UnexpectedAttribute(node, attrib); 12662 this.Core.UnexpectedAttribute(node, attrib);
12711 break; 12663 break;
12712 } 12664 }
12713 } 12665 }
12714 else 12666 else
12715 { 12667 {
12716 this.core.ParseExtensionAttribute(node, attrib); 12668 this.Core.ParseExtensionAttribute(node, attrib);
12717 } 12669 }
12718 } 12670 }
12719 12671
12720 // generate the identifier if it wasn't provided 12672 // generate the identifier if it wasn't provided
12721 if (null == id) 12673 if (null == id)
12722 { 12674 {
12723 id = this.core.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), LowercaseOrNull(key), LowercaseOrNull(name)); 12675 id = this.Core.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), LowercaseOrNull(key), LowercaseOrNull(name));
12724 } 12676 }
12725 12677
12726 if ((Wix.RegistryValue.ActionType.append == actionType || Wix.RegistryValue.ActionType.prepend == actionType) && 12678 if ((Wix.RegistryValue.ActionType.append == actionType || Wix.RegistryValue.ActionType.prepend == actionType) &&
12727 Wix.RegistryValue.TypeType.multiString != typeType) 12679 Wix.RegistryValue.TypeType.multiString != typeType)
12728 { 12680 {
12729 this.core.OnMessage(WixErrors.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Action", action, "Type", "multiString")); 12681 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Action", action, "Type", "multiString"));
12730 } 12682 }
12731 12683
12732 if (null == key) 12684 if (null == key)
12733 { 12685 {
12734 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); 12686 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
12735 } 12687 }
12736 12688
12737 if (CompilerConstants.IntegerNotSet == root) 12689 if (CompilerConstants.IntegerNotSet == root)
12738 { 12690 {
12739 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root")); 12691 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root"));
12740 } 12692 }
12741 12693
12742 if (null == type) 12694 if (null == type)
12743 { 12695 {
12744 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type")); 12696 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type"));
12745 } 12697 }
12746 12698
12747 foreach (XElement child in node.Elements()) 12699 foreach (XElement child in node.Elements())
@@ -12753,7 +12705,7 @@ namespace WixToolset
12753 case "MultiStringValue": 12705 case "MultiStringValue":
12754 if (Wix.RegistryValue.TypeType.multiString != typeType && null != value) 12706 if (Wix.RegistryValue.TypeType.multiString != typeType && null != value)
12755 { 12707 {
12756 this.core.OnMessage(WixErrors.RegistryMultipleValuesWithoutMultiString(sourceLineNumbers, node.Name.LocalName, "Value", child.Name.LocalName, "Type")); 12708 this.Core.OnMessage(WixErrors.RegistryMultipleValuesWithoutMultiString(sourceLineNumbers, node.Name.LocalName, "Value", child.Name.LocalName, "Type"));
12757 } 12709 }
12758 else if (null == value) 12710 else if (null == value)
12759 { 12711 {
@@ -12771,14 +12723,14 @@ namespace WixToolset
12771 this.ParsePermissionExElement(child, id.Id, "Registry"); 12723 this.ParsePermissionExElement(child, id.Id, "Registry");
12772 break; 12724 break;
12773 default: 12725 default:
12774 this.core.UnexpectedElement(node, child); 12726 this.Core.UnexpectedElement(node, child);
12775 break; 12727 break;
12776 } 12728 }
12777 } 12729 }
12778 else 12730 else
12779 { 12731 {
12780 Dictionary<string, string> context = new Dictionary<string, string>() { { "RegistryId", id.Id }, { "ComponentId", componentId }, { "Win64", win64Component.ToString() } }; 12732 Dictionary<string, string> context = new Dictionary<string, string>() { { "RegistryId", id.Id }, { "ComponentId", componentId }, { "Win64", win64Component.ToString() } };
12781 this.core.ParseExtensionElement(node, child, context); 12733 this.Core.ParseExtensionElement(node, child, context);
12782 } 12734 }
12783 } 12735 }
12784 12736
@@ -12824,21 +12776,21 @@ namespace WixToolset
12824 // value may be set by child MultiStringValue elements, so it must be checked here 12776 // value may be set by child MultiStringValue elements, so it must be checked here
12825 if (null == value) 12777 if (null == value)
12826 { 12778 {
12827 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 12779 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
12828 } 12780 }
12829 else if (0 == value.Length && ("+" == name || "-" == name || "*" == name)) // prevent accidental authoring of special name values 12781 else if (0 == value.Length && ("+" == name || "-" == name || "*" == name)) // prevent accidental authoring of special name values
12830 { 12782 {
12831 this.core.OnMessage(WixErrors.RegistryNameValueIncorrect(sourceLineNumbers, node.Name.LocalName, "Name", name)); 12783 this.Core.OnMessage(WixErrors.RegistryNameValueIncorrect(sourceLineNumbers, node.Name.LocalName, "Name", name));
12832 } 12784 }
12833 12785
12834 if (!this.core.EncounteredError) 12786 if (!this.Core.EncounteredError)
12835 { 12787 {
12836 Row row = this.core.CreateRow(sourceLineNumbers, "Registry", id); 12788 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Registry, id);
12837 row[1] = root; 12789 row.Set(1, root);
12838 row[2] = key; 12790 row.Set(2, key);
12839 row[3] = name; 12791 row.Set(3, name);
12840 row[4] = value; 12792 row.Set(4, value);
12841 row[5] = componentId; 12793 row.Set(5, componentId);
12842 } 12794 }
12843 12795
12844 // If this was just a regular registry key (that could be the key path) 12796 // If this was just a regular registry key (that could be the key path)
@@ -12877,72 +12829,72 @@ namespace WixToolset
12877 switch (attrib.Name.LocalName) 12829 switch (attrib.Name.LocalName)
12878 { 12830 {
12879 case "Id": 12831 case "Id":
12880 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 12832 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
12881 break; 12833 break;
12882 case "Action": 12834 case "Action":
12883 action = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12835 action = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12884 if (0 < action.Length) 12836 if (0 < action.Length)
12885 { 12837 {
12886 if (!Wix.RemoveRegistryKey.TryParseActionType(action, out actionType)) 12838 if (!Wix.RemoveRegistryKey.TryParseActionType(action, out actionType))
12887 { 12839 {
12888 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, action, "removeOnInstall", "removeOnUninstall")); 12840 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, action, "removeOnInstall", "removeOnUninstall"));
12889 } 12841 }
12890 } 12842 }
12891 break; 12843 break;
12892 case "Key": 12844 case "Key":
12893 key = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12845 key = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12894 break; 12846 break;
12895 case "Root": 12847 case "Root":
12896 root = this.core.GetAttributeMsidbRegistryRootValue(sourceLineNumbers, attrib, true); 12848 root = this.Core.GetAttributeMsidbRegistryRootValue(sourceLineNumbers, attrib, true);
12897 break; 12849 break;
12898 default: 12850 default:
12899 this.core.UnexpectedAttribute(node, attrib); 12851 this.Core.UnexpectedAttribute(node, attrib);
12900 break; 12852 break;
12901 } 12853 }
12902 } 12854 }
12903 else 12855 else
12904 { 12856 {
12905 this.core.ParseExtensionAttribute(node, attrib); 12857 this.Core.ParseExtensionAttribute(node, attrib);
12906 } 12858 }
12907 } 12859 }
12908 12860
12909 // generate the identifier if it wasn't provided 12861 // generate the identifier if it wasn't provided
12910 if (null == id) 12862 if (null == id)
12911 { 12863 {
12912 id = this.core.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), LowercaseOrNull(key), LowercaseOrNull(name)); 12864 id = this.Core.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), LowercaseOrNull(key), LowercaseOrNull(name));
12913 } 12865 }
12914 12866
12915 if (null == action) 12867 if (null == action)
12916 { 12868 {
12917 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Action")); 12869 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Action"));
12918 } 12870 }
12919 12871
12920 if (null == key) 12872 if (null == key)
12921 { 12873 {
12922 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); 12874 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
12923 } 12875 }
12924 12876
12925 if (CompilerConstants.IntegerNotSet == root) 12877 if (CompilerConstants.IntegerNotSet == root)
12926 { 12878 {
12927 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root")); 12879 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root"));
12928 } 12880 }
12929 12881
12930 this.core.ParseForExtensionElements(node); 12882 this.Core.ParseForExtensionElements(node);
12931 12883
12932 if (!this.core.EncounteredError) 12884 if (!this.Core.EncounteredError)
12933 { 12885 {
12934 Row row = this.core.CreateRow(sourceLineNumbers, (Wix.RemoveRegistryKey.ActionType.removeOnUninstall == actionType ? "Registry" : "RemoveRegistry"), id); 12886 var row = this.Core.CreateRow(sourceLineNumbers, (Wix.RemoveRegistryKey.ActionType.removeOnUninstall == actionType ? TupleDefinitionType.Registry : TupleDefinitionType.RemoveRegistry), id);
12935 row[1] = root; 12887 row.Set(1, root);
12936 row[2] = key; 12888 row.Set(2, key);
12937 row[3] = name; 12889 row.Set(3, name);
12938 if (Wix.RemoveRegistryKey.ActionType.removeOnUninstall == actionType) // Registry table 12890 if (Wix.RemoveRegistryKey.ActionType.removeOnUninstall == actionType) // Registry table
12939 { 12891 {
12940 row[4] = null; 12892 row.Set(4, null);
12941 row[5] = componentId; 12893 row.Set(5, componentId);
12942 } 12894 }
12943 else // RemoveRegistry table 12895 else // RemoveRegistry table
12944 { 12896 {
12945 row[4] = componentId; 12897 row.Set(4, componentId);
12946 } 12898 }
12947 } 12899 }
12948 } 12900 }
@@ -12970,53 +12922,53 @@ namespace WixToolset
12970 switch (attrib.Name.LocalName) 12922 switch (attrib.Name.LocalName)
12971 { 12923 {
12972 case "Id": 12924 case "Id":
12973 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 12925 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
12974 break; 12926 break;
12975 case "Key": 12927 case "Key":
12976 key = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12928 key = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12977 break; 12929 break;
12978 case "Name": 12930 case "Name":
12979 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 12931 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
12980 break; 12932 break;
12981 case "Root": 12933 case "Root":
12982 root = this.core.GetAttributeMsidbRegistryRootValue(sourceLineNumbers, attrib, true); 12934 root = this.Core.GetAttributeMsidbRegistryRootValue(sourceLineNumbers, attrib, true);
12983 break; 12935 break;
12984 default: 12936 default:
12985 this.core.UnexpectedAttribute(node, attrib); 12937 this.Core.UnexpectedAttribute(node, attrib);
12986 break; 12938 break;
12987 } 12939 }
12988 } 12940 }
12989 else 12941 else
12990 { 12942 {
12991 this.core.ParseExtensionAttribute(node, attrib); 12943 this.Core.ParseExtensionAttribute(node, attrib);
12992 } 12944 }
12993 } 12945 }
12994 12946
12995 // generate the identifier if it wasn't provided 12947 // generate the identifier if it wasn't provided
12996 if (null == id) 12948 if (null == id)
12997 { 12949 {
12998 id = this.core.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), LowercaseOrNull(key), LowercaseOrNull(name)); 12950 id = this.Core.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), LowercaseOrNull(key), LowercaseOrNull(name));
12999 } 12951 }
13000 12952
13001 if (null == key) 12953 if (null == key)
13002 { 12954 {
13003 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); 12955 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
13004 } 12956 }
13005 12957
13006 if (CompilerConstants.IntegerNotSet == root) 12958 if (CompilerConstants.IntegerNotSet == root)
13007 { 12959 {
13008 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root")); 12960 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root"));
13009 } 12961 }
13010 12962
13011 this.core.ParseForExtensionElements(node); 12963 this.Core.ParseForExtensionElements(node);
13012 12964
13013 if (!this.core.EncounteredError) 12965 if (!this.Core.EncounteredError)
13014 { 12966 {
13015 Row row = this.core.CreateRow(sourceLineNumbers, "RemoveRegistry", id); 12967 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RemoveRegistry, id);
13016 row[1] = root; 12968 row.Set(1, root);
13017 row[2] = key; 12969 row.Set(2, key);
13018 row[3] = name; 12970 row.Set(3, name);
13019 row[4] = componentId; 12971 row.Set(4, componentId);
13020 } 12972 }
13021 } 12973 }
13022 12974
@@ -13043,16 +12995,16 @@ namespace WixToolset
13043 switch (attrib.Name.LocalName) 12995 switch (attrib.Name.LocalName)
13044 { 12996 {
13045 case "Id": 12997 case "Id":
13046 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 12998 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
13047 break; 12999 break;
13048 case "Directory": 13000 case "Directory":
13049 directory = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, parentDirectory); 13001 directory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, parentDirectory);
13050 break; 13002 break;
13051 case "Name": 13003 case "Name":
13052 name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, true); 13004 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, true);
13053 break; 13005 break;
13054 case "On": 13006 case "On":
13055 Wix.InstallUninstallType onValue = this.core.GetAttributeInstallUninstallValue(sourceLineNumbers, attrib); 13007 Wix.InstallUninstallType onValue = this.Core.GetAttributeInstallUninstallValue(sourceLineNumbers, attrib);
13056 switch (onValue) 13008 switch (onValue)
13057 { 13009 {
13058 case Wix.InstallUninstallType.install: 13010 case Wix.InstallUninstallType.install:
@@ -13070,29 +13022,29 @@ namespace WixToolset
13070 } 13022 }
13071 break; 13023 break;
13072 case "Property": 13024 case "Property":
13073 property = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 13025 property = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
13074 break; 13026 break;
13075 case "ShortName": 13027 case "ShortName":
13076 shortName = this.core.GetAttributeShortFilename(sourceLineNumbers, attrib, true); 13028 shortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, true);
13077 break; 13029 break;
13078 default: 13030 default:
13079 this.core.UnexpectedAttribute(node, attrib); 13031 this.Core.UnexpectedAttribute(node, attrib);
13080 break; 13032 break;
13081 } 13033 }
13082 } 13034 }
13083 else 13035 else
13084 { 13036 {
13085 this.core.ParseExtensionAttribute(node, attrib); 13037 this.Core.ParseExtensionAttribute(node, attrib);
13086 } 13038 }
13087 } 13039 }
13088 13040
13089 if (null == name) 13041 if (null == name)
13090 { 13042 {
13091 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 13043 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
13092 } 13044 }
13093 else if (0 < name.Length) 13045 else if (0 < name.Length)
13094 { 13046 {
13095 if (this.core.IsValidShortFilename(name, true)) 13047 if (this.Core.IsValidShortFilename(name, true))
13096 { 13048 {
13097 if (null == shortName) 13049 if (null == shortName)
13098 { 13050 {
@@ -13101,51 +13053,51 @@ namespace WixToolset
13101 } 13053 }
13102 else 13054 else
13103 { 13055 {
13104 this.core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", name, "ShortName")); 13056 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", name, "ShortName"));
13105 } 13057 }
13106 } 13058 }
13107 else if (null == shortName) // generate a short file name. 13059 else if (null == shortName) // generate a short file name.
13108 { 13060 {
13109 shortName = this.core.CreateShortName(name, true, true, node.Name.LocalName, componentId); 13061 shortName = this.Core.CreateShortName(name, true, true, node.Name.LocalName, componentId);
13110 } 13062 }
13111 } 13063 }
13112 13064
13113 if (CompilerConstants.IntegerNotSet == on) 13065 if (CompilerConstants.IntegerNotSet == on)
13114 { 13066 {
13115 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On")); 13067 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On"));
13116 on = CompilerConstants.IllegalInteger; 13068 on = CompilerConstants.IllegalInteger;
13117 } 13069 }
13118 13070
13119 if (null != directory && null != property) 13071 if (null != directory && null != property)
13120 { 13072 {
13121 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "Directory", directory)); 13073 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "Directory", directory));
13122 } 13074 }
13123 13075
13124 if (null == id) 13076 if (null == id)
13125 { 13077 {
13126 id = this.core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, LowercaseOrNull(shortName), LowercaseOrNull(name), on.ToString()); 13078 id = this.Core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, LowercaseOrNull(shortName), LowercaseOrNull(name), on.ToString());
13127 } 13079 }
13128 13080
13129 this.core.ParseForExtensionElements(node); 13081 this.Core.ParseForExtensionElements(node);
13130 13082
13131 if (!this.core.EncounteredError) 13083 if (!this.Core.EncounteredError)
13132 { 13084 {
13133 Row row = this.core.CreateRow(sourceLineNumbers, "RemoveFile", id); 13085 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RemoveFile, id);
13134 row[1] = componentId; 13086 row.Set(1, componentId);
13135 row[2] = GetMsiFilenameValue(shortName, name); 13087 row.Set(2, GetMsiFilenameValue(shortName, name));
13136 if (null != directory) 13088 if (null != directory)
13137 { 13089 {
13138 row[3] = directory; 13090 row.Set(3, directory);
13139 } 13091 }
13140 else if (null != property) 13092 else if (null != property)
13141 { 13093 {
13142 row[3] = property; 13094 row.Set(3, property);
13143 } 13095 }
13144 else 13096 else
13145 { 13097 {
13146 row[3] = parentDirectory; 13098 row.Set(3, parentDirectory);
13147 } 13099 }
13148 row[4] = on; 13100 row.Set(4, on);
13149 } 13101 }
13150 } 13102 }
13151 13103
@@ -13170,13 +13122,13 @@ namespace WixToolset
13170 switch (attrib.Name.LocalName) 13122 switch (attrib.Name.LocalName)
13171 { 13123 {
13172 case "Id": 13124 case "Id":
13173 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 13125 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
13174 break; 13126 break;
13175 case "Directory": 13127 case "Directory":
13176 directory = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, parentDirectory); 13128 directory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, parentDirectory);
13177 break; 13129 break;
13178 case "On": 13130 case "On":
13179 Wix.InstallUninstallType onValue = this.core.GetAttributeInstallUninstallValue(sourceLineNumbers, attrib); 13131 Wix.InstallUninstallType onValue = this.Core.GetAttributeInstallUninstallValue(sourceLineNumbers, attrib);
13180 switch (onValue) 13132 switch (onValue)
13181 { 13133 {
13182 case Wix.InstallUninstallType.install: 13134 case Wix.InstallUninstallType.install:
@@ -13194,55 +13146,55 @@ namespace WixToolset
13194 } 13146 }
13195 break; 13147 break;
13196 case "Property": 13148 case "Property":
13197 property = this.core.GetAttributeValue(sourceLineNumbers, attrib); 13149 property = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
13198 break; 13150 break;
13199 default: 13151 default:
13200 this.core.UnexpectedAttribute(node, attrib); 13152 this.Core.UnexpectedAttribute(node, attrib);
13201 break; 13153 break;
13202 } 13154 }
13203 } 13155 }
13204 else 13156 else
13205 { 13157 {
13206 this.core.ParseExtensionAttribute(node, attrib); 13158 this.Core.ParseExtensionAttribute(node, attrib);
13207 } 13159 }
13208 } 13160 }
13209 13161
13210 if (CompilerConstants.IntegerNotSet == on) 13162 if (CompilerConstants.IntegerNotSet == on)
13211 { 13163 {
13212 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On")); 13164 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On"));
13213 on = CompilerConstants.IllegalInteger; 13165 on = CompilerConstants.IllegalInteger;
13214 } 13166 }
13215 13167
13216 if (null != directory && null != property) 13168 if (null != directory && null != property)
13217 { 13169 {
13218 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "Directory", directory)); 13170 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "Directory", directory));
13219 } 13171 }
13220 13172
13221 if (null == id) 13173 if (null == id)
13222 { 13174 {
13223 id = this.core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, on.ToString()); 13175 id = this.Core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, on.ToString());
13224 } 13176 }
13225 13177
13226 this.core.ParseForExtensionElements(node); 13178 this.Core.ParseForExtensionElements(node);
13227 13179
13228 if (!this.core.EncounteredError) 13180 if (!this.Core.EncounteredError)
13229 { 13181 {
13230 Row row = this.core.CreateRow(sourceLineNumbers, "RemoveFile", id); 13182 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RemoveFile, id);
13231 row[1] = componentId; 13183 row.Set(1, componentId);
13232 row[2] = null; 13184 row.Set(2, null);
13233 if (null != directory) 13185 if (null != directory)
13234 { 13186 {
13235 row[3] = directory; 13187 row.Set(3, directory);
13236 } 13188 }
13237 else if (null != property) 13189 else if (null != property)
13238 { 13190 {
13239 row[3] = property; 13191 row.Set(3, property);
13240 } 13192 }
13241 else 13193 else
13242 { 13194 {
13243 row[3] = parentDirectory; 13195 row.Set(3, parentDirectory);
13244 } 13196 }
13245 row[4] = on; 13197 row.Set(4, on);
13246 } 13198 }
13247 } 13199 }
13248 13200
@@ -13266,52 +13218,52 @@ namespace WixToolset
13266 switch (attrib.Name.LocalName) 13218 switch (attrib.Name.LocalName)
13267 { 13219 {
13268 case "Id": 13220 case "Id":
13269 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 13221 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
13270 break; 13222 break;
13271 case "Directory": 13223 case "Directory":
13272 directoryId = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, directoryId); 13224 directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, directoryId);
13273 break; 13225 break;
13274 case "RunFromSource": 13226 case "RunFromSource":
13275 runFromSource = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 13227 runFromSource = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
13276 break; 13228 break;
13277 case "RunLocal": 13229 case "RunLocal":
13278 runLocal = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 13230 runLocal = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
13279 break; 13231 break;
13280 default: 13232 default:
13281 this.core.UnexpectedAttribute(node, attrib); 13233 this.Core.UnexpectedAttribute(node, attrib);
13282 break; 13234 break;
13283 } 13235 }
13284 } 13236 }
13285 else 13237 else
13286 { 13238 {
13287 this.core.ParseExtensionAttribute(node, attrib); 13239 this.Core.ParseExtensionAttribute(node, attrib);
13288 } 13240 }
13289 } 13241 }
13290 13242
13291 if (null == id) 13243 if (null == id)
13292 { 13244 {
13293 id = this.core.CreateIdentifier("rc", componentId, directoryId); 13245 id = this.Core.CreateIdentifier("rc", componentId, directoryId);
13294 } 13246 }
13295 13247
13296 if (CompilerConstants.IntegerNotSet == runFromSource) 13248 if (CompilerConstants.IntegerNotSet == runFromSource)
13297 { 13249 {
13298 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "RunFromSource")); 13250 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "RunFromSource"));
13299 } 13251 }
13300 13252
13301 if (CompilerConstants.IntegerNotSet == runLocal) 13253 if (CompilerConstants.IntegerNotSet == runLocal)
13302 { 13254 {
13303 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "RunLocal")); 13255 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "RunLocal"));
13304 } 13256 }
13305 13257
13306 this.core.ParseForExtensionElements(node); 13258 this.Core.ParseForExtensionElements(node);
13307 13259
13308 if (!this.core.EncounteredError) 13260 if (!this.Core.EncounteredError)
13309 { 13261 {
13310 Row row = this.core.CreateRow(sourceLineNumbers, "ReserveCost", id); 13262 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ReserveCost, id);
13311 row[1] = componentId; 13263 row.Set(1, componentId);
13312 row[2] = directoryId; 13264 row.Set(2, directoryId);
13313 row[3] = runLocal; 13265 row.Set(3, runLocal);
13314 row[4] = runFromSource; 13266 row.Set(4, runFromSource);
13315 } 13267 }
13316 } 13268 }
13317 13269
@@ -13354,51 +13306,51 @@ namespace WixToolset
13354 case "Action": 13306 case "Action":
13355 if (customAction) 13307 if (customAction)
13356 { 13308 {
13357 actionName = this.core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib); 13309 actionName = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib);
13358 this.core.CreateSimpleReference(childSourceLineNumbers, "CustomAction", actionName); 13310 this.Core.CreateSimpleReference(childSourceLineNumbers, "CustomAction", actionName);
13359 } 13311 }
13360 else 13312 else
13361 { 13313 {
13362 this.core.UnexpectedAttribute(child, attrib); 13314 this.Core.UnexpectedAttribute(child, attrib);
13363 } 13315 }
13364 break; 13316 break;
13365 case "After": 13317 case "After":
13366 if (customAction || showDialog || specialAction || specialStandardAction) 13318 if (customAction || showDialog || specialAction || specialStandardAction)
13367 { 13319 {
13368 afterAction = this.core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib); 13320 afterAction = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib);
13369 this.core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable, afterAction); 13321 this.Core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable, afterAction);
13370 } 13322 }
13371 else 13323 else
13372 { 13324 {
13373 this.core.UnexpectedAttribute(child, attrib); 13325 this.Core.UnexpectedAttribute(child, attrib);
13374 } 13326 }
13375 break; 13327 break;
13376 case "Before": 13328 case "Before":
13377 if (customAction || showDialog || specialAction || specialStandardAction) 13329 if (customAction || showDialog || specialAction || specialStandardAction)
13378 { 13330 {
13379 beforeAction = this.core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib); 13331 beforeAction = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib);
13380 this.core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable, beforeAction); 13332 this.Core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable, beforeAction);
13381 } 13333 }
13382 else 13334 else
13383 { 13335 {
13384 this.core.UnexpectedAttribute(child, attrib); 13336 this.Core.UnexpectedAttribute(child, attrib);
13385 } 13337 }
13386 break; 13338 break;
13387 case "Dialog": 13339 case "Dialog":
13388 if (showDialog) 13340 if (showDialog)
13389 { 13341 {
13390 actionName = this.core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib); 13342 actionName = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib);
13391 this.core.CreateSimpleReference(childSourceLineNumbers, "Dialog", actionName); 13343 this.Core.CreateSimpleReference(childSourceLineNumbers, "Dialog", actionName);
13392 } 13344 }
13393 else 13345 else
13394 { 13346 {
13395 this.core.UnexpectedAttribute(child, attrib); 13347 this.Core.UnexpectedAttribute(child, attrib);
13396 } 13348 }
13397 break; 13349 break;
13398 case "OnExit": 13350 case "OnExit":
13399 if (customAction || showDialog || specialAction) 13351 if (customAction || showDialog || specialAction)
13400 { 13352 {
13401 Wix.ExitType exitValue = this.core.GetAttributeExitValue(childSourceLineNumbers, attrib); 13353 Wix.ExitType exitValue = this.Core.GetAttributeExitValue(childSourceLineNumbers, attrib);
13402 switch (exitValue) 13354 switch (exitValue)
13403 { 13355 {
13404 case Wix.ExitType.success: 13356 case Wix.ExitType.success:
@@ -13417,51 +13369,51 @@ namespace WixToolset
13417 } 13369 }
13418 else 13370 else
13419 { 13371 {
13420 this.core.UnexpectedAttribute(child, attrib); 13372 this.Core.UnexpectedAttribute(child, attrib);
13421 } 13373 }
13422 break; 13374 break;
13423 case "Overridable": 13375 case "Overridable":
13424 overridable = YesNoType.Yes == this.core.GetAttributeYesNoValue(childSourceLineNumbers, attrib); 13376 overridable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, attrib);
13425 break; 13377 break;
13426 case "Sequence": 13378 case "Sequence":
13427 sequence = this.core.GetAttributeIntegerValue(childSourceLineNumbers, attrib, 1, short.MaxValue); 13379 sequence = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, attrib, 1, short.MaxValue);
13428 break; 13380 break;
13429 case "Suppress": 13381 case "Suppress":
13430 suppress = YesNoType.Yes == this.core.GetAttributeYesNoValue(childSourceLineNumbers, attrib); 13382 suppress = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, attrib);
13431 break; 13383 break;
13432 default: 13384 default:
13433 this.core.UnexpectedAttribute(node, attrib); 13385 this.Core.UnexpectedAttribute(node, attrib);
13434 break; 13386 break;
13435 } 13387 }
13436 } 13388 }
13437 else 13389 else
13438 { 13390 {
13439 this.core.ParseExtensionAttribute(node, attrib); 13391 this.Core.ParseExtensionAttribute(node, attrib);
13440 } 13392 }
13441 } 13393 }
13442 13394
13443 13395
13444 // Get the condition from the inner text of the element. 13396 // Get the condition from the inner text of the element.
13445 condition = this.core.GetConditionInnerText(child); 13397 condition = this.Core.GetConditionInnerText(child);
13446 13398
13447 if (customAction && "Custom" == actionName) 13399 if (customAction && "Custom" == actionName)
13448 { 13400 {
13449 this.core.OnMessage(WixErrors.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Action")); 13401 this.Core.OnMessage(WixErrors.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Action"));
13450 } 13402 }
13451 else if (showDialog && "Show" == actionName) 13403 else if (showDialog && "Show" == actionName)
13452 { 13404 {
13453 this.core.OnMessage(WixErrors.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Dialog")); 13405 this.Core.OnMessage(WixErrors.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Dialog"));
13454 } 13406 }
13455 13407
13456 if (CompilerConstants.IntegerNotSet != sequence) 13408 if (CompilerConstants.IntegerNotSet != sequence)
13457 { 13409 {
13458 if (CompilerConstants.IntegerNotSet != exitSequence) 13410 if (CompilerConstants.IntegerNotSet != exitSequence)
13459 { 13411 {
13460 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(childSourceLineNumbers, child.Name.LocalName, "Sequence", "OnExit")); 13412 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(childSourceLineNumbers, child.Name.LocalName, "Sequence", "OnExit"));
13461 } 13413 }
13462 else if (null != beforeAction || null != afterAction) 13414 else if (null != beforeAction || null != afterAction)
13463 { 13415 {
13464 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(childSourceLineNumbers, child.Name.LocalName, "Sequence", "Before", "After")); 13416 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(childSourceLineNumbers, child.Name.LocalName, "Sequence", "Before", "After"));
13465 } 13417 }
13466 } 13418 }
13467 else // sequence not specified use OnExit (which may also be not set). 13419 else // sequence not specified use OnExit (which may also be not set).
@@ -13471,59 +13423,59 @@ namespace WixToolset
13471 13423
13472 if (null != beforeAction && null != afterAction) 13424 if (null != beforeAction && null != afterAction)
13473 { 13425 {
13474 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(childSourceLineNumbers, child.Name.LocalName, "After", "Before")); 13426 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(childSourceLineNumbers, child.Name.LocalName, "After", "Before"));
13475 } 13427 }
13476 else if ((customAction || showDialog || specialAction) && !suppress && CompilerConstants.IntegerNotSet == sequence && null == beforeAction && null == afterAction) 13428 else if ((customAction || showDialog || specialAction) && !suppress && CompilerConstants.IntegerNotSet == sequence && null == beforeAction && null == afterAction)
13477 { 13429 {
13478 this.core.OnMessage(WixErrors.NeedSequenceBeforeOrAfter(childSourceLineNumbers, child.Name.LocalName)); 13430 this.Core.OnMessage(WixErrors.NeedSequenceBeforeOrAfter(childSourceLineNumbers, child.Name.LocalName));
13479 } 13431 }
13480 13432
13481 // action that is scheduled to occur before/after itself 13433 // action that is scheduled to occur before/after itself
13482 if (beforeAction == actionName) 13434 if (beforeAction == actionName)
13483 { 13435 {
13484 this.core.OnMessage(WixErrors.ActionScheduledRelativeToItself(childSourceLineNumbers, child.Name.LocalName, "Before", beforeAction)); 13436 this.Core.OnMessage(WixErrors.ActionScheduledRelativeToItself(childSourceLineNumbers, child.Name.LocalName, "Before", beforeAction));
13485 } 13437 }
13486 else if (afterAction == actionName) 13438 else if (afterAction == actionName)
13487 { 13439 {
13488 this.core.OnMessage(WixErrors.ActionScheduledRelativeToItself(childSourceLineNumbers, child.Name.LocalName, "After", afterAction)); 13440 this.Core.OnMessage(WixErrors.ActionScheduledRelativeToItself(childSourceLineNumbers, child.Name.LocalName, "After", afterAction));
13489 } 13441 }
13490 13442
13491 // normal standard actions cannot be set overridable by the user (since they are overridable by default) 13443 // normal standard actions cannot be set overridable by the user (since they are overridable by default)
13492 if (overridable && WindowsInstallerStandard.IsStandardAction(actionName) && !specialAction) 13444 if (overridable && WindowsInstallerStandard.IsStandardAction(actionName) && !specialAction)
13493 { 13445 {
13494 this.core.OnMessage(WixErrors.UnexpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Overridable")); 13446 this.Core.OnMessage(WixErrors.UnexpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Overridable"));
13495 } 13447 }
13496 13448
13497 // suppress cannot be specified at the same time as Before, After, or Sequence 13449 // suppress cannot be specified at the same time as Before, After, or Sequence
13498 if (suppress && (null != afterAction || null != beforeAction || CompilerConstants.IntegerNotSet != sequence || overridable)) 13450 if (suppress && (null != afterAction || null != beforeAction || CompilerConstants.IntegerNotSet != sequence || overridable))
13499 { 13451 {
13500 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(childSourceLineNumbers, child.Name.LocalName, "Suppress", "Before", "After", "Sequence", "Overridable")); 13452 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(childSourceLineNumbers, child.Name.LocalName, "Suppress", "Before", "After", "Sequence", "Overridable"));
13501 } 13453 }
13502 13454
13503 this.core.ParseForExtensionElements(child); 13455 this.Core.ParseForExtensionElements(child);
13504 13456
13505 // add the row and any references needed 13457 // add the row and any references needed
13506 if (!this.core.EncounteredError) 13458 if (!this.Core.EncounteredError)
13507 { 13459 {
13508 if (suppress) 13460 if (suppress)
13509 { 13461 {
13510 Row row = this.core.CreateRow(childSourceLineNumbers, "WixSuppressAction"); 13462 var row = this.Core.CreateRow(childSourceLineNumbers, TupleDefinitionType.WixSuppressAction);
13511 row[0] = sequenceTable; 13463 row.Set(0, sequenceTable);
13512 row[1] = actionName; 13464 row.Set(1, actionName);
13513 } 13465 }
13514 else 13466 else
13515 { 13467 {
13516 Row row = this.core.CreateRow(childSourceLineNumbers, "WixAction"); 13468 var row = this.Core.CreateRow(childSourceLineNumbers, TupleDefinitionType.WixAction);
13517 row[0] = sequenceTable; 13469 row.Set(0, sequenceTable);
13518 row[1] = actionName; 13470 row.Set(1, actionName);
13519 row[2] = condition; 13471 row.Set(2, condition);
13520 if (CompilerConstants.IntegerNotSet != sequence) 13472 if (CompilerConstants.IntegerNotSet != sequence)
13521 { 13473 {
13522 row[3] = sequence; 13474 row.Set(3, sequence);
13523 } 13475 }
13524 row[4] = beforeAction; 13476 row.Set(4, beforeAction);
13525 row[5] = afterAction; 13477 row.Set(5, afterAction);
13526 row[6] = overridable ? 1 : 0; 13478 row.Set(6, overridable ? 1 : 0);
13527 } 13479 }
13528 } 13480 }
13529 } 13481 }
@@ -13548,7 +13500,7 @@ namespace WixToolset
13548 string requiredPrivileges = null; 13500 string requiredPrivileges = null;
13549 string sid = null; 13501 string sid = null;
13550 13502
13551 this.core.OnMessage(WixWarnings.ServiceConfigFamilyNotSupported(sourceLineNumbers, node.Name.LocalName)); 13503 this.Core.OnMessage(WixWarnings.ServiceConfigFamilyNotSupported(sourceLineNumbers, node.Name.LocalName));
13552 13504
13553 foreach (XAttribute attrib in node.Attributes()) 13505 foreach (XAttribute attrib in node.Attributes())
13554 { 13506 {
@@ -13557,10 +13509,10 @@ namespace WixToolset
13557 switch (attrib.Name.LocalName) 13509 switch (attrib.Name.LocalName)
13558 { 13510 {
13559 case "Id": 13511 case "Id":
13560 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 13512 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
13561 break; 13513 break;
13562 case "DelayedAutoStart": 13514 case "DelayedAutoStart":
13563 delayedAutoStart = this.core.GetAttributeValue(sourceLineNumbers, attrib); 13515 delayedAutoStart = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
13564 if (0 < delayedAutoStart.Length) 13516 if (0 < delayedAutoStart.Length)
13565 { 13517 {
13566 switch (delayedAutoStart) 13518 switch (delayedAutoStart)
@@ -13578,7 +13530,7 @@ namespace WixToolset
13578 } 13530 }
13579 break; 13531 break;
13580 case "FailureActionsWhen": 13532 case "FailureActionsWhen":
13581 failureActionsWhen = this.core.GetAttributeValue(sourceLineNumbers, attrib); 13533 failureActionsWhen = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
13582 if (0 < failureActionsWhen.Length) 13534 if (0 < failureActionsWhen.Length)
13583 { 13535 {
13584 switch (failureActionsWhen) 13536 switch (failureActionsWhen)
@@ -13596,42 +13548,42 @@ namespace WixToolset
13596 } 13548 }
13597 break; 13549 break;
13598 case "OnInstall": 13550 case "OnInstall":
13599 YesNoType install = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 13551 YesNoType install = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
13600 if (YesNoType.Yes == install) 13552 if (YesNoType.Yes == install)
13601 { 13553 {
13602 events |= MsiInterop.MsidbServiceConfigEventInstall; 13554 events |= MsiInterop.MsidbServiceConfigEventInstall;
13603 } 13555 }
13604 break; 13556 break;
13605 case "OnReinstall": 13557 case "OnReinstall":
13606 YesNoType reinstall = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 13558 YesNoType reinstall = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
13607 if (YesNoType.Yes == reinstall) 13559 if (YesNoType.Yes == reinstall)
13608 { 13560 {
13609 events |= MsiInterop.MsidbServiceConfigEventReinstall; 13561 events |= MsiInterop.MsidbServiceConfigEventReinstall;
13610 } 13562 }
13611 break; 13563 break;
13612 case "OnUninstall": 13564 case "OnUninstall":
13613 YesNoType uninstall = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 13565 YesNoType uninstall = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
13614 if (YesNoType.Yes == uninstall) 13566 if (YesNoType.Yes == uninstall)
13615 { 13567 {
13616 events |= MsiInterop.MsidbServiceConfigEventUninstall; 13568 events |= MsiInterop.MsidbServiceConfigEventUninstall;
13617 } 13569 }
13618 break; 13570 break;
13619 default: 13571 default:
13620 this.core.UnexpectedAttribute(node, attrib); 13572 this.Core.UnexpectedAttribute(node, attrib);
13621 break; 13573 break;
13622 case "PreShutdownDelay": 13574 case "PreShutdownDelay":
13623 preShutdownDelay = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 13575 preShutdownDelay = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
13624 break; 13576 break;
13625 case "ServiceName": 13577 case "ServiceName":
13626 if (!String.IsNullOrEmpty(serviceName)) 13578 if (!String.IsNullOrEmpty(serviceName))
13627 { 13579 {
13628 this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ServiceInstall")); 13580 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ServiceInstall"));
13629 } 13581 }
13630 13582
13631 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 13583 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
13632 break; 13584 break;
13633 case "ServiceSid": 13585 case "ServiceSid":
13634 sid = this.core.GetAttributeValue(sourceLineNumbers, attrib); 13586 sid = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
13635 if (0 < sid.Length) 13587 if (0 < sid.Length)
13636 { 13588 {
13637 switch (sid) 13589 switch (sid)
@@ -13655,7 +13607,7 @@ namespace WixToolset
13655 } 13607 }
13656 else 13608 else
13657 { 13609 {
13658 this.core.ParseExtensionAttribute(node, attrib); 13610 this.Core.ParseExtensionAttribute(node, attrib);
13659 } 13611 }
13660 } 13612 }
13661 13613
@@ -13667,7 +13619,7 @@ namespace WixToolset
13667 switch (child.Name.LocalName) 13619 switch (child.Name.LocalName)
13668 { 13620 {
13669 case "RequiredPrivilege": 13621 case "RequiredPrivilege":
13670 string privilege = this.core.GetTrimmedInnerText(child); 13622 string privilege = this.Core.GetTrimmedInnerText(child);
13671 switch (privilege) 13623 switch (privilege)
13672 { 13624 {
13673 case "assignPrimaryToken": 13625 case "assignPrimaryToken":
@@ -13791,85 +13743,85 @@ namespace WixToolset
13791 requiredPrivileges = String.Concat(requiredPrivileges, privilege); 13743 requiredPrivileges = String.Concat(requiredPrivileges, privilege);
13792 break; 13744 break;
13793 default: 13745 default:
13794 this.core.UnexpectedElement(node, child); 13746 this.Core.UnexpectedElement(node, child);
13795 break; 13747 break;
13796 } 13748 }
13797 } 13749 }
13798 else 13750 else
13799 { 13751 {
13800 this.core.ParseExtensionElement(node, child); 13752 this.Core.ParseExtensionElement(node, child);
13801 } 13753 }
13802 } 13754 }
13803 13755
13804 if (String.IsNullOrEmpty(name)) 13756 if (String.IsNullOrEmpty(name))
13805 { 13757 {
13806 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ServiceName")); 13758 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ServiceName"));
13807 } 13759 }
13808 else if (null == id) 13760 else if (null == id)
13809 { 13761 {
13810 id = this.core.CreateIdentifierFromFilename(name); 13762 id = this.Core.CreateIdentifierFromFilename(name);
13811 } 13763 }
13812 13764
13813 if (0 == events) 13765 if (0 == events)
13814 { 13766 {
13815 this.core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "OnInstall", "OnReinstall", "OnUninstall")); 13767 this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "OnInstall", "OnReinstall", "OnUninstall"));
13816 } 13768 }
13817 13769
13818 if (String.IsNullOrEmpty(delayedAutoStart) && String.IsNullOrEmpty(failureActionsWhen) && String.IsNullOrEmpty(preShutdownDelay) && String.IsNullOrEmpty(requiredPrivileges) && String.IsNullOrEmpty(sid)) 13770 if (String.IsNullOrEmpty(delayedAutoStart) && String.IsNullOrEmpty(failureActionsWhen) && String.IsNullOrEmpty(preShutdownDelay) && String.IsNullOrEmpty(requiredPrivileges) && String.IsNullOrEmpty(sid))
13819 { 13771 {
13820 this.core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "DelayedAutoStart", "FailureActionsWhen", "PreShutdownDelay", "ServiceSid", "RequiredPrivilege")); 13772 this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "DelayedAutoStart", "FailureActionsWhen", "PreShutdownDelay", "ServiceSid", "RequiredPrivilege"));
13821 } 13773 }
13822 13774
13823 if (!this.core.EncounteredError) 13775 if (!this.Core.EncounteredError)
13824 { 13776 {
13825 if (!String.IsNullOrEmpty(delayedAutoStart)) 13777 if (!String.IsNullOrEmpty(delayedAutoStart))
13826 { 13778 {
13827 Row row = this.core.CreateRow(sourceLineNumbers, "MsiServiceConfig", new Identifier(String.Concat(id.Id, ".DS"), id.Access)); 13779 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiServiceConfig, new Identifier(String.Concat(id.Id, ".DS"), id.Access));
13828 row[1] = name; 13780 row.Set(1, name);
13829 row[2] = events; 13781 row.Set(2, events);
13830 row[3] = 3; 13782 row.Set(3, 3);
13831 row[4] = delayedAutoStart; 13783 row.Set(4, delayedAutoStart);
13832 row[5] = componentId; 13784 row.Set(5, componentId);
13833 } 13785 }
13834 13786
13835 if (!String.IsNullOrEmpty(failureActionsWhen)) 13787 if (!String.IsNullOrEmpty(failureActionsWhen))
13836 { 13788 {
13837 Row row = this.core.CreateRow(sourceLineNumbers, "MsiServiceConfig", new Identifier(String.Concat(id.Id, ".FA"), id.Access)); 13789 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiServiceConfig, new Identifier(String.Concat(id.Id, ".FA"), id.Access));
13838 row[1] = name; 13790 row.Set(1, name);
13839 row[2] = events; 13791 row.Set(2, events);
13840 row[3] = 4; 13792 row.Set(3, 4);
13841 row[4] = failureActionsWhen; 13793 row.Set(4, failureActionsWhen);
13842 row[5] = componentId; 13794 row.Set(5, componentId);
13843 } 13795 }
13844 13796
13845 if (!String.IsNullOrEmpty(sid)) 13797 if (!String.IsNullOrEmpty(sid))
13846 { 13798 {
13847 Row row = this.core.CreateRow(sourceLineNumbers, "MsiServiceConfig", new Identifier(String.Concat(id.Id, ".SS"), id.Access)); 13799 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiServiceConfig, new Identifier(String.Concat(id.Id, ".SS"), id.Access));
13848 row[1] = name; 13800 row.Set(1, name);
13849 row[2] = events; 13801 row.Set(2, events);
13850 row[3] = 5; 13802 row.Set(3, 5);
13851 row[4] = sid; 13803 row.Set(4, sid);
13852 row[5] = componentId; 13804 row.Set(5, componentId);
13853 } 13805 }
13854 13806
13855 if (!String.IsNullOrEmpty(requiredPrivileges)) 13807 if (!String.IsNullOrEmpty(requiredPrivileges))
13856 { 13808 {
13857 Row row = this.core.CreateRow(sourceLineNumbers, "MsiServiceConfig", new Identifier(String.Concat(id.Id, ".RP"), id.Access)); 13809 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiServiceConfig, new Identifier(String.Concat(id.Id, ".RP"), id.Access));
13858 row[1] = name; 13810 row.Set(1, name);
13859 row[2] = events; 13811 row.Set(2, events);
13860 row[3] = 6; 13812 row.Set(3, 6);
13861 row[4] = requiredPrivileges; 13813 row.Set(4, requiredPrivileges);
13862 row[5] = componentId; 13814 row.Set(5, componentId);
13863 } 13815 }
13864 13816
13865 if (!String.IsNullOrEmpty(preShutdownDelay)) 13817 if (!String.IsNullOrEmpty(preShutdownDelay))
13866 { 13818 {
13867 Row row = this.core.CreateRow(sourceLineNumbers, "MsiServiceConfig", new Identifier(String.Concat(id.Id, ".PD"), id.Access)); 13819 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiServiceConfig, new Identifier(String.Concat(id.Id, ".PD"), id.Access));
13868 row[1] = name; 13820 row.Set(1, name);
13869 row[2] = events; 13821 row.Set(2, events);
13870 row[3] = 7; 13822 row.Set(3, 7);
13871 row[4] = preShutdownDelay; 13823 row.Set(4, preShutdownDelay);
13872 row[5] = componentId; 13824 row.Set(5, componentId);
13873 } 13825 }
13874 } 13826 }
13875 } 13827 }
@@ -13892,7 +13844,7 @@ namespace WixToolset
13892 string actions = null; 13844 string actions = null;
13893 string actionsDelays = null; 13845 string actionsDelays = null;
13894 13846
13895 this.core.OnMessage(WixWarnings.ServiceConfigFamilyNotSupported(sourceLineNumbers, node.Name.LocalName)); 13847 this.Core.OnMessage(WixWarnings.ServiceConfigFamilyNotSupported(sourceLineNumbers, node.Name.LocalName));
13896 13848
13897 foreach (XAttribute attrib in node.Attributes()) 13849 foreach (XAttribute attrib in node.Attributes())
13898 { 13850 {
@@ -13901,54 +13853,54 @@ namespace WixToolset
13901 switch (attrib.Name.LocalName) 13853 switch (attrib.Name.LocalName)
13902 { 13854 {
13903 case "Id": 13855 case "Id":
13904 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 13856 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
13905 break; 13857 break;
13906 case "Command": 13858 case "Command":
13907 command = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 13859 command = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
13908 break; 13860 break;
13909 case "OnInstall": 13861 case "OnInstall":
13910 YesNoType install = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 13862 YesNoType install = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
13911 if (YesNoType.Yes == install) 13863 if (YesNoType.Yes == install)
13912 { 13864 {
13913 events |= MsiInterop.MsidbServiceConfigEventInstall; 13865 events |= MsiInterop.MsidbServiceConfigEventInstall;
13914 } 13866 }
13915 break; 13867 break;
13916 case "OnReinstall": 13868 case "OnReinstall":
13917 YesNoType reinstall = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 13869 YesNoType reinstall = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
13918 if (YesNoType.Yes == reinstall) 13870 if (YesNoType.Yes == reinstall)
13919 { 13871 {
13920 events |= MsiInterop.MsidbServiceConfigEventReinstall; 13872 events |= MsiInterop.MsidbServiceConfigEventReinstall;
13921 } 13873 }
13922 break; 13874 break;
13923 case "OnUninstall": 13875 case "OnUninstall":
13924 YesNoType uninstall = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 13876 YesNoType uninstall = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
13925 if (YesNoType.Yes == uninstall) 13877 if (YesNoType.Yes == uninstall)
13926 { 13878 {
13927 events |= MsiInterop.MsidbServiceConfigEventUninstall; 13879 events |= MsiInterop.MsidbServiceConfigEventUninstall;
13928 } 13880 }
13929 break; 13881 break;
13930 case "RebootMessage": 13882 case "RebootMessage":
13931 rebootMessage = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 13883 rebootMessage = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
13932 break; 13884 break;
13933 case "ResetPeriod": 13885 case "ResetPeriod":
13934 resetPeriod = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 13886 resetPeriod = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
13935 break; 13887 break;
13936 case "ServiceName": 13888 case "ServiceName":
13937 if (!String.IsNullOrEmpty(serviceName)) 13889 if (!String.IsNullOrEmpty(serviceName))
13938 { 13890 {
13939 this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ServiceInstall")); 13891 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ServiceInstall"));
13940 } 13892 }
13941 13893
13942 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 13894 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
13943 break; 13895 break;
13944 default: 13896 default:
13945 this.core.UnexpectedAttribute(node, attrib); 13897 this.Core.UnexpectedAttribute(node, attrib);
13946 break; 13898 break;
13947 } 13899 }
13948 } 13900 }
13949 else 13901 else
13950 { 13902 {
13951 this.core.ParseExtensionAttribute(node, attrib); 13903 this.Core.ParseExtensionAttribute(node, attrib);
13952 } 13904 }
13953 } 13905 }
13954 13906
@@ -13971,7 +13923,7 @@ namespace WixToolset
13971 switch (childAttrib.Name.LocalName) 13923 switch (childAttrib.Name.LocalName)
13972 { 13924 {
13973 case "Action": 13925 case "Action":
13974 action = this.core.GetAttributeValue(childSourceLineNumbers, childAttrib); 13926 action = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
13975 switch (action) 13927 switch (action)
13976 { 13928 {
13977 case "none": 13929 case "none":
@@ -13992,10 +13944,10 @@ namespace WixToolset
13992 } 13944 }
13993 break; 13945 break;
13994 case "Delay": 13946 case "Delay":
13995 delay = this.core.GetAttributeValue(childSourceLineNumbers, childAttrib); 13947 delay = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib);
13996 break; 13948 break;
13997 default: 13949 default:
13998 this.core.UnexpectedAttribute(child, childAttrib); 13950 this.Core.UnexpectedAttribute(child, childAttrib);
13999 break; 13951 break;
14000 } 13952 }
14001 } 13953 }
@@ -14003,12 +13955,12 @@ namespace WixToolset
14003 13955
14004 if (String.IsNullOrEmpty(action)) 13956 if (String.IsNullOrEmpty(action))
14005 { 13957 {
14006 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, child.Name.LocalName, "Action")); 13958 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, child.Name.LocalName, "Action"));
14007 } 13959 }
14008 13960
14009 if (String.IsNullOrEmpty(delay)) 13961 if (String.IsNullOrEmpty(delay))
14010 { 13962 {
14011 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, child.Name.LocalName, "Delay")); 13963 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, child.Name.LocalName, "Delay"));
14012 } 13964 }
14013 13965
14014 if (!String.IsNullOrEmpty(actions)) 13966 if (!String.IsNullOrEmpty(actions))
@@ -14024,44 +13976,44 @@ namespace WixToolset
14024 actionsDelays = String.Concat(actionsDelays, delay); 13976 actionsDelays = String.Concat(actionsDelays, delay);
14025 break; 13977 break;
14026 default: 13978 default:
14027 this.core.UnexpectedElement(node, child); 13979 this.Core.UnexpectedElement(node, child);
14028 break; 13980 break;
14029 } 13981 }
14030 } 13982 }
14031 else 13983 else
14032 { 13984 {
14033 this.core.ParseExtensionElement(node, child); 13985 this.Core.ParseExtensionElement(node, child);
14034 } 13986 }
14035 } 13987 }
14036 13988
14037 if (String.IsNullOrEmpty(name)) 13989 if (String.IsNullOrEmpty(name))
14038 { 13990 {
14039 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ServiceName")); 13991 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ServiceName"));
14040 } 13992 }
14041 else if (null == id) 13993 else if (null == id)
14042 { 13994 {
14043 id = this.core.CreateIdentifierFromFilename(name); 13995 id = this.Core.CreateIdentifierFromFilename(name);
14044 } 13996 }
14045 13997
14046 if (0 == events) 13998 if (0 == events)
14047 { 13999 {
14048 this.core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "OnInstall", "OnReinstall", "OnUninstall")); 14000 this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "OnInstall", "OnReinstall", "OnUninstall"));
14049 } 14001 }
14050 14002
14051 if (!this.core.EncounteredError) 14003 if (!this.Core.EncounteredError)
14052 { 14004 {
14053 Row row = this.core.CreateRow(sourceLineNumbers, "MsiServiceConfigFailureActions", id); 14005 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiServiceConfigFailureActions, id);
14054 row[1] = name; 14006 row.Set(1, name);
14055 row[2] = events; 14007 row.Set(2, events);
14056 if (CompilerConstants.IntegerNotSet != resetPeriod) 14008 if (CompilerConstants.IntegerNotSet != resetPeriod)
14057 { 14009 {
14058 row[3] = resetPeriod; 14010 row.Set(3, resetPeriod);
14059 } 14011 }
14060 row[4] = rebootMessage ?? "[~]"; 14012 row.Set(4, rebootMessage ?? "[~]");
14061 row[5] = command ?? "[~]"; 14013 row.Set(5, command ?? "[~]");
14062 row[6] = actions; 14014 row.Set(6, actions);
14063 row[7] = actionsDelays; 14015 row.Set(7, actionsDelays);
14064 row[8] = componentId; 14016 row.Set(8, componentId);
14065 } 14017 }
14066 } 14018 }
14067 14019
@@ -14086,13 +14038,13 @@ namespace WixToolset
14086 switch (attrib.Name.LocalName) 14038 switch (attrib.Name.LocalName)
14087 { 14039 {
14088 case "Id": 14040 case "Id":
14089 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 14041 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
14090 break; 14042 break;
14091 case "Name": 14043 case "Name":
14092 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14044 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14093 break; 14045 break;
14094 case "Remove": 14046 case "Remove":
14095 Wix.InstallUninstallType removeValue = this.core.GetAttributeInstallUninstallValue(sourceLineNumbers, attrib); 14047 Wix.InstallUninstallType removeValue = this.Core.GetAttributeInstallUninstallValue(sourceLineNumbers, attrib);
14096 switch (removeValue) 14048 switch (removeValue)
14097 { 14049 {
14098 case Wix.InstallUninstallType.install: 14050 case Wix.InstallUninstallType.install:
@@ -14107,7 +14059,7 @@ namespace WixToolset
14107 } 14059 }
14108 break; 14060 break;
14109 case "Start": 14061 case "Start":
14110 Wix.InstallUninstallType startValue = this.core.GetAttributeInstallUninstallValue(sourceLineNumbers, attrib); 14062 Wix.InstallUninstallType startValue = this.Core.GetAttributeInstallUninstallValue(sourceLineNumbers, attrib);
14111 switch (startValue) 14063 switch (startValue)
14112 { 14064 {
14113 case Wix.InstallUninstallType.install: 14065 case Wix.InstallUninstallType.install:
@@ -14122,7 +14074,7 @@ namespace WixToolset
14122 } 14074 }
14123 break; 14075 break;
14124 case "Stop": 14076 case "Stop":
14125 Wix.InstallUninstallType stopValue = this.core.GetAttributeInstallUninstallValue(sourceLineNumbers, attrib); 14077 Wix.InstallUninstallType stopValue = this.Core.GetAttributeInstallUninstallValue(sourceLineNumbers, attrib);
14126 switch (stopValue) 14078 switch (stopValue)
14127 { 14079 {
14128 case Wix.InstallUninstallType.install: 14080 case Wix.InstallUninstallType.install:
@@ -14137,27 +14089,27 @@ namespace WixToolset
14137 } 14089 }
14138 break; 14090 break;
14139 case "Wait": 14091 case "Wait":
14140 wait = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 14092 wait = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
14141 break; 14093 break;
14142 default: 14094 default:
14143 this.core.UnexpectedAttribute(node, attrib); 14095 this.Core.UnexpectedAttribute(node, attrib);
14144 break; 14096 break;
14145 } 14097 }
14146 } 14098 }
14147 else 14099 else
14148 { 14100 {
14149 this.core.ParseExtensionAttribute(node, attrib); 14101 this.Core.ParseExtensionAttribute(node, attrib);
14150 } 14102 }
14151 } 14103 }
14152 14104
14153 if (null == id) 14105 if (null == id)
14154 { 14106 {
14155 id = this.core.CreateIdentifierFromFilename(name); 14107 id = this.Core.CreateIdentifierFromFilename(name);
14156 } 14108 }
14157 14109
14158 if (null == name) 14110 if (null == name)
14159 { 14111 {
14160 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 14112 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
14161 } 14113 }
14162 14114
14163 // get the ServiceControl arguments 14115 // get the ServiceControl arguments
@@ -14172,30 +14124,30 @@ namespace WixToolset
14172 { 14124 {
14173 arguments = String.Concat(arguments, "[~]"); 14125 arguments = String.Concat(arguments, "[~]");
14174 } 14126 }
14175 arguments = String.Concat(arguments, this.core.GetTrimmedInnerText(child)); 14127 arguments = String.Concat(arguments, this.Core.GetTrimmedInnerText(child));
14176 break; 14128 break;
14177 default: 14129 default:
14178 this.core.UnexpectedElement(node, child); 14130 this.Core.UnexpectedElement(node, child);
14179 break; 14131 break;
14180 } 14132 }
14181 } 14133 }
14182 else 14134 else
14183 { 14135 {
14184 this.core.ParseExtensionElement(node, child); 14136 this.Core.ParseExtensionElement(node, child);
14185 } 14137 }
14186 } 14138 }
14187 14139
14188 if (!this.core.EncounteredError) 14140 if (!this.Core.EncounteredError)
14189 { 14141 {
14190 Row row = this.core.CreateRow(sourceLineNumbers, "ServiceControl", id); 14142 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ServiceControl, id);
14191 row[1] = name; 14143 row.Set(1, name);
14192 row[2] = events; 14144 row.Set(2, events);
14193 row[3] = arguments; 14145 row.Set(3, arguments);
14194 if (YesNoType.NotSet != wait) 14146 if (YesNoType.NotSet != wait)
14195 { 14147 {
14196 row[4] = YesNoType.Yes == wait ? 1 : 0; 14148 row.Set(4, YesNoType.Yes == wait ? 1 : 0);
14197 } 14149 }
14198 row[5] = componentId; 14150 row.Set(5, componentId);
14199 } 14151 }
14200 } 14152 }
14201 14153
@@ -14217,28 +14169,28 @@ namespace WixToolset
14217 switch (attrib.Name.LocalName) 14169 switch (attrib.Name.LocalName)
14218 { 14170 {
14219 case "Id": 14171 case "Id":
14220 dependency = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14172 dependency = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14221 break; 14173 break;
14222 case "Group": 14174 case "Group":
14223 group = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 14175 group = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
14224 break; 14176 break;
14225 default: 14177 default:
14226 this.core.UnexpectedAttribute(node, attrib); 14178 this.Core.UnexpectedAttribute(node, attrib);
14227 break; 14179 break;
14228 } 14180 }
14229 } 14181 }
14230 else 14182 else
14231 { 14183 {
14232 this.core.ParseExtensionAttribute(node, attrib); 14184 this.Core.ParseExtensionAttribute(node, attrib);
14233 } 14185 }
14234 } 14186 }
14235 14187
14236 if (null == dependency) 14188 if (null == dependency)
14237 { 14189 {
14238 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 14190 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
14239 } 14191 }
14240 14192
14241 this.core.ParseForExtensionElements(node); 14193 this.Core.ParseForExtensionElements(node);
14242 14194
14243 return group ? String.Concat("+", dependency) : dependency; 14195 return group ? String.Concat("+", dependency) : dependency;
14244 } 14196 }
@@ -14272,25 +14224,25 @@ namespace WixToolset
14272 switch (attrib.Name.LocalName) 14224 switch (attrib.Name.LocalName)
14273 { 14225 {
14274 case "Id": 14226 case "Id":
14275 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 14227 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
14276 break; 14228 break;
14277 case "Account": 14229 case "Account":
14278 account = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14230 account = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14279 break; 14231 break;
14280 case "Arguments": 14232 case "Arguments":
14281 arguments = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14233 arguments = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14282 break; 14234 break;
14283 case "Description": 14235 case "Description":
14284 description = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14236 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14285 break; 14237 break;
14286 case "DisplayName": 14238 case "DisplayName":
14287 displayName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14239 displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14288 break; 14240 break;
14289 case "EraseDescription": 14241 case "EraseDescription":
14290 eraseDescription = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 14242 eraseDescription = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
14291 break; 14243 break;
14292 case "ErrorControl": 14244 case "ErrorControl":
14293 string errorControlValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14245 string errorControlValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14294 if (0 < errorControlValue.Length) 14246 if (0 < errorControlValue.Length)
14295 { 14247 {
14296 Wix.ServiceInstall.ErrorControlType errorControlType = Wix.ServiceInstall.ParseErrorControlType(errorControlValue); 14248 Wix.ServiceInstall.ErrorControlType errorControlType = Wix.ServiceInstall.ParseErrorControlType(errorControlValue);
@@ -14306,28 +14258,28 @@ namespace WixToolset
14306 errorbits |= MsiInterop.MsidbServiceInstallErrorCritical; 14258 errorbits |= MsiInterop.MsidbServiceInstallErrorCritical;
14307 break; 14259 break;
14308 default: 14260 default:
14309 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, errorControlValue, "ignore", "normal", "critical")); 14261 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, errorControlValue, "ignore", "normal", "critical"));
14310 break; 14262 break;
14311 } 14263 }
14312 } 14264 }
14313 break; 14265 break;
14314 case "Interactive": 14266 case "Interactive":
14315 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 14267 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
14316 { 14268 {
14317 typebits |= MsiInterop.MsidbServiceInstallInteractive; 14269 typebits |= MsiInterop.MsidbServiceInstallInteractive;
14318 } 14270 }
14319 break; 14271 break;
14320 case "LoadOrderGroup": 14272 case "LoadOrderGroup":
14321 loadOrderGroup = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14273 loadOrderGroup = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14322 break; 14274 break;
14323 case "Name": 14275 case "Name":
14324 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14276 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14325 break; 14277 break;
14326 case "Password": 14278 case "Password":
14327 password = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14279 password = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14328 break; 14280 break;
14329 case "Start": 14281 case "Start":
14330 string startValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14282 string startValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14331 if (0 < startValue.Length) 14283 if (0 < startValue.Length)
14332 { 14284 {
14333 Wix.ServiceInstall.StartType start = Wix.ServiceInstall.ParseStartType(startValue); 14285 Wix.ServiceInstall.StartType start = Wix.ServiceInstall.ParseStartType(startValue);
@@ -14344,16 +14296,16 @@ namespace WixToolset
14344 break; 14296 break;
14345 case Wix.ServiceInstall.StartType.boot: 14297 case Wix.ServiceInstall.StartType.boot:
14346 case Wix.ServiceInstall.StartType.system: 14298 case Wix.ServiceInstall.StartType.system:
14347 this.core.OnMessage(WixErrors.ValueNotSupported(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, startValue)); 14299 this.Core.OnMessage(WixErrors.ValueNotSupported(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, startValue));
14348 break; 14300 break;
14349 default: 14301 default:
14350 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, startValue, "auto", "demand", "disabled")); 14302 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, startValue, "auto", "demand", "disabled"));
14351 break; 14303 break;
14352 } 14304 }
14353 } 14305 }
14354 break; 14306 break;
14355 case "Type": 14307 case "Type":
14356 string typeValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14308 string typeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14357 if (0 < typeValue.Length) 14309 if (0 < typeValue.Length)
14358 { 14310 {
14359 Wix.ServiceInstall.TypeType typeType = Wix.ServiceInstall.ParseTypeType(typeValue); 14311 Wix.ServiceInstall.TypeType typeType = Wix.ServiceInstall.ParseTypeType(typeValue);
@@ -14367,43 +14319,43 @@ namespace WixToolset
14367 break; 14319 break;
14368 case Wix.ServiceInstall.TypeType.kernelDriver: 14320 case Wix.ServiceInstall.TypeType.kernelDriver:
14369 case Wix.ServiceInstall.TypeType.systemDriver: 14321 case Wix.ServiceInstall.TypeType.systemDriver:
14370 this.core.OnMessage(WixErrors.ValueNotSupported(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, typeValue)); 14322 this.Core.OnMessage(WixErrors.ValueNotSupported(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, typeValue));
14371 break; 14323 break;
14372 default: 14324 default:
14373 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, node.Name.LocalName, typeValue, "ownProcess", "shareProcess")); 14325 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, node.Name.LocalName, typeValue, "ownProcess", "shareProcess"));
14374 break; 14326 break;
14375 } 14327 }
14376 } 14328 }
14377 break; 14329 break;
14378 case "Vital": 14330 case "Vital":
14379 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 14331 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
14380 { 14332 {
14381 errorbits |= MsiInterop.MsidbServiceInstallErrorControlVital; 14333 errorbits |= MsiInterop.MsidbServiceInstallErrorControlVital;
14382 } 14334 }
14383 break; 14335 break;
14384 default: 14336 default:
14385 this.core.UnexpectedAttribute(node, attrib); 14337 this.Core.UnexpectedAttribute(node, attrib);
14386 break; 14338 break;
14387 } 14339 }
14388 } 14340 }
14389 else 14341 else
14390 { 14342 {
14391 this.core.ParseExtensionAttribute(node, attrib); 14343 this.Core.ParseExtensionAttribute(node, attrib);
14392 } 14344 }
14393 } 14345 }
14394 14346
14395 if (String.IsNullOrEmpty(name)) 14347 if (String.IsNullOrEmpty(name))
14396 { 14348 {
14397 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 14349 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
14398 } 14350 }
14399 else if (null == id) 14351 else if (null == id)
14400 { 14352 {
14401 id = this.core.CreateIdentifierFromFilename(name); 14353 id = this.Core.CreateIdentifierFromFilename(name);
14402 } 14354 }
14403 14355
14404 if (0 == startType) 14356 if (0 == startType)
14405 { 14357 {
14406 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Start")); 14358 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Start"));
14407 } 14359 }
14408 14360
14409 if (eraseDescription) 14361 if (eraseDescription)
@@ -14431,14 +14383,14 @@ namespace WixToolset
14431 dependencies = String.Concat(dependencies, this.ParseServiceDependencyElement(child), "[~]"); 14383 dependencies = String.Concat(dependencies, this.ParseServiceDependencyElement(child), "[~]");
14432 break; 14384 break;
14433 default: 14385 default:
14434 this.core.UnexpectedElement(node, child); 14386 this.Core.UnexpectedElement(node, child);
14435 break; 14387 break;
14436 } 14388 }
14437 } 14389 }
14438 else 14390 else
14439 { 14391 {
14440 Dictionary<string, string> context = new Dictionary<string, string>() { { "ServiceInstallId", id.Id }, { "ServiceInstallName", name }, { "ServiceInstallComponentId", componentId }, { "Win64", win64Component.ToString() } }; 14392 Dictionary<string, string> context = new Dictionary<string, string>() { { "ServiceInstallId", id.Id }, { "ServiceInstallName", name }, { "ServiceInstallComponentId", componentId }, { "Win64", win64Component.ToString() } };
14441 this.core.ParseExtensionElement(node, child, context); 14393 this.Core.ParseExtensionElement(node, child, context);
14442 } 14394 }
14443 } 14395 }
14444 14396
@@ -14447,21 +14399,21 @@ namespace WixToolset
14447 dependencies = String.Concat(dependencies, "[~]"); 14399 dependencies = String.Concat(dependencies, "[~]");
14448 } 14400 }
14449 14401
14450 if (!this.core.EncounteredError) 14402 if (!this.Core.EncounteredError)
14451 { 14403 {
14452 Row row = this.core.CreateRow(sourceLineNumbers, "ServiceInstall", id); 14404 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ServiceInstall, id);
14453 row[1] = name; 14405 row.Set(1, name);
14454 row[2] = displayName; 14406 row.Set(2, displayName);
14455 row[3] = typebits; 14407 row.Set(3, typebits);
14456 row[4] = startType; 14408 row.Set(4, startType);
14457 row[5] = errorbits; 14409 row.Set(5, errorbits);
14458 row[6] = loadOrderGroup; 14410 row.Set(6, loadOrderGroup);
14459 row[7] = dependencies; 14411 row.Set(7, dependencies);
14460 row[8] = account; 14412 row.Set(8, account);
14461 row[9] = password; 14413 row.Set(9, password);
14462 row[10] = arguments; 14414 row.Set(10, arguments);
14463 row[11] = componentId; 14415 row.Set(11, componentId);
14464 row[12] = description; 14416 row.Set(12, description);
14465 } 14417 }
14466 } 14418 }
14467 14419
@@ -14486,14 +14438,14 @@ namespace WixToolset
14486 switch (attrib.Name.LocalName) 14438 switch (attrib.Name.LocalName)
14487 { 14439 {
14488 case "Action": 14440 case "Action":
14489 actionName = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 14441 actionName = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
14490 break; 14442 break;
14491 case "Id": 14443 case "Id":
14492 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 14444 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
14493 this.core.CreateSimpleReference(sourceLineNumbers, "Directory", id); 14445 this.Core.CreateSimpleReference(sourceLineNumbers, "Directory", id);
14494 break; 14446 break;
14495 case "Sequence": 14447 case "Sequence":
14496 string sequenceValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14448 string sequenceValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14497 if (0 < sequenceValue.Length) 14449 if (0 < sequenceValue.Length)
14498 { 14450 {
14499 Wix.SequenceType sequenceType = Wix.Enums.ParseSequenceType(sequenceValue); 14451 Wix.SequenceType sequenceType = Wix.Enums.ParseSequenceType(sequenceValue);
@@ -14513,30 +14465,30 @@ namespace WixToolset
14513 // default so no work necessary. 14465 // default so no work necessary.
14514 break; 14466 break;
14515 default: 14467 default:
14516 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, sequenceValue, "execute", "ui", "both")); 14468 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, sequenceValue, "execute", "ui", "both"));
14517 break; 14469 break;
14518 } 14470 }
14519 } 14471 }
14520 break; 14472 break;
14521 case "Value": 14473 case "Value":
14522 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14474 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14523 break; 14475 break;
14524 default: 14476 default:
14525 this.core.UnexpectedAttribute(node, attrib); 14477 this.Core.UnexpectedAttribute(node, attrib);
14526 break; 14478 break;
14527 } 14479 }
14528 } 14480 }
14529 else 14481 else
14530 { 14482 {
14531 this.core.ParseExtensionAttribute(node, attrib); 14483 this.Core.ParseExtensionAttribute(node, attrib);
14532 } 14484 }
14533 } 14485 }
14534 14486
14535 condition = this.core.GetConditionInnerText(node); 14487 condition = this.Core.GetConditionInnerText(node);
14536 14488
14537 if (null == id) 14489 if (null == id)
14538 { 14490 {
14539 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 14491 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
14540 } 14492 }
14541 else if (String.IsNullOrEmpty(actionName)) 14493 else if (String.IsNullOrEmpty(actionName))
14542 { 14494 {
@@ -14545,30 +14497,30 @@ namespace WixToolset
14545 14497
14546 if (null == value) 14498 if (null == value)
14547 { 14499 {
14548 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 14500 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
14549 } 14501 }
14550 14502
14551 this.core.ParseForExtensionElements(node); 14503 this.Core.ParseForExtensionElements(node);
14552 14504
14553 // add the row and any references needed 14505 // add the row and any references needed
14554 if (!this.core.EncounteredError) 14506 if (!this.Core.EncounteredError)
14555 { 14507 {
14556 Row row = this.core.CreateRow(sourceLineNumbers, "CustomAction"); 14508 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CustomAction);
14557 row[0] = actionName; 14509 row.Set(0, actionName);
14558 row[1] = MsiInterop.MsidbCustomActionTypeProperty | MsiInterop.MsidbCustomActionTypeTextData | extraBits; 14510 row.Set(1, MsiInterop.MsidbCustomActionTypeProperty | MsiInterop.MsidbCustomActionTypeTextData | extraBits);
14559 row[2] = id; 14511 row.Set(2, id);
14560 row[3] = value; 14512 row.Set(3, value);
14561 14513
14562 foreach (string sequence in sequences) 14514 foreach (string sequence in sequences)
14563 { 14515 {
14564 Row sequenceRow = this.core.CreateRow(sourceLineNumbers, "WixAction"); 14516 var sequenceRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixAction);
14565 sequenceRow[0] = sequence; 14517 sequenceRow.Set(0, sequence);
14566 sequenceRow[1] = actionName; 14518 sequenceRow.Set(1, actionName);
14567 sequenceRow[2] = condition; 14519 sequenceRow.Set(2, condition);
14568 // no explicit sequence 14520 // no explicit sequence
14569 // no before action 14521 // no before action
14570 sequenceRow[5] = "CostInitialize"; 14522 sequenceRow.Set(5, "CostInitialize");
14571 sequenceRow[6] = 0; // not overridable 14523 sequenceRow.Set(6, 0); // not overridable
14572 } 14524 }
14573 } 14525 }
14574 } 14526 }
@@ -14596,19 +14548,19 @@ namespace WixToolset
14596 switch (attrib.Name.LocalName) 14548 switch (attrib.Name.LocalName)
14597 { 14549 {
14598 case "Action": 14550 case "Action":
14599 actionName = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 14551 actionName = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
14600 break; 14552 break;
14601 case "Id": 14553 case "Id":
14602 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 14554 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
14603 break; 14555 break;
14604 case "After": 14556 case "After":
14605 afterAction = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 14557 afterAction = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
14606 break; 14558 break;
14607 case "Before": 14559 case "Before":
14608 beforeAction = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 14560 beforeAction = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
14609 break; 14561 break;
14610 case "Sequence": 14562 case "Sequence":
14611 string sequenceValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14563 string sequenceValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14612 if (0 < sequenceValue.Length) 14564 if (0 < sequenceValue.Length)
14613 { 14565 {
14614 Wix.SequenceType sequenceType = Wix.Enums.ParseSequenceType(sequenceValue); 14566 Wix.SequenceType sequenceType = Wix.Enums.ParseSequenceType(sequenceValue);
@@ -14628,30 +14580,30 @@ namespace WixToolset
14628 // default so no work necessary. 14580 // default so no work necessary.
14629 break; 14581 break;
14630 default: 14582 default:
14631 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, sequenceValue, "execute", "ui", "both")); 14583 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, sequenceValue, "execute", "ui", "both"));
14632 break; 14584 break;
14633 } 14585 }
14634 } 14586 }
14635 break; 14587 break;
14636 case "Value": 14588 case "Value":
14637 value = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 14589 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
14638 break; 14590 break;
14639 default: 14591 default:
14640 this.core.UnexpectedAttribute(node, attrib); 14592 this.Core.UnexpectedAttribute(node, attrib);
14641 break; 14593 break;
14642 } 14594 }
14643 } 14595 }
14644 else 14596 else
14645 { 14597 {
14646 this.core.ParseExtensionAttribute(node, attrib); 14598 this.Core.ParseExtensionAttribute(node, attrib);
14647 } 14599 }
14648 } 14600 }
14649 14601
14650 condition = this.core.GetConditionInnerText(node); 14602 condition = this.Core.GetConditionInnerText(node);
14651 14603
14652 if (null == id) 14604 if (null == id)
14653 { 14605 {
14654 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 14606 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
14655 } 14607 }
14656 else if (String.IsNullOrEmpty(actionName)) 14608 else if (String.IsNullOrEmpty(actionName))
14657 { 14609 {
@@ -14660,59 +14612,59 @@ namespace WixToolset
14660 14612
14661 if (null == value) 14613 if (null == value)
14662 { 14614 {
14663 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 14615 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
14664 } 14616 }
14665 14617
14666 if (null != beforeAction && null != afterAction) 14618 if (null != beforeAction && null != afterAction)
14667 { 14619 {
14668 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "After", "Before")); 14620 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "After", "Before"));
14669 } 14621 }
14670 else if (null == beforeAction && null == afterAction) 14622 else if (null == beforeAction && null == afterAction)
14671 { 14623 {
14672 this.core.OnMessage(WixErrors.ExpectedAttributesWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "After", "Before", "Id")); 14624 this.Core.OnMessage(WixErrors.ExpectedAttributesWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "After", "Before", "Id"));
14673 } 14625 }
14674 14626
14675 this.core.ParseForExtensionElements(node); 14627 this.Core.ParseForExtensionElements(node);
14676 14628
14677 // add the row and any references needed 14629 // add the row and any references needed
14678 if (!this.core.EncounteredError) 14630 if (!this.Core.EncounteredError)
14679 { 14631 {
14680 // action that is scheduled to occur before/after itself 14632 // action that is scheduled to occur before/after itself
14681 if (beforeAction == actionName) 14633 if (beforeAction == actionName)
14682 { 14634 {
14683 this.core.OnMessage(WixErrors.ActionScheduledRelativeToItself(sourceLineNumbers, node.Name.LocalName, "Before", beforeAction)); 14635 this.Core.OnMessage(WixErrors.ActionScheduledRelativeToItself(sourceLineNumbers, node.Name.LocalName, "Before", beforeAction));
14684 } 14636 }
14685 else if (afterAction == actionName) 14637 else if (afterAction == actionName)
14686 { 14638 {
14687 this.core.OnMessage(WixErrors.ActionScheduledRelativeToItself(sourceLineNumbers, node.Name.LocalName, "After", afterAction)); 14639 this.Core.OnMessage(WixErrors.ActionScheduledRelativeToItself(sourceLineNumbers, node.Name.LocalName, "After", afterAction));
14688 } 14640 }
14689 14641
14690 Row row = this.core.CreateRow(sourceLineNumbers, "CustomAction"); 14642 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CustomAction);
14691 row[0] = actionName; 14643 row.Set(0, actionName);
14692 row[1] = MsiInterop.MsidbCustomActionTypeProperty | MsiInterop.MsidbCustomActionTypeTextData | extraBits; 14644 row.Set(1, MsiInterop.MsidbCustomActionTypeProperty | MsiInterop.MsidbCustomActionTypeTextData | extraBits);
14693 row[2] = id; 14645 row.Set(2, id);
14694 row[3] = value; 14646 row.Set(3, value);
14695 14647
14696 foreach (string sequence in sequences) 14648 foreach (string sequence in sequences)
14697 { 14649 {
14698 Row sequenceRow = this.core.CreateRow(sourceLineNumbers, "WixAction"); 14650 var sequenceRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixAction);
14699 sequenceRow[0] = sequence; 14651 sequenceRow.Set(0, sequence);
14700 sequenceRow[1] = actionName; 14652 sequenceRow.Set(1, actionName);
14701 sequenceRow[2] = condition; 14653 sequenceRow.Set(2, condition);
14702 // no explicit sequence 14654 // no explicit sequence
14703 sequenceRow[4] = beforeAction; 14655 sequenceRow.Set(4, beforeAction);
14704 sequenceRow[5] = afterAction; 14656 sequenceRow.Set(5, afterAction);
14705 sequenceRow[6] = 0; // not overridable 14657 sequenceRow.Set(6, 0); // not overridable
14706 14658
14707 if (null != beforeAction) 14659 if (null != beforeAction)
14708 { 14660 {
14709 if (WindowsInstallerStandard.IsStandardAction(beforeAction)) 14661 if (WindowsInstallerStandard.IsStandardAction(beforeAction))
14710 { 14662 {
14711 this.core.CreateSimpleReference(sourceLineNumbers, "WixAction", sequence, beforeAction); 14663 this.Core.CreateSimpleReference(sourceLineNumbers, "WixAction", sequence, beforeAction);
14712 } 14664 }
14713 else 14665 else
14714 { 14666 {
14715 this.core.CreateSimpleReference(sourceLineNumbers, "CustomAction", beforeAction); 14667 this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", beforeAction);
14716 } 14668 }
14717 } 14669 }
14718 14670
@@ -14720,11 +14672,11 @@ namespace WixToolset
14720 { 14672 {
14721 if (WindowsInstallerStandard.IsStandardAction(afterAction)) 14673 if (WindowsInstallerStandard.IsStandardAction(afterAction))
14722 { 14674 {
14723 this.core.CreateSimpleReference(sourceLineNumbers, "WixAction", sequence, afterAction); 14675 this.Core.CreateSimpleReference(sourceLineNumbers, "WixAction", sequence, afterAction);
14724 } 14676 }
14725 else 14677 else
14726 { 14678 {
14727 this.core.CreateSimpleReference(sourceLineNumbers, "CustomAction", afterAction); 14679 this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", afterAction);
14728 } 14680 }
14729 } 14681 }
14730 } 14682 }
@@ -14748,31 +14700,31 @@ namespace WixToolset
14748 switch (attrib.Name.LocalName) 14700 switch (attrib.Name.LocalName)
14749 { 14701 {
14750 case "Id": 14702 case "Id":
14751 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 14703 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
14752 break; 14704 break;
14753 default: 14705 default:
14754 this.core.UnexpectedAttribute(node, attrib); 14706 this.Core.UnexpectedAttribute(node, attrib);
14755 break; 14707 break;
14756 } 14708 }
14757 } 14709 }
14758 else 14710 else
14759 { 14711 {
14760 this.core.ParseExtensionAttribute(node, attrib); 14712 this.Core.ParseExtensionAttribute(node, attrib);
14761 } 14713 }
14762 } 14714 }
14763 14715
14764 if (null == id) 14716 if (null == id)
14765 { 14717 {
14766 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 14718 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
14767 } 14719 }
14768 14720
14769 this.core.ParseForExtensionElements(node); 14721 this.Core.ParseForExtensionElements(node);
14770 14722
14771 if (!this.core.EncounteredError) 14723 if (!this.Core.EncounteredError)
14772 { 14724 {
14773 Row row = this.core.CreateRow(sourceLineNumbers, "FileSFPCatalog"); 14725 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.FileSFPCatalog);
14774 row[0] = id; 14726 row.Set(0, id);
14775 row[1] = parentSFPCatalog; 14727 row.Set(1, parentSFPCatalog);
14776 } 14728 }
14777 } 14729 }
14778 14730
@@ -14796,34 +14748,34 @@ namespace WixToolset
14796 switch (attrib.Name.LocalName) 14748 switch (attrib.Name.LocalName)
14797 { 14749 {
14798 case "Dependency": 14750 case "Dependency":
14799 dependency = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14751 dependency = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14800 break; 14752 break;
14801 case "Name": 14753 case "Name":
14802 name = this.core.GetAttributeShortFilename(sourceLineNumbers, attrib, false); 14754 name = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, false);
14803 parentSFPCatalog = name; 14755 parentSFPCatalog = name;
14804 break; 14756 break;
14805 case "SourceFile": 14757 case "SourceFile":
14806 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14758 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14807 break; 14759 break;
14808 default: 14760 default:
14809 this.core.UnexpectedAttribute(node, attrib); 14761 this.Core.UnexpectedAttribute(node, attrib);
14810 break; 14762 break;
14811 } 14763 }
14812 } 14764 }
14813 else 14765 else
14814 { 14766 {
14815 this.core.ParseExtensionAttribute(node, attrib); 14767 this.Core.ParseExtensionAttribute(node, attrib);
14816 } 14768 }
14817 } 14769 }
14818 14770
14819 if (null == name) 14771 if (null == name)
14820 { 14772 {
14821 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 14773 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
14822 } 14774 }
14823 14775
14824 if (null == sourceFile) 14776 if (null == sourceFile)
14825 { 14777 {
14826 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); 14778 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
14827 } 14779 }
14828 14780
14829 foreach (XElement child in node.Elements()) 14781 foreach (XElement child in node.Elements())
@@ -14836,7 +14788,7 @@ namespace WixToolset
14836 this.ParseSFPCatalogElement(child, ref parentName); 14788 this.ParseSFPCatalogElement(child, ref parentName);
14837 if (null != dependency && parentName == dependency) 14789 if (null != dependency && parentName == dependency)
14838 { 14790 {
14839 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Dependency")); 14791 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Dependency"));
14840 } 14792 }
14841 dependency = parentName; 14793 dependency = parentName;
14842 break; 14794 break;
@@ -14844,27 +14796,27 @@ namespace WixToolset
14844 this.ParseSFPFileElement(child, name); 14796 this.ParseSFPFileElement(child, name);
14845 break; 14797 break;
14846 default: 14798 default:
14847 this.core.UnexpectedElement(node, child); 14799 this.Core.UnexpectedElement(node, child);
14848 break; 14800 break;
14849 } 14801 }
14850 } 14802 }
14851 else 14803 else
14852 { 14804 {
14853 this.core.ParseExtensionElement(node, child); 14805 this.Core.ParseExtensionElement(node, child);
14854 } 14806 }
14855 } 14807 }
14856 14808
14857 if (null == dependency) 14809 if (null == dependency)
14858 { 14810 {
14859 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Dependency")); 14811 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Dependency"));
14860 } 14812 }
14861 14813
14862 if (!this.core.EncounteredError) 14814 if (!this.Core.EncounteredError)
14863 { 14815 {
14864 Row row = this.core.CreateRow(sourceLineNumbers, "SFPCatalog"); 14816 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.SFPCatalog);
14865 row[0] = name; 14817 row.Set(0, name);
14866 row[1] = sourceFile; 14818 row.Set(1, sourceFile);
14867 row[2] = dependency; 14819 row.Set(2, dependency);
14868 } 14820 }
14869 } 14821 }
14870 14822
@@ -14904,50 +14856,50 @@ namespace WixToolset
14904 switch (attrib.Name.LocalName) 14856 switch (attrib.Name.LocalName)
14905 { 14857 {
14906 case "Id": 14858 case "Id":
14907 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 14859 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
14908 break; 14860 break;
14909 case "Advertise": 14861 case "Advertise":
14910 advertise = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 14862 advertise = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
14911 break; 14863 break;
14912 case "Arguments": 14864 case "Arguments":
14913 arguments = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14865 arguments = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14914 break; 14866 break;
14915 case "Description": 14867 case "Description":
14916 description = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14868 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14917 break; 14869 break;
14918 case "DescriptionResourceDll": 14870 case "DescriptionResourceDll":
14919 descriptionResourceDll = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14871 descriptionResourceDll = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14920 break; 14872 break;
14921 case "DescriptionResourceId": 14873 case "DescriptionResourceId":
14922 descriptionResourceId = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 14874 descriptionResourceId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
14923 break; 14875 break;
14924 case "Directory": 14876 case "Directory":
14925 directory = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null); 14877 directory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
14926 break; 14878 break;
14927 case "DisplayResourceDll": 14879 case "DisplayResourceDll":
14928 displayResourceDll = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14880 displayResourceDll = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14929 break; 14881 break;
14930 case "DisplayResourceId": 14882 case "DisplayResourceId":
14931 displayResourceId = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 14883 displayResourceId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
14932 break; 14884 break;
14933 case "Hotkey": 14885 case "Hotkey":
14934 hotkey = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 14886 hotkey = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
14935 break; 14887 break;
14936 case "Icon": 14888 case "Icon":
14937 icon = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 14889 icon = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
14938 this.core.CreateSimpleReference(sourceLineNumbers, "Icon", icon); 14890 this.Core.CreateSimpleReference(sourceLineNumbers, "Icon", icon);
14939 break; 14891 break;
14940 case "IconIndex": 14892 case "IconIndex":
14941 iconIndex = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, short.MinValue + 1, short.MaxValue); 14893 iconIndex = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, short.MinValue + 1, short.MaxValue);
14942 break; 14894 break;
14943 case "Name": 14895 case "Name":
14944 name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); 14896 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
14945 break; 14897 break;
14946 case "ShortName": 14898 case "ShortName":
14947 shortName = this.core.GetAttributeShortFilename(sourceLineNumbers, attrib, false); 14899 shortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, false);
14948 break; 14900 break;
14949 case "Show": 14901 case "Show":
14950 string showValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14902 string showValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14951 if (showValue.Length == 0) 14903 if (showValue.Length == 0)
14952 { 14904 {
14953 show = CompilerConstants.IllegalInteger; 14905 show = CompilerConstants.IllegalInteger;
@@ -14967,32 +14919,32 @@ namespace WixToolset
14967 show = 7; 14919 show = 7;
14968 break; 14920 break;
14969 default: 14921 default:
14970 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Show", showValue, "normal", "maximized", "minimized")); 14922 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Show", showValue, "normal", "maximized", "minimized"));
14971 show = CompilerConstants.IllegalInteger; 14923 show = CompilerConstants.IllegalInteger;
14972 break; 14924 break;
14973 } 14925 }
14974 } 14926 }
14975 break; 14927 break;
14976 case "Target": 14928 case "Target":
14977 target = this.core.GetAttributeValue(sourceLineNumbers, attrib); 14929 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
14978 break; 14930 break;
14979 case "WorkingDirectory": 14931 case "WorkingDirectory":
14980 workingDirectory = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 14932 workingDirectory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
14981 break; 14933 break;
14982 default: 14934 default:
14983 this.core.UnexpectedAttribute(node, attrib); 14935 this.Core.UnexpectedAttribute(node, attrib);
14984 break; 14936 break;
14985 } 14937 }
14986 } 14938 }
14987 else 14939 else
14988 { 14940 {
14989 this.core.ParseExtensionAttribute(node, attrib); 14941 this.Core.ParseExtensionAttribute(node, attrib);
14990 } 14942 }
14991 } 14943 }
14992 14944
14993 if (advertise && null != target) 14945 if (advertise && null != target)
14994 { 14946 {
14995 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Target", "Advertise", "yes")); 14947 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Target", "Advertise", "yes"));
14996 } 14948 }
14997 14949
14998 if (null == directory) 14950 if (null == directory)
@@ -15003,7 +14955,7 @@ namespace WixToolset
15003 } 14955 }
15004 else 14956 else
15005 { 14957 {
15006 this.core.OnMessage(WixErrors.ExpectedAttributeWhenElementNotUnderElement(sourceLineNumbers, node.Name.LocalName, "Directory", "Component")); 14958 this.Core.OnMessage(WixErrors.ExpectedAttributeWhenElementNotUnderElement(sourceLineNumbers, node.Name.LocalName, "Directory", "Component"));
15007 } 14959 }
15008 } 14960 }
15009 14961
@@ -15011,14 +14963,14 @@ namespace WixToolset
15011 { 14963 {
15012 if (CompilerConstants.IntegerNotSet == descriptionResourceId) 14964 if (CompilerConstants.IntegerNotSet == descriptionResourceId)
15013 { 14965 {
15014 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DescriptionResourceDll", "DescriptionResourceId")); 14966 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DescriptionResourceDll", "DescriptionResourceId"));
15015 } 14967 }
15016 } 14968 }
15017 else 14969 else
15018 { 14970 {
15019 if (CompilerConstants.IntegerNotSet != descriptionResourceId) 14971 if (CompilerConstants.IntegerNotSet != descriptionResourceId)
15020 { 14972 {
15021 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DescriptionResourceId", "DescriptionResourceDll")); 14973 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DescriptionResourceId", "DescriptionResourceDll"));
15022 } 14974 }
15023 } 14975 }
15024 14976
@@ -15026,24 +14978,24 @@ namespace WixToolset
15026 { 14978 {
15027 if (CompilerConstants.IntegerNotSet == displayResourceId) 14979 if (CompilerConstants.IntegerNotSet == displayResourceId)
15028 { 14980 {
15029 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayResourceDll", "DisplayResourceId")); 14981 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayResourceDll", "DisplayResourceId"));
15030 } 14982 }
15031 } 14983 }
15032 else 14984 else
15033 { 14985 {
15034 if (CompilerConstants.IntegerNotSet != displayResourceId) 14986 if (CompilerConstants.IntegerNotSet != displayResourceId)
15035 { 14987 {
15036 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayResourceId", "DisplayResourceDll")); 14988 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayResourceId", "DisplayResourceDll"));
15037 } 14989 }
15038 } 14990 }
15039 14991
15040 if (null == name) 14992 if (null == name)
15041 { 14993 {
15042 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 14994 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
15043 } 14995 }
15044 else if (0 < name.Length) 14996 else if (0 < name.Length)
15045 { 14997 {
15046 if (this.core.IsValidShortFilename(name, false)) 14998 if (this.Core.IsValidShortFilename(name, false))
15047 { 14999 {
15048 if (null == shortName) 15000 if (null == shortName)
15049 { 15001 {
@@ -15052,23 +15004,23 @@ namespace WixToolset
15052 } 15004 }
15053 else 15005 else
15054 { 15006 {
15055 this.core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", name, "ShortName")); 15007 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", name, "ShortName"));
15056 } 15008 }
15057 } 15009 }
15058 else if (null == shortName) // generate a short file name. 15010 else if (null == shortName) // generate a short file name.
15059 { 15011 {
15060 shortName = this.core.CreateShortName(name, true, false, node.Name.LocalName, componentId, directory); 15012 shortName = this.Core.CreateShortName(name, true, false, node.Name.LocalName, componentId, directory);
15061 } 15013 }
15062 } 15014 }
15063 15015
15064 if ("Component" != parentElementLocalName && null != target) 15016 if ("Component" != parentElementLocalName && null != target)
15065 { 15017 {
15066 this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "Target", parentElementLocalName)); 15018 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "Target", parentElementLocalName));
15067 } 15019 }
15068 15020
15069 if (null == id) 15021 if (null == id)
15070 { 15022 {
15071 id = this.core.CreateIdentifier("sct", directory, LowercaseOrNull(name) ?? LowercaseOrNull(shortName)); 15023 id = this.Core.CreateIdentifier("sct", directory, LowercaseOrNull(name) ?? LowercaseOrNull(shortName));
15072 } 15024 }
15073 15025
15074 foreach (XElement child in node.Elements()) 15026 foreach (XElement child in node.Elements())
@@ -15084,68 +15036,68 @@ namespace WixToolset
15084 this.ParseShortcutPropertyElement(child, id.Id); 15036 this.ParseShortcutPropertyElement(child, id.Id);
15085 break; 15037 break;
15086 default: 15038 default:
15087 this.core.UnexpectedElement(node, child); 15039 this.Core.UnexpectedElement(node, child);
15088 break; 15040 break;
15089 } 15041 }
15090 } 15042 }
15091 else 15043 else
15092 { 15044 {
15093 this.core.ParseExtensionElement(node, child); 15045 this.Core.ParseExtensionElement(node, child);
15094 } 15046 }
15095 } 15047 }
15096 15048
15097 if (!this.core.EncounteredError) 15049 if (!this.Core.EncounteredError)
15098 { 15050 {
15099 Row row = this.core.CreateRow(sourceLineNumbers, "Shortcut", id); 15051 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Shortcut, id);
15100 row[1] = directory; 15052 row.Set(1, directory);
15101 row[2] = GetMsiFilenameValue(shortName, name); 15053 row.Set(2, GetMsiFilenameValue(shortName, name));
15102 row[3] = componentId; 15054 row.Set(3, componentId);
15103 if (advertise) 15055 if (advertise)
15104 { 15056 {
15105 if (YesNoType.Yes != parentKeyPath && "Component" != parentElementLocalName) 15057 if (YesNoType.Yes != parentKeyPath && "Component" != parentElementLocalName)
15106 { 15058 {
15107 this.core.OnMessage(WixWarnings.UnclearShortcut(sourceLineNumbers, id.Id, componentId, defaultTarget)); 15059 this.Core.OnMessage(WixWarnings.UnclearShortcut(sourceLineNumbers, id.Id, componentId, defaultTarget));
15108 } 15060 }
15109 row[4] = Guid.Empty.ToString("B"); 15061 row.Set(4, Guid.Empty.ToString("B"));
15110 } 15062 }
15111 else if (null != target) 15063 else if (null != target)
15112 { 15064 {
15113 row[4] = target; 15065 row.Set(4, target);
15114 } 15066 }
15115 else if ("Component" == parentElementLocalName || "CreateFolder" == parentElementLocalName) 15067 else if ("Component" == parentElementLocalName || "CreateFolder" == parentElementLocalName)
15116 { 15068 {
15117 row[4] = String.Format(CultureInfo.InvariantCulture, "[{0}]", defaultTarget); 15069 row.Set(4, String.Format(CultureInfo.InvariantCulture, "[{0}]", defaultTarget));
15118 } 15070 }
15119 else if ("File" == parentElementLocalName) 15071 else if ("File" == parentElementLocalName)
15120 { 15072 {
15121 row[4] = String.Format(CultureInfo.InvariantCulture, "[#{0}]", defaultTarget); 15073 row.Set(4, String.Format(CultureInfo.InvariantCulture, "[#{0}]", defaultTarget));
15122 } 15074 }
15123 row[5] = arguments; 15075 row.Set(5, arguments);
15124 row[6] = description; 15076 row.Set(6, description);
15125 if (CompilerConstants.IntegerNotSet != hotkey) 15077 if (CompilerConstants.IntegerNotSet != hotkey)
15126 { 15078 {
15127 row[7] = hotkey; 15079 row.Set(7, hotkey);
15128 } 15080 }
15129 row[8] = icon; 15081 row.Set(8, icon);
15130 if (CompilerConstants.IntegerNotSet != iconIndex) 15082 if (CompilerConstants.IntegerNotSet != iconIndex)
15131 { 15083 {
15132 row[9] = iconIndex; 15084 row.Set(9, iconIndex);
15133 } 15085 }
15134 15086
15135 if (CompilerConstants.IntegerNotSet != show) 15087 if (CompilerConstants.IntegerNotSet != show)
15136 { 15088 {
15137 row[10] = show; 15089 row.Set(10, show);
15138 } 15090 }
15139 row[11] = workingDirectory; 15091 row.Set(11, workingDirectory);
15140 row[12] = displayResourceDll; 15092 row.Set(12, displayResourceDll);
15141 if (CompilerConstants.IntegerNotSet != displayResourceId) 15093 if (CompilerConstants.IntegerNotSet != displayResourceId)
15142 { 15094 {
15143 row[13] = displayResourceId; 15095 row.Set(13, displayResourceId);
15144 } 15096 }
15145 row[14] = descriptionResourceDll; 15097 row.Set(14, descriptionResourceDll);
15146 if (CompilerConstants.IntegerNotSet != descriptionResourceId) 15098 if (CompilerConstants.IntegerNotSet != descriptionResourceId)
15147 { 15099 {
15148 row[15] = descriptionResourceId; 15100 row.Set(15, descriptionResourceId);
15149 } 15101 }
15150 } 15102 }
15151 } 15103 }
@@ -15168,35 +15120,35 @@ namespace WixToolset
15168 switch (attrib.Name.LocalName) 15120 switch (attrib.Name.LocalName)
15169 { 15121 {
15170 case "Id": 15122 case "Id":
15171 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 15123 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
15172 break; 15124 break;
15173 case "Key": 15125 case "Key":
15174 key = this.core.GetAttributeValue(sourceLineNumbers, attrib); 15126 key = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
15175 break; 15127 break;
15176 case "Value": 15128 case "Value":
15177 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 15129 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
15178 break; 15130 break;
15179 default: 15131 default:
15180 this.core.UnexpectedAttribute(node, attrib); 15132 this.Core.UnexpectedAttribute(node, attrib);
15181 break; 15133 break;
15182 } 15134 }
15183 } 15135 }
15184 else 15136 else
15185 { 15137 {
15186 this.core.ParseExtensionAttribute(node, attrib); 15138 this.Core.ParseExtensionAttribute(node, attrib);
15187 } 15139 }
15188 } 15140 }
15189 15141
15190 if (String.IsNullOrEmpty(key)) 15142 if (String.IsNullOrEmpty(key))
15191 { 15143 {
15192 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); 15144 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
15193 } 15145 }
15194 else if (null == id) 15146 else if (null == id)
15195 { 15147 {
15196 id = this.core.CreateIdentifier("scp", shortcutId, key.ToUpperInvariant()); 15148 id = this.Core.CreateIdentifier("scp", shortcutId, key.ToUpperInvariant());
15197 } 15149 }
15198 15150
15199 string innerText = this.core.GetTrimmedInnerText(node); 15151 string innerText = this.Core.GetTrimmedInnerText(node);
15200 if (!String.IsNullOrEmpty(innerText)) 15152 if (!String.IsNullOrEmpty(innerText))
15201 { 15153 {
15202 if (String.IsNullOrEmpty(value)) 15154 if (String.IsNullOrEmpty(value))
@@ -15205,23 +15157,23 @@ namespace WixToolset
15205 } 15157 }
15206 else // cannot specify both the value attribute and inner text 15158 else // cannot specify both the value attribute and inner text
15207 { 15159 {
15208 this.core.OnMessage(WixErrors.IllegalAttributeWithInnerText(sourceLineNumbers, node.Name.LocalName, "Value")); 15160 this.Core.OnMessage(WixErrors.IllegalAttributeWithInnerText(sourceLineNumbers, node.Name.LocalName, "Value"));
15209 } 15161 }
15210 } 15162 }
15211 15163
15212 if (String.IsNullOrEmpty(value)) 15164 if (String.IsNullOrEmpty(value))
15213 { 15165 {
15214 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 15166 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
15215 } 15167 }
15216 15168
15217 this.core.ParseForExtensionElements(node); 15169 this.Core.ParseForExtensionElements(node);
15218 15170
15219 if (!this.core.EncounteredError) 15171 if (!this.Core.EncounteredError)
15220 { 15172 {
15221 Row row = this.core.CreateRow(sourceLineNumbers, "MsiShortcutProperty", id); 15173 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiShortcutProperty, id);
15222 row[1] = shortcutId; 15174 row.Set(1, shortcutId);
15223 row[2] = key; 15175 row.Set(2, key);
15224 row[3] = value; 15176 row.Set(3, value);
15225 } 15177 }
15226 } 15178 }
15227 15179
@@ -15253,75 +15205,75 @@ namespace WixToolset
15253 switch (attrib.Name.LocalName) 15205 switch (attrib.Name.LocalName)
15254 { 15206 {
15255 case "Id": 15207 case "Id":
15256 id = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 15208 id = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
15257 break; 15209 break;
15258 case "Advertise": 15210 case "Advertise":
15259 advertise = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 15211 advertise = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
15260 break; 15212 break;
15261 case "Control": 15213 case "Control":
15262 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 15214 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
15263 { 15215 {
15264 flags |= 2; 15216 flags |= 2;
15265 } 15217 }
15266 break; 15218 break;
15267 case "Cost": 15219 case "Cost":
15268 cost = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 15220 cost = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
15269 break; 15221 break;
15270 case "Description": 15222 case "Description":
15271 description = this.core.GetAttributeValue(sourceLineNumbers, attrib); 15223 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
15272 break; 15224 break;
15273 case "HasDiskImage": 15225 case "HasDiskImage":
15274 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 15226 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
15275 { 15227 {
15276 flags |= 8; 15228 flags |= 8;
15277 } 15229 }
15278 break; 15230 break;
15279 case "HelpDirectory": 15231 case "HelpDirectory":
15280 helpDirectory = this.core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null); 15232 helpDirectory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
15281 break; 15233 break;
15282 case "Hidden": 15234 case "Hidden":
15283 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 15235 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
15284 { 15236 {
15285 flags |= 4; 15237 flags |= 4;
15286 } 15238 }
15287 break; 15239 break;
15288 case "Language": 15240 case "Language":
15289 language = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 15241 language = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
15290 break; 15242 break;
15291 case "MajorVersion": 15243 case "MajorVersion":
15292 majorVersion = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, ushort.MaxValue); 15244 majorVersion = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, ushort.MaxValue);
15293 break; 15245 break;
15294 case "MinorVersion": 15246 case "MinorVersion":
15295 minorVersion = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, byte.MaxValue); 15247 minorVersion = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, byte.MaxValue);
15296 break; 15248 break;
15297 case "ResourceId": 15249 case "ResourceId":
15298 resourceId = this.core.GetAttributeLongValue(sourceLineNumbers, attrib, int.MinValue, int.MaxValue); 15250 resourceId = this.Core.GetAttributeLongValue(sourceLineNumbers, attrib, int.MinValue, int.MaxValue);
15299 break; 15251 break;
15300 case "Restricted": 15252 case "Restricted":
15301 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 15253 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
15302 { 15254 {
15303 flags |= 1; 15255 flags |= 1;
15304 } 15256 }
15305 break; 15257 break;
15306 default: 15258 default:
15307 this.core.UnexpectedAttribute(node, attrib); 15259 this.Core.UnexpectedAttribute(node, attrib);
15308 break; 15260 break;
15309 } 15261 }
15310 } 15262 }
15311 else 15263 else
15312 { 15264 {
15313 this.core.ParseExtensionAttribute(node, attrib); 15265 this.Core.ParseExtensionAttribute(node, attrib);
15314 } 15266 }
15315 } 15267 }
15316 15268
15317 if (null == id) 15269 if (null == id)
15318 { 15270 {
15319 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 15271 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
15320 } 15272 }
15321 15273
15322 if (CompilerConstants.IntegerNotSet == language) 15274 if (CompilerConstants.IntegerNotSet == language)
15323 { 15275 {
15324 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language")); 15276 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language"));
15325 language = CompilerConstants.IllegalInteger; 15277 language = CompilerConstants.IllegalInteger;
15326 } 15278 }
15327 15279
@@ -15370,13 +15322,13 @@ namespace WixToolset
15370 this.ParseInterfaceElement(child, componentId, null, null, id, registryVersion); 15322 this.ParseInterfaceElement(child, componentId, null, null, id, registryVersion);
15371 break; 15323 break;
15372 default: 15324 default:
15373 this.core.UnexpectedElement(node, child); 15325 this.Core.UnexpectedElement(node, child);
15374 break; 15326 break;
15375 } 15327 }
15376 } 15328 }
15377 else 15329 else
15378 { 15330 {
15379 this.core.ParseExtensionElement(node, child); 15331 this.Core.ParseExtensionElement(node, child);
15380 } 15332 }
15381 } 15333 }
15382 15334
@@ -15385,48 +15337,48 @@ namespace WixToolset
15385 { 15337 {
15386 if (CompilerConstants.LongNotSet != resourceId) 15338 if (CompilerConstants.LongNotSet != resourceId)
15387 { 15339 {
15388 this.core.OnMessage(WixErrors.IllegalAttributeWhenAdvertised(sourceLineNumbers, node.Name.LocalName, "ResourceId")); 15340 this.Core.OnMessage(WixErrors.IllegalAttributeWhenAdvertised(sourceLineNumbers, node.Name.LocalName, "ResourceId"));
15389 } 15341 }
15390 15342
15391 if (0 != flags) 15343 if (0 != flags)
15392 { 15344 {
15393 if (0x1 == (flags & 0x1)) 15345 if (0x1 == (flags & 0x1))
15394 { 15346 {
15395 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Restricted", "Advertise", "yes")); 15347 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Restricted", "Advertise", "yes"));
15396 } 15348 }
15397 15349
15398 if (0x2 == (flags & 0x2)) 15350 if (0x2 == (flags & 0x2))
15399 { 15351 {
15400 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Control", "Advertise", "yes")); 15352 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Control", "Advertise", "yes"));
15401 } 15353 }
15402 15354
15403 if (0x4 == (flags & 0x4)) 15355 if (0x4 == (flags & 0x4))
15404 { 15356 {
15405 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Hidden", "Advertise", "yes")); 15357 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Hidden", "Advertise", "yes"));
15406 } 15358 }
15407 15359
15408 if (0x8 == (flags & 0x8)) 15360 if (0x8 == (flags & 0x8))
15409 { 15361 {
15410 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "HasDiskImage", "Advertise", "yes")); 15362 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "HasDiskImage", "Advertise", "yes"));
15411 } 15363 }
15412 } 15364 }
15413 15365
15414 if (!this.core.EncounteredError) 15366 if (!this.Core.EncounteredError)
15415 { 15367 {
15416 Row row = this.core.CreateRow(sourceLineNumbers, "TypeLib"); 15368 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.TypeLib);
15417 row[0] = id; 15369 row.Set(0, id);
15418 row[1] = language; 15370 row.Set(1, language);
15419 row[2] = componentId; 15371 row.Set(2, componentId);
15420 if (CompilerConstants.IntegerNotSet != majorVersion || CompilerConstants.IntegerNotSet != minorVersion) 15372 if (CompilerConstants.IntegerNotSet != majorVersion || CompilerConstants.IntegerNotSet != minorVersion)
15421 { 15373 {
15422 row[3] = (CompilerConstants.IntegerNotSet != majorVersion ? majorVersion * 256 : 0) + (CompilerConstants.IntegerNotSet != minorVersion ? minorVersion : 0); 15374 row.Set(3, (CompilerConstants.IntegerNotSet != majorVersion ? majorVersion * 256 : 0) + (CompilerConstants.IntegerNotSet != minorVersion ? minorVersion : 0));
15423 } 15375 }
15424 row[4] = description; 15376 row.Set(4, description);
15425 row[5] = helpDirectory; 15377 row.Set(5, helpDirectory);
15426 row[6] = Guid.Empty.ToString("B"); 15378 row.Set(6, Guid.Empty.ToString("B"));
15427 if (CompilerConstants.IntegerNotSet != cost) 15379 if (CompilerConstants.IntegerNotSet != cost)
15428 { 15380 {
15429 row[7] = cost; 15381 row.Set(7, cost);
15430 } 15382 }
15431 } 15383 }
15432 } 15384 }
@@ -15434,21 +15386,21 @@ namespace WixToolset
15434 { 15386 {
15435 if (CompilerConstants.IntegerNotSet != cost && CompilerConstants.IllegalInteger != cost) 15387 if (CompilerConstants.IntegerNotSet != cost && CompilerConstants.IllegalInteger != cost)
15436 { 15388 {
15437 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Cost", "Advertise", "no")); 15389 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Cost", "Advertise", "no"));
15438 } 15390 }
15439 15391
15440 if (null == fileServer) 15392 if (null == fileServer)
15441 { 15393 {
15442 this.core.OnMessage(WixErrors.MissingTypeLibFile(sourceLineNumbers, node.Name.LocalName, "File")); 15394 this.Core.OnMessage(WixErrors.MissingTypeLibFile(sourceLineNumbers, node.Name.LocalName, "File"));
15443 } 15395 }
15444 15396
15445 if (null == registryVersion) 15397 if (null == registryVersion)
15446 { 15398 {
15447 this.core.OnMessage(WixErrors.ExpectedAttributesWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "MajorVersion", "MinorVersion", "Advertise", "no")); 15399 this.Core.OnMessage(WixErrors.ExpectedAttributesWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "MajorVersion", "MinorVersion", "Advertise", "no"));
15448 } 15400 }
15449 15401
15450 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion], (Default) = [Description] 15402 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion], (Default) = [Description]
15451 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}", id, registryVersion), null, description, componentId); 15403 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}", id, registryVersion), null, description, componentId);
15452 15404
15453 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\[Language]\[win16|win32|win64], (Default) = [TypeLibPath]\[ResourceId] 15405 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\[Language]\[win16|win32|win64], (Default) = [TypeLibPath]\[ResourceId]
15454 string path = String.Concat("[#", fileServer, "]"); 15406 string path = String.Concat("[#", fileServer, "]");
@@ -15456,15 +15408,15 @@ namespace WixToolset
15456 { 15408 {
15457 path = String.Concat(path, Path.DirectorySeparatorChar, resourceId.ToString(CultureInfo.InvariantCulture.NumberFormat)); 15409 path = String.Concat(path, Path.DirectorySeparatorChar, resourceId.ToString(CultureInfo.InvariantCulture.NumberFormat));
15458 } 15410 }
15459 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\{2}\{3}", id, registryVersion, language, (win64Component ? "win64" : "win32")), null, path, componentId); 15411 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\{2}\{3}", id, registryVersion, language, (win64Component ? "win64" : "win32")), null, path, componentId);
15460 15412
15461 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\FLAGS, (Default) = [TypeLibFlags] 15413 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\FLAGS, (Default) = [TypeLibFlags]
15462 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\FLAGS", id, registryVersion), null, flags.ToString(CultureInfo.InvariantCulture.NumberFormat), componentId); 15414 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\FLAGS", id, registryVersion), null, flags.ToString(CultureInfo.InvariantCulture.NumberFormat), componentId);
15463 15415
15464 if (null != helpDirectory) 15416 if (null != helpDirectory)
15465 { 15417 {
15466 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\HELPDIR, (Default) = [HelpDirectory] 15418 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\HELPDIR, (Default) = [HelpDirectory]
15467 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\HELPDIR", id, registryVersion), null, String.Concat("[", helpDirectory, "]"), componentId); 15419 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\HELPDIR", id, registryVersion), null, String.Concat("[", helpDirectory, "]"), componentId);
15468 } 15420 }
15469 } 15421 }
15470 } 15422 }
@@ -15489,69 +15441,69 @@ namespace WixToolset
15489 switch (attrib.Name.LocalName) 15441 switch (attrib.Name.LocalName)
15490 { 15442 {
15491 case "Id": 15443 case "Id":
15492 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 15444 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
15493 break; 15445 break;
15494 case "BinarySource": 15446 case "BinarySource":
15495 if (null != source) 15447 if (null != source)
15496 { 15448 {
15497 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "FileSource", "PropertySource")); 15449 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "FileSource", "PropertySource"));
15498 } 15450 }
15499 source = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 15451 source = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
15500 type = MsiInterop.MsidbCustomActionTypeExe + MsiInterop.MsidbCustomActionTypeBinaryData; 15452 type = MsiInterop.MsidbCustomActionTypeExe + MsiInterop.MsidbCustomActionTypeBinaryData;
15501 this.core.CreateSimpleReference(sourceLineNumbers, "Binary", source); // add a reference to the appropriate Binary 15453 this.Core.CreateSimpleReference(sourceLineNumbers, "Binary", source); // add a reference to the appropriate Binary
15502 break; 15454 break;
15503 case "CommandLine": 15455 case "CommandLine":
15504 commandLine = this.core.GetAttributeValue(sourceLineNumbers, attrib); 15456 commandLine = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
15505 break; 15457 break;
15506 case "FileSource": 15458 case "FileSource":
15507 if (null != source) 15459 if (null != source)
15508 { 15460 {
15509 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinarySource", "PropertySource")); 15461 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinarySource", "PropertySource"));
15510 } 15462 }
15511 source = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 15463 source = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
15512 type = MsiInterop.MsidbCustomActionTypeExe + MsiInterop.MsidbCustomActionTypeSourceFile; 15464 type = MsiInterop.MsidbCustomActionTypeExe + MsiInterop.MsidbCustomActionTypeSourceFile;
15513 this.core.CreateSimpleReference(sourceLineNumbers, "File", source); // add a reference to the appropriate File 15465 this.Core.CreateSimpleReference(sourceLineNumbers, "File", source); // add a reference to the appropriate File
15514 break; 15466 break;
15515 case "PropertySource": 15467 case "PropertySource":
15516 if (null != source) 15468 if (null != source)
15517 { 15469 {
15518 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinarySource", "FileSource")); 15470 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinarySource", "FileSource"));
15519 } 15471 }
15520 source = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 15472 source = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
15521 type = MsiInterop.MsidbCustomActionTypeExe + MsiInterop.MsidbCustomActionTypeProperty; 15473 type = MsiInterop.MsidbCustomActionTypeExe + MsiInterop.MsidbCustomActionTypeProperty;
15522 // cannot add a reference to a Property because it may be created at runtime. 15474 // cannot add a reference to a Property because it may be created at runtime.
15523 break; 15475 break;
15524 default: 15476 default:
15525 this.core.UnexpectedAttribute(node, attrib); 15477 this.Core.UnexpectedAttribute(node, attrib);
15526 break; 15478 break;
15527 } 15479 }
15528 } 15480 }
15529 else 15481 else
15530 { 15482 {
15531 this.core.ParseExtensionAttribute(node, attrib); 15483 this.Core.ParseExtensionAttribute(node, attrib);
15532 } 15484 }
15533 } 15485 }
15534 15486
15535 // Get the condition from the inner text of the element. 15487 // Get the condition from the inner text of the element.
15536 condition = this.core.GetConditionInnerText(node); 15488 condition = this.Core.GetConditionInnerText(node);
15537 15489
15538 if (null == id) 15490 if (null == id)
15539 { 15491 {
15540 id = this.core.CreateIdentifier("mec", source, type.ToString()); 15492 id = this.Core.CreateIdentifier("mec", source, type.ToString());
15541 } 15493 }
15542 15494
15543 if (null == source) 15495 if (null == source)
15544 { 15496 {
15545 this.core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "BinarySource", "FileSource", "PropertySource")); 15497 this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "BinarySource", "FileSource", "PropertySource"));
15546 } 15498 }
15547 15499
15548 if (!this.core.EncounteredError) 15500 if (!this.Core.EncounteredError)
15549 { 15501 {
15550 Row row = this.core.CreateRow(sourceLineNumbers, "MsiEmbeddedChainer", id); 15502 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiEmbeddedChainer, id);
15551 row[1] = condition; 15503 row.Set(1, condition);
15552 row[2] = commandLine; 15504 row.Set(2, commandLine);
15553 row[3] = source; 15505 row.Set(3, source);
15554 row[4] = type; 15506 row.Set(4, type);
15555 } 15507 }
15556 } 15508 }
15557 15509
@@ -15572,16 +15524,16 @@ namespace WixToolset
15572 switch (attrib.Name.LocalName) 15524 switch (attrib.Name.LocalName)
15573 { 15525 {
15574 case "Id": 15526 case "Id":
15575 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 15527 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
15576 break; 15528 break;
15577 default: 15529 default:
15578 this.core.UnexpectedAttribute(node, attrib); 15530 this.Core.UnexpectedAttribute(node, attrib);
15579 break; 15531 break;
15580 } 15532 }
15581 } 15533 }
15582 else 15534 else
15583 { 15535 {
15584 this.core.ParseExtensionAttribute(node, attrib); 15536 this.Core.ParseExtensionAttribute(node, attrib);
15585 } 15537 }
15586 } 15538 }
15587 15539
@@ -15595,7 +15547,7 @@ namespace WixToolset
15595 this.ParseBillboardActionElement(child); 15547 this.ParseBillboardActionElement(child);
15596 break; 15548 break;
15597 case "ComboBox": 15549 case "ComboBox":
15598 this.ParseControlGroupElement(child, this.tableDefinitions["ComboBox"], "ListItem"); 15550 this.ParseControlGroupElement(child, TupleDefinitionType.ComboBox, "ListItem");
15599 break; 15551 break;
15600 case "Dialog": 15552 case "Dialog":
15601 this.ParseDialogElement(child); 15553 this.ParseDialogElement(child);
@@ -15607,7 +15559,7 @@ namespace WixToolset
15607 if (0 < embeddedUICount) // there can be only one embedded UI 15559 if (0 < embeddedUICount) // there can be only one embedded UI
15608 { 15560 {
15609 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); 15561 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
15610 this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName)); 15562 this.Core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName));
15611 } 15563 }
15612 this.ParseEmbeddedUIElement(child); 15564 this.ParseEmbeddedUIElement(child);
15613 ++embeddedUICount; 15565 ++embeddedUICount;
@@ -15616,10 +15568,10 @@ namespace WixToolset
15616 this.ParseErrorElement(child); 15568 this.ParseErrorElement(child);
15617 break; 15569 break;
15618 case "ListBox": 15570 case "ListBox":
15619 this.ParseControlGroupElement(child, this.tableDefinitions["ListBox"], "ListItem"); 15571 this.ParseControlGroupElement(child, TupleDefinitionType.ListBox, "ListItem");
15620 break; 15572 break;
15621 case "ListView": 15573 case "ListView":
15622 this.ParseControlGroupElement(child, this.tableDefinitions["ListView"], "ListItem"); 15574 this.ParseControlGroupElement(child, TupleDefinitionType.ListView, "ListItem");
15623 break; 15575 break;
15624 case "ProgressText": 15576 case "ProgressText":
15625 this.ParseActionTextElement(child); 15577 this.ParseActionTextElement(child);
@@ -15633,7 +15585,7 @@ namespace WixToolset
15633 if (RadioButtonType.Bitmap == radioButtonType || RadioButtonType.Icon == radioButtonType) 15585 if (RadioButtonType.Bitmap == radioButtonType || RadioButtonType.Icon == radioButtonType)
15634 { 15586 {
15635 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); 15587 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
15636 this.core.OnMessage(WixErrors.RadioButtonBitmapAndIconDisallowed(childSourceLineNumbers)); 15588 this.Core.OnMessage(WixErrors.RadioButtonBitmapAndIconDisallowed(childSourceLineNumbers));
15637 } 15589 }
15638 break; 15590 break;
15639 case "TextStyle": 15591 case "TextStyle":
@@ -15662,19 +15614,19 @@ namespace WixToolset
15662 break; 15614 break;
15663 15615
15664 default: 15616 default:
15665 this.core.UnexpectedElement(node, child); 15617 this.Core.UnexpectedElement(node, child);
15666 break; 15618 break;
15667 } 15619 }
15668 } 15620 }
15669 else 15621 else
15670 { 15622 {
15671 this.core.ParseExtensionElement(node, child); 15623 this.Core.ParseExtensionElement(node, child);
15672 } 15624 }
15673 } 15625 }
15674 15626
15675 if (null != id && !this.core.EncounteredError) 15627 if (null != id && !this.Core.EncounteredError)
15676 { 15628 {
15677 this.core.CreateRow(sourceLineNumbers, "WixUI", id); 15629 this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixUI, id);
15678 } 15630 }
15679 } 15631 }
15680 15632
@@ -15685,7 +15637,7 @@ namespace WixToolset
15685 /// <param name="table">Table to add row to.</param> 15637 /// <param name="table">Table to add row to.</param>
15686 /// <param name="property">Identifier of property referred to by list item.</param> 15638 /// <param name="property">Identifier of property referred to by list item.</param>
15687 /// <param name="order">Relative order of list items.</param> 15639 /// <param name="order">Relative order of list items.</param>
15688 private void ParseListItemElement(XElement node, TableDefinition table, string property, ref int order) 15640 private void ParseListItemElement(XElement node, TupleDefinitionType tableName, string property, ref int order)
15689 { 15641 {
15690 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 15642 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
15691 string icon = null; 15643 string icon = null;
@@ -15699,50 +15651,50 @@ namespace WixToolset
15699 switch (attrib.Name.LocalName) 15651 switch (attrib.Name.LocalName)
15700 { 15652 {
15701 case "Icon": 15653 case "Icon":
15702 if ("ListView" == table.Name) 15654 if (TupleDefinitionType.ListView == tableName)
15703 { 15655 {
15704 icon = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 15656 icon = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
15705 this.core.CreateSimpleReference(sourceLineNumbers, "Binary", icon); 15657 this.Core.CreateSimpleReference(sourceLineNumbers, "Binary", icon);
15706 } 15658 }
15707 else 15659 else
15708 { 15660 {
15709 this.core.OnMessage(WixErrors.IllegalAttributeExceptOnElement(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ListView")); 15661 this.Core.OnMessage(WixErrors.IllegalAttributeExceptOnElement(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ListView"));
15710 } 15662 }
15711 break; 15663 break;
15712 case "Text": 15664 case "Text":
15713 text = this.core.GetAttributeValue(sourceLineNumbers, attrib); 15665 text = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
15714 break; 15666 break;
15715 case "Value": 15667 case "Value":
15716 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 15668 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
15717 break; 15669 break;
15718 default: 15670 default:
15719 this.core.UnexpectedAttribute(node, attrib); 15671 this.Core.UnexpectedAttribute(node, attrib);
15720 break; 15672 break;
15721 } 15673 }
15722 } 15674 }
15723 else 15675 else
15724 { 15676 {
15725 this.core.ParseExtensionAttribute(node, attrib); 15677 this.Core.ParseExtensionAttribute(node, attrib);
15726 } 15678 }
15727 } 15679 }
15728 15680
15729 if (null == value) 15681 if (null == value)
15730 { 15682 {
15731 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 15683 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
15732 } 15684 }
15733 15685
15734 this.core.ParseForExtensionElements(node); 15686 this.Core.ParseForExtensionElements(node);
15735 15687
15736 if (!this.core.EncounteredError) 15688 if (!this.Core.EncounteredError)
15737 { 15689 {
15738 Row row = this.core.CreateRow(sourceLineNumbers, table.Name); 15690 var row = this.Core.CreateRow(sourceLineNumbers, tableName);
15739 row[0] = property; 15691 row.Set(0, property);
15740 row[1] = ++order; 15692 row.Set(1, ++order);
15741 row[2] = value; 15693 row.Set(2, value);
15742 row[3] = text; 15694 row.Set(3, text);
15743 if (null != icon) 15695 if (null != icon)
15744 { 15696 {
15745 row[4] = icon; 15697 row.Set(4, icon);
15746 } 15698 }
15747 } 15699 }
15748 } 15700 }
@@ -15776,102 +15728,102 @@ namespace WixToolset
15776 case "Bitmap": 15728 case "Bitmap":
15777 if (RadioButtonType.NotSet != type) 15729 if (RadioButtonType.NotSet != type)
15778 { 15730 {
15779 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Icon", "Text")); 15731 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Icon", "Text"));
15780 } 15732 }
15781 text = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 15733 text = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
15782 this.core.CreateSimpleReference(sourceLineNumbers, "Binary", text); 15734 this.Core.CreateSimpleReference(sourceLineNumbers, "Binary", text);
15783 type = RadioButtonType.Bitmap; 15735 type = RadioButtonType.Bitmap;
15784 break; 15736 break;
15785 case "Height": 15737 case "Height":
15786 height = this.core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 15738 height = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
15787 break; 15739 break;
15788 case "Help": 15740 case "Help":
15789 help = this.core.GetAttributeValue(sourceLineNumbers, attrib); 15741 help = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
15790 break; 15742 break;
15791 case "Icon": 15743 case "Icon":
15792 if (RadioButtonType.NotSet != type) 15744 if (RadioButtonType.NotSet != type)
15793 { 15745 {
15794 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Bitmap", "Text")); 15746 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Bitmap", "Text"));
15795 } 15747 }
15796 text = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 15748 text = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
15797 this.core.CreateSimpleReference(sourceLineNumbers, "Binary", text); 15749 this.Core.CreateSimpleReference(sourceLineNumbers, "Binary", text);
15798 type = RadioButtonType.Icon; 15750 type = RadioButtonType.Icon;
15799 break; 15751 break;
15800 case "Text": 15752 case "Text":
15801 if (RadioButtonType.NotSet != type) 15753 if (RadioButtonType.NotSet != type)
15802 { 15754 {
15803 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Bitmap", "Icon")); 15755 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Bitmap", "Icon"));
15804 } 15756 }
15805 text = this.core.GetAttributeValue(sourceLineNumbers, attrib); 15757 text = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
15806 type = RadioButtonType.Text; 15758 type = RadioButtonType.Text;
15807 break; 15759 break;
15808 case "ToolTip": 15760 case "ToolTip":
15809 tooltip = this.core.GetAttributeValue(sourceLineNumbers, attrib); 15761 tooltip = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
15810 break; 15762 break;
15811 case "Value": 15763 case "Value":
15812 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 15764 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
15813 break; 15765 break;
15814 case "Width": 15766 case "Width":
15815 width = this.core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 15767 width = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
15816 break; 15768 break;
15817 case "X": 15769 case "X":
15818 x = this.core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 15770 x = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
15819 break; 15771 break;
15820 case "Y": 15772 case "Y":
15821 y = this.core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 15773 y = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
15822 break; 15774 break;
15823 default: 15775 default:
15824 this.core.UnexpectedAttribute(node, attrib); 15776 this.Core.UnexpectedAttribute(node, attrib);
15825 break; 15777 break;
15826 } 15778 }
15827 } 15779 }
15828 else 15780 else
15829 { 15781 {
15830 this.core.ParseExtensionAttribute(node, attrib); 15782 this.Core.ParseExtensionAttribute(node, attrib);
15831 } 15783 }
15832 } 15784 }
15833 15785
15834 if (null == value) 15786 if (null == value)
15835 { 15787 {
15836 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 15788 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
15837 } 15789 }
15838 15790
15839 if (null == x) 15791 if (null == x)
15840 { 15792 {
15841 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "X")); 15793 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "X"));
15842 } 15794 }
15843 15795
15844 if (null == y) 15796 if (null == y)
15845 { 15797 {
15846 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Y")); 15798 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Y"));
15847 } 15799 }
15848 15800
15849 if (null == width) 15801 if (null == width)
15850 { 15802 {
15851 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Width")); 15803 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Width"));
15852 } 15804 }
15853 15805
15854 if (null == height) 15806 if (null == height)
15855 { 15807 {
15856 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Height")); 15808 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Height"));
15857 } 15809 }
15858 15810
15859 this.core.ParseForExtensionElements(node); 15811 this.Core.ParseForExtensionElements(node);
15860 15812
15861 if (!this.core.EncounteredError) 15813 if (!this.Core.EncounteredError)
15862 { 15814 {
15863 Row row = this.core.CreateRow(sourceLineNumbers, "RadioButton"); 15815 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RadioButton);
15864 row[0] = property; 15816 row.Set(0, property);
15865 row[1] = ++order; 15817 row.Set(1, ++order);
15866 row[2] = value; 15818 row.Set(2, value);
15867 row[3] = x; 15819 row.Set(3, x);
15868 row[4] = y; 15820 row.Set(4, y);
15869 row[5] = width; 15821 row.Set(5, width);
15870 row[6] = height; 15822 row.Set(6, height);
15871 row[7] = text; 15823 row.Set(7, text);
15872 if (null != tooltip || null != help) 15824 if (null != tooltip || null != help)
15873 { 15825 {
15874 row[8] = String.Concat(tooltip, "|", help); 15826 row.Set(8, String.Concat(tooltip, "|", help));
15875 } 15827 }
15876 } 15828 }
15877 15829
@@ -15895,23 +15847,23 @@ namespace WixToolset
15895 switch (attrib.Name.LocalName) 15847 switch (attrib.Name.LocalName)
15896 { 15848 {
15897 case "Id": 15849 case "Id":
15898 action = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 15850 action = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
15899 this.core.CreateSimpleReference(sourceLineNumbers, "WixAction", "InstallExecuteSequence", action); 15851 this.Core.CreateSimpleReference(sourceLineNumbers, "WixAction", "InstallExecuteSequence", action);
15900 break; 15852 break;
15901 default: 15853 default:
15902 this.core.UnexpectedAttribute(node, attrib); 15854 this.Core.UnexpectedAttribute(node, attrib);
15903 break; 15855 break;
15904 } 15856 }
15905 } 15857 }
15906 else 15858 else
15907 { 15859 {
15908 this.core.ParseExtensionAttribute(node, attrib); 15860 this.Core.ParseExtensionAttribute(node, attrib);
15909 } 15861 }
15910 } 15862 }
15911 15863
15912 if (null == action) 15864 if (null == action)
15913 { 15865 {
15914 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 15866 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
15915 } 15867 }
15916 15868
15917 foreach (XElement child in node.Elements()) 15869 foreach (XElement child in node.Elements())
@@ -15925,13 +15877,13 @@ namespace WixToolset
15925 this.ParseBillboardElement(child, action, order); 15877 this.ParseBillboardElement(child, action, order);
15926 break; 15878 break;
15927 default: 15879 default:
15928 this.core.UnexpectedElement(node, child); 15880 this.Core.UnexpectedElement(node, child);
15929 break; 15881 break;
15930 } 15882 }
15931 } 15883 }
15932 else 15884 else
15933 { 15885 {
15934 this.core.ParseExtensionElement(node, child); 15886 this.Core.ParseExtensionElement(node, child);
15935 } 15887 }
15936 } 15888 }
15937 } 15889 }
@@ -15955,26 +15907,26 @@ namespace WixToolset
15955 switch (attrib.Name.LocalName) 15907 switch (attrib.Name.LocalName)
15956 { 15908 {
15957 case "Id": 15909 case "Id":
15958 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 15910 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
15959 break; 15911 break;
15960 case "Feature": 15912 case "Feature":
15961 feature = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 15913 feature = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
15962 this.core.CreateSimpleReference(sourceLineNumbers, "Feature", feature); 15914 this.Core.CreateSimpleReference(sourceLineNumbers, "Feature", feature);
15963 break; 15915 break;
15964 default: 15916 default:
15965 this.core.UnexpectedAttribute(node, attrib); 15917 this.Core.UnexpectedAttribute(node, attrib);
15966 break; 15918 break;
15967 } 15919 }
15968 } 15920 }
15969 else 15921 else
15970 { 15922 {
15971 this.core.ParseExtensionAttribute(node, attrib); 15923 this.Core.ParseExtensionAttribute(node, attrib);
15972 } 15924 }
15973 } 15925 }
15974 15926
15975 if (null == id) 15927 if (null == id)
15976 { 15928 {
15977 id = this.core.CreateIdentifier("bil", action, order.ToString(), feature); 15929 id = this.Core.CreateIdentifier("bil", action, order.ToString(), feature);
15978 } 15930 }
15979 15931
15980 foreach (XElement child in node.Elements()) 15932 foreach (XElement child in node.Elements())
@@ -15985,31 +15937,31 @@ namespace WixToolset
15985 { 15937 {
15986 case "Control": 15938 case "Control":
15987 // These are all thrown away. 15939 // These are all thrown away.
15988 Row lastTabRow = null; 15940 IntermediateTuple lastTabRow = null;
15989 string firstControl = null; 15941 string firstControl = null;
15990 string defaultControl = null; 15942 string defaultControl = null;
15991 string cancelControl = null; 15943 string cancelControl = null;
15992 15944
15993 this.ParseControlElement(child, id.Id, this.tableDefinitions["BBControl"], ref lastTabRow, ref firstControl, ref defaultControl, ref cancelControl, false); 15945 this.ParseControlElement(child, id.Id, TupleDefinitionType.BBControl, ref lastTabRow, ref firstControl, ref defaultControl, ref cancelControl, false);
15994 break; 15946 break;
15995 default: 15947 default:
15996 this.core.UnexpectedElement(node, child); 15948 this.Core.UnexpectedElement(node, child);
15997 break; 15949 break;
15998 } 15950 }
15999 } 15951 }
16000 else 15952 else
16001 { 15953 {
16002 this.core.ParseExtensionElement(node, child); 15954 this.Core.ParseExtensionElement(node, child);
16003 } 15955 }
16004 } 15956 }
16005 15957
16006 15958
16007 if (!this.core.EncounteredError) 15959 if (!this.Core.EncounteredError)
16008 { 15960 {
16009 Row row = this.core.CreateRow(sourceLineNumbers, "Billboard", id); 15961 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Billboard, id);
16010 row[1] = feature; 15962 row.Set(1, feature);
16011 row[2] = action; 15963 row.Set(2, action);
16012 row[3] = order; 15964 row.Set(3, order);
16013 } 15965 }
16014 } 15966 }
16015 15967
@@ -16019,7 +15971,7 @@ namespace WixToolset
16019 /// <param name="node">Element to parse.</param> 15971 /// <param name="node">Element to parse.</param>
16020 /// <param name="table">Table referred to by control group.</param> 15972 /// <param name="table">Table referred to by control group.</param>
16021 /// <param name="childTag">Expected child elements.</param> 15973 /// <param name="childTag">Expected child elements.</param>
16022 private void ParseControlGroupElement(XElement node, TableDefinition table, string childTag) 15974 private void ParseControlGroupElement(XElement node, TupleDefinitionType tableName, string childTag)
16023 { 15975 {
16024 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 15976 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
16025 int order = 0; 15977 int order = 0;
@@ -16032,22 +15984,22 @@ namespace WixToolset
16032 switch (attrib.Name.LocalName) 15984 switch (attrib.Name.LocalName)
16033 { 15985 {
16034 case "Property": 15986 case "Property":
16035 property = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 15987 property = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
16036 break; 15988 break;
16037 default: 15989 default:
16038 this.core.UnexpectedAttribute(node, attrib); 15990 this.Core.UnexpectedAttribute(node, attrib);
16039 break; 15991 break;
16040 } 15992 }
16041 } 15993 }
16042 else 15994 else
16043 { 15995 {
16044 this.core.ParseExtensionAttribute(node, attrib); 15996 this.Core.ParseExtensionAttribute(node, attrib);
16045 } 15997 }
16046 } 15998 }
16047 15999
16048 if (null == property) 16000 if (null == property)
16049 { 16001 {
16050 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property")); 16002 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property"));
16051 } 16003 }
16052 16004
16053 foreach (XElement child in node.Elements()) 16005 foreach (XElement child in node.Elements())
@@ -16056,25 +16008,25 @@ namespace WixToolset
16056 { 16008 {
16057 if (childTag != child.Name.LocalName) 16009 if (childTag != child.Name.LocalName)
16058 { 16010 {
16059 this.core.UnexpectedElement(node, child); 16011 this.Core.UnexpectedElement(node, child);
16060 } 16012 }
16061 16013
16062 switch (child.Name.LocalName) 16014 switch (child.Name.LocalName)
16063 { 16015 {
16064 case "ListItem": 16016 case "ListItem":
16065 this.ParseListItemElement(child, table, property, ref order); 16017 this.ParseListItemElement(child, tableName, property, ref order);
16066 break; 16018 break;
16067 case "Property": 16019 case "Property":
16068 this.ParsePropertyElement(child); 16020 this.ParsePropertyElement(child);
16069 break; 16021 break;
16070 default: 16022 default:
16071 this.core.UnexpectedElement(node, child); 16023 this.Core.UnexpectedElement(node, child);
16072 break; 16024 break;
16073 } 16025 }
16074 } 16026 }
16075 else 16027 else
16076 { 16028 {
16077 this.core.ParseExtensionElement(node, child); 16029 this.Core.ParseExtensionElement(node, child);
16078 } 16030 }
16079 } 16031 }
16080 16032
@@ -16099,23 +16051,23 @@ namespace WixToolset
16099 switch (attrib.Name.LocalName) 16051 switch (attrib.Name.LocalName)
16100 { 16052 {
16101 case "Property": 16053 case "Property":
16102 property = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 16054 property = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
16103 this.core.CreateSimpleReference(sourceLineNumbers, "Property", property); 16055 this.Core.CreateSimpleReference(sourceLineNumbers, "Property", property);
16104 break; 16056 break;
16105 default: 16057 default:
16106 this.core.UnexpectedAttribute(node, attrib); 16058 this.Core.UnexpectedAttribute(node, attrib);
16107 break; 16059 break;
16108 } 16060 }
16109 } 16061 }
16110 else 16062 else
16111 { 16063 {
16112 this.core.ParseExtensionAttribute(node, attrib); 16064 this.Core.ParseExtensionAttribute(node, attrib);
16113 } 16065 }
16114 } 16066 }
16115 16067
16116 if (null == property) 16068 if (null == property)
16117 { 16069 {
16118 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property")); 16070 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property"));
16119 } 16071 }
16120 16072
16121 foreach (XElement child in node.Elements()) 16073 foreach (XElement child in node.Elements())
@@ -16133,17 +16085,17 @@ namespace WixToolset
16133 else if (groupType != type) 16085 else if (groupType != type)
16134 { 16086 {
16135 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); 16087 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
16136 this.core.OnMessage(WixErrors.RadioButtonTypeInconsistent(childSourceLineNumbers)); 16088 this.Core.OnMessage(WixErrors.RadioButtonTypeInconsistent(childSourceLineNumbers));
16137 } 16089 }
16138 break; 16090 break;
16139 default: 16091 default:
16140 this.core.UnexpectedElement(node, child); 16092 this.Core.UnexpectedElement(node, child);
16141 break; 16093 break;
16142 } 16094 }
16143 } 16095 }
16144 else 16096 else
16145 { 16097 {
16146 this.core.ParseExtensionElement(node, child); 16098 this.Core.ParseExtensionElement(node, child);
16147 } 16099 }
16148 } 16100 }
16149 16101
@@ -16168,35 +16120,35 @@ namespace WixToolset
16168 switch (attrib.Name.LocalName) 16120 switch (attrib.Name.LocalName)
16169 { 16121 {
16170 case "Action": 16122 case "Action":
16171 action = this.core.GetAttributeValue(sourceLineNumbers, attrib); 16123 action = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
16172 break; 16124 break;
16173 case "Template": 16125 case "Template":
16174 template = this.core.GetAttributeValue(sourceLineNumbers, attrib); 16126 template = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
16175 break; 16127 break;
16176 default: 16128 default:
16177 this.core.UnexpectedAttribute(node, attrib); 16129 this.Core.UnexpectedAttribute(node, attrib);
16178 break; 16130 break;
16179 } 16131 }
16180 } 16132 }
16181 else 16133 else
16182 { 16134 {
16183 this.core.ParseExtensionAttribute(node, attrib); 16135 this.Core.ParseExtensionAttribute(node, attrib);
16184 } 16136 }
16185 } 16137 }
16186 16138
16187 if (null == action) 16139 if (null == action)
16188 { 16140 {
16189 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Action")); 16141 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Action"));
16190 } 16142 }
16191 16143
16192 this.core.ParseForExtensionElements(node); 16144 this.Core.ParseForExtensionElements(node);
16193 16145
16194 if (!this.core.EncounteredError) 16146 if (!this.Core.EncounteredError)
16195 { 16147 {
16196 Row row = this.core.CreateRow(sourceLineNumbers, "ActionText"); 16148 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ActionText);
16197 row[0] = action; 16149 row.Set(0, action);
16198 row[1] = Common.GetInnerText(node); 16150 row.Set(1, Common.GetInnerText(node));
16199 row[2] = template; 16151 row.Set(2, template);
16200 } 16152 }
16201 } 16153 }
16202 16154
@@ -16217,16 +16169,16 @@ namespace WixToolset
16217 switch (attrib.Name.LocalName) 16169 switch (attrib.Name.LocalName)
16218 { 16170 {
16219 case "Id": 16171 case "Id":
16220 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 16172 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
16221 break; 16173 break;
16222 default: 16174 default:
16223 this.core.UnexpectedAttribute(node, attrib); 16175 this.Core.UnexpectedAttribute(node, attrib);
16224 break; 16176 break;
16225 } 16177 }
16226 } 16178 }
16227 else 16179 else
16228 { 16180 {
16229 this.core.ParseExtensionAttribute(node, attrib); 16181 this.Core.ParseExtensionAttribute(node, attrib);
16230 } 16182 }
16231 } 16183 }
16232 16184
@@ -16234,15 +16186,15 @@ namespace WixToolset
16234 16186
16235 if (null == id) 16187 if (null == id)
16236 { 16188 {
16237 id = this.core.CreateIdentifier("txt", text); 16189 id = this.Core.CreateIdentifier("txt", text);
16238 } 16190 }
16239 16191
16240 this.core.ParseForExtensionElements(node); 16192 this.Core.ParseForExtensionElements(node);
16241 16193
16242 if (!this.core.EncounteredError) 16194 if (!this.Core.EncounteredError)
16243 { 16195 {
16244 Row row = this.core.CreateRow(sourceLineNumbers, "UIText", id); 16196 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.UIText, id);
16245 row[1] = text; 16197 row.Set(1, text);
16246 } 16198 }
16247 } 16199 }
16248 16200
@@ -16266,12 +16218,12 @@ namespace WixToolset
16266 switch (attrib.Name.LocalName) 16218 switch (attrib.Name.LocalName)
16267 { 16219 {
16268 case "Id": 16220 case "Id":
16269 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 16221 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
16270 break; 16222 break;
16271 16223
16272 // RGB Values 16224 // RGB Values
16273 case "Red": 16225 case "Red":
16274 int redColor = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, byte.MaxValue); 16226 int redColor = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, byte.MaxValue);
16275 if (CompilerConstants.IllegalInteger != redColor) 16227 if (CompilerConstants.IllegalInteger != redColor)
16276 { 16228 {
16277 if (CompilerConstants.IntegerNotSet == color) 16229 if (CompilerConstants.IntegerNotSet == color)
@@ -16285,7 +16237,7 @@ namespace WixToolset
16285 } 16237 }
16286 break; 16238 break;
16287 case "Green": 16239 case "Green":
16288 int greenColor = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, byte.MaxValue); 16240 int greenColor = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, byte.MaxValue);
16289 if (CompilerConstants.IllegalInteger != greenColor) 16241 if (CompilerConstants.IllegalInteger != greenColor)
16290 { 16242 {
16291 if (CompilerConstants.IntegerNotSet == color) 16243 if (CompilerConstants.IntegerNotSet == color)
@@ -16299,7 +16251,7 @@ namespace WixToolset
16299 } 16251 }
16300 break; 16252 break;
16301 case "Blue": 16253 case "Blue":
16302 int blueColor = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, byte.MaxValue); 16254 int blueColor = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, byte.MaxValue);
16303 if (CompilerConstants.IllegalInteger != blueColor) 16255 if (CompilerConstants.IllegalInteger != blueColor)
16304 { 16256 {
16305 if (CompilerConstants.IntegerNotSet == color) 16257 if (CompilerConstants.IntegerNotSet == color)
@@ -16315,25 +16267,25 @@ namespace WixToolset
16315 16267
16316 // Style values 16268 // Style values
16317 case "Bold": 16269 case "Bold":
16318 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16270 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16319 { 16271 {
16320 bits |= MsiInterop.MsidbTextStyleStyleBitsBold; 16272 bits |= MsiInterop.MsidbTextStyleStyleBitsBold;
16321 } 16273 }
16322 break; 16274 break;
16323 case "Italic": 16275 case "Italic":
16324 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16276 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16325 { 16277 {
16326 bits |= MsiInterop.MsidbTextStyleStyleBitsItalic; 16278 bits |= MsiInterop.MsidbTextStyleStyleBitsItalic;
16327 } 16279 }
16328 break; 16280 break;
16329 case "Strike": 16281 case "Strike":
16330 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16282 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16331 { 16283 {
16332 bits |= MsiInterop.MsidbTextStyleStyleBitsStrike; 16284 bits |= MsiInterop.MsidbTextStyleStyleBitsStrike;
16333 } 16285 }
16334 break; 16286 break;
16335 case "Underline": 16287 case "Underline":
16336 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16288 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16337 { 16289 {
16338 bits |= MsiInterop.MsidbTextStyleStyleBitsUnderline; 16290 bits |= MsiInterop.MsidbTextStyleStyleBitsUnderline;
16339 } 16291 }
@@ -16341,48 +16293,48 @@ namespace WixToolset
16341 16293
16342 // Font values 16294 // Font values
16343 case "FaceName": 16295 case "FaceName":
16344 faceName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 16296 faceName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
16345 break; 16297 break;
16346 case "Size": 16298 case "Size":
16347 size = this.core.GetAttributeValue(sourceLineNumbers, attrib); 16299 size = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
16348 break; 16300 break;
16349 16301
16350 default: 16302 default:
16351 this.core.UnexpectedAttribute(node, attrib); 16303 this.Core.UnexpectedAttribute(node, attrib);
16352 break; 16304 break;
16353 } 16305 }
16354 } 16306 }
16355 else 16307 else
16356 { 16308 {
16357 this.core.ParseExtensionAttribute(node, attrib); 16309 this.Core.ParseExtensionAttribute(node, attrib);
16358 } 16310 }
16359 } 16311 }
16360 16312
16361 if (null == id) 16313 if (null == id)
16362 { 16314 {
16363 this.core.CreateIdentifier("txs", faceName, size.ToString(), color.ToString(), bits.ToString()); 16315 this.Core.CreateIdentifier("txs", faceName, size.ToString(), color.ToString(), bits.ToString());
16364 } 16316 }
16365 16317
16366 if (null == faceName) 16318 if (null == faceName)
16367 { 16319 {
16368 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "FaceName")); 16320 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "FaceName"));
16369 } 16321 }
16370 16322
16371 this.core.ParseForExtensionElements(node); 16323 this.Core.ParseForExtensionElements(node);
16372 16324
16373 if (!this.core.EncounteredError) 16325 if (!this.Core.EncounteredError)
16374 { 16326 {
16375 Row row = this.core.CreateRow(sourceLineNumbers, "TextStyle", id); 16327 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.TextStyle, id);
16376 row[1] = faceName; 16328 row.Set(1, faceName);
16377 row[2] = size; 16329 row.Set(2, size);
16378 if (0 <= color) 16330 if (0 <= color)
16379 { 16331 {
16380 row[3] = color; 16332 row.Set(3, color);
16381 } 16333 }
16382 16334
16383 if (0 < bits) 16335 if (0 < bits)
16384 { 16336 {
16385 row[4] = bits; 16337 row.Set(4, bits);
16386 } 16338 }
16387 } 16339 }
16388 } 16340 }
@@ -16410,86 +16362,86 @@ namespace WixToolset
16410 switch (attrib.Name.LocalName) 16362 switch (attrib.Name.LocalName)
16411 { 16363 {
16412 case "Id": 16364 case "Id":
16413 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 16365 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
16414 break; 16366 break;
16415 case "Height": 16367 case "Height":
16416 height = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 16368 height = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
16417 break; 16369 break;
16418 case "Title": 16370 case "Title":
16419 title = this.core.GetAttributeValue(sourceLineNumbers, attrib); 16371 title = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
16420 break; 16372 break;
16421 case "Width": 16373 case "Width":
16422 width = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 16374 width = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
16423 break; 16375 break;
16424 case "X": 16376 case "X":
16425 x = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 100); 16377 x = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 100);
16426 break; 16378 break;
16427 case "Y": 16379 case "Y":
16428 y = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 100); 16380 y = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 100);
16429 break; 16381 break;
16430 16382
16431 case "CustomPalette": 16383 case "CustomPalette":
16432 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16384 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16433 { 16385 {
16434 bits ^= MsiInterop.MsidbDialogAttributesUseCustomPalette; 16386 bits ^= MsiInterop.MsidbDialogAttributesUseCustomPalette;
16435 } 16387 }
16436 break; 16388 break;
16437 case "ErrorDialog": 16389 case "ErrorDialog":
16438 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16390 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16439 { 16391 {
16440 bits ^= MsiInterop.MsidbDialogAttributesError; 16392 bits ^= MsiInterop.MsidbDialogAttributesError;
16441 } 16393 }
16442 break; 16394 break;
16443 case "Hidden": 16395 case "Hidden":
16444 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16396 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16445 { 16397 {
16446 bits ^= MsiInterop.MsidbDialogAttributesVisible; 16398 bits ^= MsiInterop.MsidbDialogAttributesVisible;
16447 } 16399 }
16448 break; 16400 break;
16449 case "KeepModeless": 16401 case "KeepModeless":
16450 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16402 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16451 { 16403 {
16452 bits ^= MsiInterop.MsidbDialogAttributesKeepModeless; 16404 bits ^= MsiInterop.MsidbDialogAttributesKeepModeless;
16453 } 16405 }
16454 break; 16406 break;
16455 case "LeftScroll": 16407 case "LeftScroll":
16456 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16408 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16457 { 16409 {
16458 bits ^= MsiInterop.MsidbDialogAttributesLeftScroll; 16410 bits ^= MsiInterop.MsidbDialogAttributesLeftScroll;
16459 } 16411 }
16460 break; 16412 break;
16461 case "Modeless": 16413 case "Modeless":
16462 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16414 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16463 { 16415 {
16464 bits ^= MsiInterop.MsidbDialogAttributesModal; 16416 bits ^= MsiInterop.MsidbDialogAttributesModal;
16465 } 16417 }
16466 break; 16418 break;
16467 case "NoMinimize": 16419 case "NoMinimize":
16468 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16420 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16469 { 16421 {
16470 bits ^= MsiInterop.MsidbDialogAttributesMinimize; 16422 bits ^= MsiInterop.MsidbDialogAttributesMinimize;
16471 } 16423 }
16472 break; 16424 break;
16473 case "RightAligned": 16425 case "RightAligned":
16474 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16426 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16475 { 16427 {
16476 bits ^= MsiInterop.MsidbDialogAttributesRightAligned; 16428 bits ^= MsiInterop.MsidbDialogAttributesRightAligned;
16477 } 16429 }
16478 break; 16430 break;
16479 case "RightToLeft": 16431 case "RightToLeft":
16480 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16432 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16481 { 16433 {
16482 bits ^= MsiInterop.MsidbDialogAttributesRTLRO; 16434 bits ^= MsiInterop.MsidbDialogAttributesRTLRO;
16483 } 16435 }
16484 break; 16436 break;
16485 case "SystemModal": 16437 case "SystemModal":
16486 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16438 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16487 { 16439 {
16488 bits ^= MsiInterop.MsidbDialogAttributesSysModal; 16440 bits ^= MsiInterop.MsidbDialogAttributesSysModal;
16489 } 16441 }
16490 break; 16442 break;
16491 case "TrackDiskSpace": 16443 case "TrackDiskSpace":
16492 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16444 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16493 { 16445 {
16494 bits ^= MsiInterop.MsidbDialogAttributesTrackDiskSpace; 16446 bits ^= MsiInterop.MsidbDialogAttributesTrackDiskSpace;
16495 trackDiskSpace = true; 16447 trackDiskSpace = true;
@@ -16497,23 +16449,23 @@ namespace WixToolset
16497 break; 16449 break;
16498 16450
16499 default: 16451 default:
16500 this.core.UnexpectedAttribute(node, attrib); 16452 this.Core.UnexpectedAttribute(node, attrib);
16501 break; 16453 break;
16502 } 16454 }
16503 } 16455 }
16504 else 16456 else
16505 { 16457 {
16506 this.core.ParseExtensionAttribute(node, attrib); 16458 this.Core.ParseExtensionAttribute(node, attrib);
16507 } 16459 }
16508 } 16460 }
16509 16461
16510 if (null == id) 16462 if (null == id)
16511 { 16463 {
16512 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 16464 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
16513 id = Identifier.Invalid; 16465 id = Identifier.Invalid;
16514 } 16466 }
16515 16467
16516 Row lastTabRow = null; 16468 IntermediateTuple lastTabRow = null;
16517 string cancelControl = null; 16469 string cancelControl = null;
16518 string defaultControl = null; 16470 string defaultControl = null;
16519 string firstControl = null; 16471 string firstControl = null;
@@ -16525,16 +16477,16 @@ namespace WixToolset
16525 switch (child.Name.LocalName) 16477 switch (child.Name.LocalName)
16526 { 16478 {
16527 case "Control": 16479 case "Control":
16528 this.ParseControlElement(child, id.Id, this.tableDefinitions["Control"], ref lastTabRow, ref firstControl, ref defaultControl, ref cancelControl, trackDiskSpace); 16480 this.ParseControlElement(child, id.Id, TupleDefinitionType.Control, ref lastTabRow, ref firstControl, ref defaultControl, ref cancelControl, trackDiskSpace);
16529 break; 16481 break;
16530 default: 16482 default:
16531 this.core.UnexpectedElement(node, child); 16483 this.Core.UnexpectedElement(node, child);
16532 break; 16484 break;
16533 } 16485 }
16534 } 16486 }
16535 else 16487 else
16536 { 16488 {
16537 this.core.ParseExtensionElement(node, child); 16489 this.Core.ParseExtensionElement(node, child);
16538 } 16490 }
16539 } 16491 }
16540 16492
@@ -16543,27 +16495,27 @@ namespace WixToolset
16543 { 16495 {
16544 if (firstControl != lastTabRow[1].ToString()) 16496 if (firstControl != lastTabRow[1].ToString())
16545 { 16497 {
16546 lastTabRow[10] = firstControl; 16498 lastTabRow.Set(10, firstControl);
16547 } 16499 }
16548 } 16500 }
16549 16501
16550 if (null == firstControl) 16502 if (null == firstControl)
16551 { 16503 {
16552 this.core.OnMessage(WixErrors.NoFirstControlSpecified(sourceLineNumbers, id.Id)); 16504 this.Core.OnMessage(WixErrors.NoFirstControlSpecified(sourceLineNumbers, id.Id));
16553 } 16505 }
16554 16506
16555 if (!this.core.EncounteredError) 16507 if (!this.Core.EncounteredError)
16556 { 16508 {
16557 Row row = this.core.CreateRow(sourceLineNumbers, "Dialog", id); 16509 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Dialog, id);
16558 row[1] = x; 16510 row.Set(1, x);
16559 row[2] = y; 16511 row.Set(2, y);
16560 row[3] = width; 16512 row.Set(3, width);
16561 row[4] = height; 16513 row.Set(4, height);
16562 row[5] = bits; 16514 row.Set(5, bits);
16563 row[6] = title; 16515 row.Set(6, title);
16564 row[7] = firstControl; 16516 row.Set(7, firstControl);
16565 row[8] = defaultControl; 16517 row.Set(8, defaultControl);
16566 row[9] = cancelControl; 16518 row.Set(9, cancelControl);
16567 } 16519 }
16568 } 16520 }
16569 16521
@@ -16592,149 +16544,149 @@ namespace WixToolset
16592 switch (attrib.Name.LocalName) 16544 switch (attrib.Name.LocalName)
16593 { 16545 {
16594 case "Id": 16546 case "Id":
16595 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 16547 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
16596 break; 16548 break;
16597 case "Name": 16549 case "Name":
16598 name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); 16550 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
16599 break; 16551 break;
16600 case "IgnoreFatalExit": 16552 case "IgnoreFatalExit":
16601 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16553 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16602 { 16554 {
16603 messageFilter ^= MsiInterop.INSTALLLOGMODE_FATALEXIT; 16555 messageFilter ^= MsiInterop.INSTALLLOGMODE_FATALEXIT;
16604 } 16556 }
16605 break; 16557 break;
16606 case "IgnoreError": 16558 case "IgnoreError":
16607 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16559 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16608 { 16560 {
16609 messageFilter ^= MsiInterop.INSTALLLOGMODE_ERROR; 16561 messageFilter ^= MsiInterop.INSTALLLOGMODE_ERROR;
16610 } 16562 }
16611 break; 16563 break;
16612 case "IgnoreWarning": 16564 case "IgnoreWarning":
16613 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16565 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16614 { 16566 {
16615 messageFilter ^= MsiInterop.INSTALLLOGMODE_WARNING; 16567 messageFilter ^= MsiInterop.INSTALLLOGMODE_WARNING;
16616 } 16568 }
16617 break; 16569 break;
16618 case "IgnoreUser": 16570 case "IgnoreUser":
16619 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16571 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16620 { 16572 {
16621 messageFilter ^= MsiInterop.INSTALLLOGMODE_USER; 16573 messageFilter ^= MsiInterop.INSTALLLOGMODE_USER;
16622 } 16574 }
16623 break; 16575 break;
16624 case "IgnoreInfo": 16576 case "IgnoreInfo":
16625 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16577 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16626 { 16578 {
16627 messageFilter ^= MsiInterop.INSTALLLOGMODE_INFO; 16579 messageFilter ^= MsiInterop.INSTALLLOGMODE_INFO;
16628 } 16580 }
16629 break; 16581 break;
16630 case "IgnoreFilesInUse": 16582 case "IgnoreFilesInUse":
16631 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16583 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16632 { 16584 {
16633 messageFilter ^= MsiInterop.INSTALLLOGMODE_FILESINUSE; 16585 messageFilter ^= MsiInterop.INSTALLLOGMODE_FILESINUSE;
16634 } 16586 }
16635 break; 16587 break;
16636 case "IgnoreResolveSource": 16588 case "IgnoreResolveSource":
16637 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16589 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16638 { 16590 {
16639 messageFilter ^= MsiInterop.INSTALLLOGMODE_RESOLVESOURCE; 16591 messageFilter ^= MsiInterop.INSTALLLOGMODE_RESOLVESOURCE;
16640 } 16592 }
16641 break; 16593 break;
16642 case "IgnoreOutOfDiskSpace": 16594 case "IgnoreOutOfDiskSpace":
16643 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16595 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16644 { 16596 {
16645 messageFilter ^= MsiInterop.INSTALLLOGMODE_OUTOFDISKSPACE; 16597 messageFilter ^= MsiInterop.INSTALLLOGMODE_OUTOFDISKSPACE;
16646 } 16598 }
16647 break; 16599 break;
16648 case "IgnoreActionStart": 16600 case "IgnoreActionStart":
16649 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16601 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16650 { 16602 {
16651 messageFilter ^= MsiInterop.INSTALLLOGMODE_ACTIONSTART; 16603 messageFilter ^= MsiInterop.INSTALLLOGMODE_ACTIONSTART;
16652 } 16604 }
16653 break; 16605 break;
16654 case "IgnoreActionData": 16606 case "IgnoreActionData":
16655 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16607 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16656 { 16608 {
16657 messageFilter ^= MsiInterop.INSTALLLOGMODE_ACTIONDATA; 16609 messageFilter ^= MsiInterop.INSTALLLOGMODE_ACTIONDATA;
16658 } 16610 }
16659 break; 16611 break;
16660 case "IgnoreProgress": 16612 case "IgnoreProgress":
16661 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16613 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16662 { 16614 {
16663 messageFilter ^= MsiInterop.INSTALLLOGMODE_PROGRESS; 16615 messageFilter ^= MsiInterop.INSTALLLOGMODE_PROGRESS;
16664 } 16616 }
16665 break; 16617 break;
16666 case "IgnoreCommonData": 16618 case "IgnoreCommonData":
16667 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16619 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16668 { 16620 {
16669 messageFilter ^= MsiInterop.INSTALLLOGMODE_COMMONDATA; 16621 messageFilter ^= MsiInterop.INSTALLLOGMODE_COMMONDATA;
16670 } 16622 }
16671 break; 16623 break;
16672 case "IgnoreInitialize": 16624 case "IgnoreInitialize":
16673 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16625 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16674 { 16626 {
16675 messageFilter ^= MsiInterop.INSTALLLOGMODE_INITIALIZE; 16627 messageFilter ^= MsiInterop.INSTALLLOGMODE_INITIALIZE;
16676 } 16628 }
16677 break; 16629 break;
16678 case "IgnoreTerminate": 16630 case "IgnoreTerminate":
16679 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16631 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16680 { 16632 {
16681 messageFilter ^= MsiInterop.INSTALLLOGMODE_TERMINATE; 16633 messageFilter ^= MsiInterop.INSTALLLOGMODE_TERMINATE;
16682 } 16634 }
16683 break; 16635 break;
16684 case "IgnoreShowDialog": 16636 case "IgnoreShowDialog":
16685 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16637 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16686 { 16638 {
16687 messageFilter ^= MsiInterop.INSTALLLOGMODE_SHOWDIALOG; 16639 messageFilter ^= MsiInterop.INSTALLLOGMODE_SHOWDIALOG;
16688 } 16640 }
16689 break; 16641 break;
16690 case "IgnoreRMFilesInUse": 16642 case "IgnoreRMFilesInUse":
16691 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16643 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16692 { 16644 {
16693 messageFilter ^= MsiInterop.INSTALLLOGMODE_RMFILESINUSE; 16645 messageFilter ^= MsiInterop.INSTALLLOGMODE_RMFILESINUSE;
16694 } 16646 }
16695 break; 16647 break;
16696 case "IgnoreInstallStart": 16648 case "IgnoreInstallStart":
16697 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16649 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16698 { 16650 {
16699 messageFilter ^= MsiInterop.INSTALLLOGMODE_INSTALLSTART; 16651 messageFilter ^= MsiInterop.INSTALLLOGMODE_INSTALLSTART;
16700 } 16652 }
16701 break; 16653 break;
16702 case "IgnoreInstallEnd": 16654 case "IgnoreInstallEnd":
16703 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16655 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16704 { 16656 {
16705 messageFilter ^= MsiInterop.INSTALLLOGMODE_INSTALLEND; 16657 messageFilter ^= MsiInterop.INSTALLLOGMODE_INSTALLEND;
16706 } 16658 }
16707 break; 16659 break;
16708 case "SourceFile": 16660 case "SourceFile":
16709 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 16661 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
16710 break; 16662 break;
16711 case "SupportBasicUI": 16663 case "SupportBasicUI":
16712 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 16664 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
16713 { 16665 {
16714 attributes |= MsiInterop.MsidbEmbeddedHandlesBasic; 16666 attributes |= MsiInterop.MsidbEmbeddedHandlesBasic;
16715 } 16667 }
16716 break; 16668 break;
16717 default: 16669 default:
16718 this.core.UnexpectedAttribute(node, attrib); 16670 this.Core.UnexpectedAttribute(node, attrib);
16719 break; 16671 break;
16720 } 16672 }
16721 } 16673 }
16722 else 16674 else
16723 { 16675 {
16724 this.core.ParseExtensionAttribute(node, attrib); 16676 this.Core.ParseExtensionAttribute(node, attrib);
16725 } 16677 }
16726 } 16678 }
16727 16679
16728 if (String.IsNullOrEmpty(sourceFile)) 16680 if (String.IsNullOrEmpty(sourceFile))
16729 { 16681 {
16730 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); 16682 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
16731 } 16683 }
16732 else if (String.IsNullOrEmpty(name)) 16684 else if (String.IsNullOrEmpty(name))
16733 { 16685 {
16734 name = Path.GetFileName(sourceFile); 16686 name = Path.GetFileName(sourceFile);
16735 if (!this.core.IsValidLongFilename(name, false)) 16687 if (!this.Core.IsValidLongFilename(name, false))
16736 { 16688 {
16737 this.core.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Source", name)); 16689 this.Core.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Source", name));
16738 } 16690 }
16739 } 16691 }
16740 16692
@@ -16742,16 +16694,16 @@ namespace WixToolset
16742 { 16694 {
16743 if (!String.IsNullOrEmpty(name)) 16695 if (!String.IsNullOrEmpty(name))
16744 { 16696 {
16745 id = this.core.CreateIdentifierFromFilename(name); 16697 id = this.Core.CreateIdentifierFromFilename(name);
16746 } 16698 }
16747 16699
16748 if (null == id) 16700 if (null == id)
16749 { 16701 {
16750 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 16702 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
16751 } 16703 }
16752 else if (!Common.IsIdentifier(id.Id)) 16704 else if (!Common.IsIdentifier(id.Id))
16753 { 16705 {
16754 this.core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id)); 16706 this.Core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id));
16755 } 16707 }
16756 } 16708 }
16757 else if (String.IsNullOrEmpty(name)) 16709 else if (String.IsNullOrEmpty(name))
@@ -16761,7 +16713,7 @@ namespace WixToolset
16761 16713
16762 if (!name.Contains(".")) 16714 if (!name.Contains("."))
16763 { 16715 {
16764 this.core.OnMessage(WixErrors.InvalidEmbeddedUIFileName(sourceLineNumbers, name)); 16716 this.Core.OnMessage(WixErrors.InvalidEmbeddedUIFileName(sourceLineNumbers, name));
16765 } 16717 }
16766 16718
16767 foreach (XElement child in node.Elements()) 16719 foreach (XElement child in node.Elements())
@@ -16774,23 +16726,23 @@ namespace WixToolset
16774 this.ParseEmbeddedUIResourceElement(child); 16726 this.ParseEmbeddedUIResourceElement(child);
16775 break; 16727 break;
16776 default: 16728 default:
16777 this.core.UnexpectedElement(node, child); 16729 this.Core.UnexpectedElement(node, child);
16778 break; 16730 break;
16779 } 16731 }
16780 } 16732 }
16781 else 16733 else
16782 { 16734 {
16783 this.core.ParseExtensionElement(node, child); 16735 this.Core.ParseExtensionElement(node, child);
16784 } 16736 }
16785 } 16737 }
16786 16738
16787 if (!this.core.EncounteredError) 16739 if (!this.Core.EncounteredError)
16788 { 16740 {
16789 Row row = this.core.CreateRow(sourceLineNumbers, "MsiEmbeddedUI", id); 16741 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiEmbeddedUI, id);
16790 row[1] = name; 16742 row.Set(1, name);
16791 row[2] = attributes; 16743 row.Set(2, attributes);
16792 row[3] = messageFilter; 16744 row.Set(3, messageFilter);
16793 row[4] = sourceFile; 16745 row.Set(4, sourceFile);
16794 } 16746 }
16795 } 16747 }
16796 16748
@@ -16813,35 +16765,35 @@ namespace WixToolset
16813 switch (attrib.Name.LocalName) 16765 switch (attrib.Name.LocalName)
16814 { 16766 {
16815 case "Id": 16767 case "Id":
16816 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 16768 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
16817 break; 16769 break;
16818 case "Name": 16770 case "Name":
16819 name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); 16771 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
16820 break; 16772 break;
16821 case "SourceFile": 16773 case "SourceFile":
16822 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 16774 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
16823 break; 16775 break;
16824 default: 16776 default:
16825 this.core.UnexpectedAttribute(node, attrib); 16777 this.Core.UnexpectedAttribute(node, attrib);
16826 break; 16778 break;
16827 } 16779 }
16828 } 16780 }
16829 else 16781 else
16830 { 16782 {
16831 this.core.ParseExtensionAttribute(node, attrib); 16783 this.Core.ParseExtensionAttribute(node, attrib);
16832 } 16784 }
16833 } 16785 }
16834 16786
16835 if (String.IsNullOrEmpty(sourceFile)) 16787 if (String.IsNullOrEmpty(sourceFile))
16836 { 16788 {
16837 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); 16789 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
16838 } 16790 }
16839 else if (String.IsNullOrEmpty(name)) 16791 else if (String.IsNullOrEmpty(name))
16840 { 16792 {
16841 name = Path.GetFileName(sourceFile); 16793 name = Path.GetFileName(sourceFile);
16842 if (!this.core.IsValidLongFilename(name, false)) 16794 if (!this.Core.IsValidLongFilename(name, false))
16843 { 16795 {
16844 this.core.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Source", name)); 16796 this.Core.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Source", name));
16845 } 16797 }
16846 } 16798 }
16847 16799
@@ -16849,16 +16801,16 @@ namespace WixToolset
16849 { 16801 {
16850 if (!String.IsNullOrEmpty(name)) 16802 if (!String.IsNullOrEmpty(name))
16851 { 16803 {
16852 id = this.core.CreateIdentifierFromFilename(name); 16804 id = this.Core.CreateIdentifierFromFilename(name);
16853 } 16805 }
16854 16806
16855 if (null == id) 16807 if (null == id)
16856 { 16808 {
16857 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 16809 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
16858 } 16810 }
16859 else if (!Common.IsIdentifier(id.Id)) 16811 else if (!Common.IsIdentifier(id.Id))
16860 { 16812 {
16861 this.core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id)); 16813 this.Core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id));
16862 } 16814 }
16863 } 16815 }
16864 else if (String.IsNullOrEmpty(name)) 16816 else if (String.IsNullOrEmpty(name))
@@ -16866,15 +16818,15 @@ namespace WixToolset
16866 name = id.Id; 16818 name = id.Id;
16867 } 16819 }
16868 16820
16869 this.core.ParseForExtensionElements(node); 16821 this.Core.ParseForExtensionElements(node);
16870 16822
16871 if (!this.core.EncounteredError) 16823 if (!this.Core.EncounteredError)
16872 { 16824 {
16873 Row row = this.core.CreateRow(sourceLineNumbers, "MsiEmbeddedUI", id); 16825 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiEmbeddedUI, id);
16874 row[1] = name; 16826 row.Set(1, name);
16875 row[2] = 0; // embedded UI resources always set this to 0 16827 row.Set(2, 0); // embedded UI resources always set this to 0
16876 row[3] = null; 16828 row.Set(3, null);
16877 row[4] = sourceFile; 16829 row.Set(4, sourceFile);
16878 } 16830 }
16879 } 16831 }
16880 16832
@@ -16889,7 +16841,7 @@ namespace WixToolset
16889 /// <param name="defaultControl">Name of the default control.</param> 16841 /// <param name="defaultControl">Name of the default control.</param>
16890 /// <param name="cancelControl">Name of the candle control.</param> 16842 /// <param name="cancelControl">Name of the candle control.</param>
16891 /// <param name="trackDiskSpace">True if the containing dialog tracks disk space.</param> 16843 /// <param name="trackDiskSpace">True if the containing dialog tracks disk space.</param>
16892 private void ParseControlElement(XElement node, string dialog, TableDefinition table, ref Row lastTabRow, ref string firstControl, ref string defaultControl, ref string cancelControl, bool trackDiskSpace) 16844 private void ParseControlElement(XElement node, string dialog, TupleDefinitionType tableName, ref IntermediateTuple lastTabRow, ref string firstControl, ref string defaultControl, ref string cancelControl, bool trackDiskSpace)
16893 { 16845 {
16894 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 16846 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
16895 Identifier id = null; 16847 Identifier id = null;
@@ -16919,11 +16871,11 @@ namespace WixToolset
16919 XAttribute typeAttribute = node.Attribute("Type"); 16871 XAttribute typeAttribute = node.Attribute("Type");
16920 if (null == typeAttribute) 16872 if (null == typeAttribute)
16921 { 16873 {
16922 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type")); 16874 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type"));
16923 } 16875 }
16924 else 16876 else
16925 { 16877 {
16926 controlType = this.core.GetAttributeValue(sourceLineNumbers, typeAttribute); 16878 controlType = this.Core.GetAttributeValue(sourceLineNumbers, typeAttribute);
16927 } 16879 }
16928 16880
16929 switch (controlType) 16881 switch (controlType)
@@ -16933,7 +16885,7 @@ namespace WixToolset
16933 notTabbable = true; 16885 notTabbable = true;
16934 disabled = true; 16886 disabled = true;
16935 16887
16936 this.core.EnsureTable(sourceLineNumbers, "Billboard"); 16888 this.Core.EnsureTable(sourceLineNumbers, "Billboard");
16937 break; 16889 break;
16938 case "Bitmap": 16890 case "Bitmap":
16939 specialAttributes = MsiInterop.BitmapControlAttributes; 16891 specialAttributes = MsiInterop.BitmapControlAttributes;
@@ -17025,30 +16977,30 @@ namespace WixToolset
17025 switch (attrib.Name.LocalName) 16977 switch (attrib.Name.LocalName)
17026 { 16978 {
17027 case "Id": 16979 case "Id":
17028 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 16980 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
17029 break; 16981 break;
17030 case "Type": // already processed 16982 case "Type": // already processed
17031 break; 16983 break;
17032 case "Cancel": 16984 case "Cancel":
17033 isCancel = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 16985 isCancel = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
17034 break; 16986 break;
17035 case "CheckBoxPropertyRef": 16987 case "CheckBoxPropertyRef":
17036 checkBoxPropertyRef = this.core.GetAttributeValue(sourceLineNumbers, attrib); 16988 checkBoxPropertyRef = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17037 break; 16989 break;
17038 case "CheckBoxValue": 16990 case "CheckBoxValue":
17039 checkboxValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 16991 checkboxValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17040 break; 16992 break;
17041 case "Default": 16993 case "Default":
17042 isDefault = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 16994 isDefault = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
17043 break; 16995 break;
17044 case "Height": 16996 case "Height":
17045 height = this.core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 16997 height = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
17046 break; 16998 break;
17047 case "Help": 16999 case "Help":
17048 help = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17000 help = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17049 break; 17001 break;
17050 case "IconSize": 17002 case "IconSize":
17051 string iconSizeValue = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17003 string iconSizeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17052 if (null != specialAttributes) 17004 if (null != specialAttributes)
17053 { 17005 {
17054 if (0 < iconSizeValue.Length) 17006 if (0 < iconSizeValue.Length)
@@ -17057,54 +17009,54 @@ namespace WixToolset
17057 switch (iconsSizeType) 17009 switch (iconsSizeType)
17058 { 17010 {
17059 case Wix.Control.IconSizeType.Item16: 17011 case Wix.Control.IconSizeType.Item16:
17060 this.core.TrySetBitFromName(specialAttributes, "Icon16", YesNoType.Yes, bits, 16); 17012 this.Core.TrySetBitFromName(specialAttributes, "Icon16", YesNoType.Yes, bits, 16);
17061 break; 17013 break;
17062 case Wix.Control.IconSizeType.Item32: 17014 case Wix.Control.IconSizeType.Item32:
17063 this.core.TrySetBitFromName(specialAttributes, "Icon32", YesNoType.Yes, bits, 16); 17015 this.Core.TrySetBitFromName(specialAttributes, "Icon32", YesNoType.Yes, bits, 16);
17064 break; 17016 break;
17065 case Wix.Control.IconSizeType.Item48: 17017 case Wix.Control.IconSizeType.Item48:
17066 this.core.TrySetBitFromName(specialAttributes, "Icon16", YesNoType.Yes, bits, 16); 17018 this.Core.TrySetBitFromName(specialAttributes, "Icon16", YesNoType.Yes, bits, 16);
17067 this.core.TrySetBitFromName(specialAttributes, "Icon32", YesNoType.Yes, bits, 16); 17019 this.Core.TrySetBitFromName(specialAttributes, "Icon32", YesNoType.Yes, bits, 16);
17068 break; 17020 break;
17069 default: 17021 default:
17070 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, iconSizeValue, "16", "32", "48")); 17022 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, iconSizeValue, "16", "32", "48"));
17071 break; 17023 break;
17072 } 17024 }
17073 } 17025 }
17074 } 17026 }
17075 else 17027 else
17076 { 17028 {
17077 this.core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, iconSizeValue, "Type")); 17029 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, iconSizeValue, "Type"));
17078 } 17030 }
17079 break; 17031 break;
17080 case "Property": 17032 case "Property":
17081 property = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17033 property = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17082 break; 17034 break;
17083 case "TabSkip": 17035 case "TabSkip":
17084 notTabbable = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 17036 notTabbable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
17085 break; 17037 break;
17086 case "Text": 17038 case "Text":
17087 text = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17039 text = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17088 break; 17040 break;
17089 case "ToolTip": 17041 case "ToolTip":
17090 tooltip = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17042 tooltip = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17091 break; 17043 break;
17092 case "Width": 17044 case "Width":
17093 width = this.core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 17045 width = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
17094 break; 17046 break;
17095 case "X": 17047 case "X":
17096 x = this.core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 17048 x = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
17097 break; 17049 break;
17098 case "Y": 17050 case "Y":
17099 y = this.core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); 17051 y = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
17100 break; 17052 break;
17101 default: 17053 default:
17102 YesNoType attribValue = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 17054 YesNoType attribValue = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
17103 if (!this.core.TrySetBitFromName(MsiInterop.CommonControlAttributes, attrib.Name.LocalName, attribValue, bits, 0)) 17055 if (!this.Core.TrySetBitFromName(MsiInterop.CommonControlAttributes, attrib.Name.LocalName, attribValue, bits, 0))
17104 { 17056 {
17105 if (null == specialAttributes || !this.core.TrySetBitFromName(specialAttributes, attrib.Name.LocalName, attribValue, bits, 16)) 17057 if (null == specialAttributes || !this.Core.TrySetBitFromName(specialAttributes, attrib.Name.LocalName, attribValue, bits, 16))
17106 { 17058 {
17107 this.core.UnexpectedAttribute(node, attrib); 17059 this.Core.UnexpectedAttribute(node, attrib);
17108 } 17060 }
17109 } 17061 }
17110 break; 17062 break;
@@ -17112,11 +17064,11 @@ namespace WixToolset
17112 } 17064 }
17113 else 17065 else
17114 { 17066 {
17115 this.core.ParseExtensionAttribute(node, attrib); 17067 this.Core.ParseExtensionAttribute(node, attrib);
17116 } 17068 }
17117 } 17069 }
17118 17070
17119 attributes = this.core.CreateIntegerFromBitArray(bits); 17071 attributes = this.Core.CreateIntegerFromBitArray(bits);
17120 17072
17121 if (disabled) 17073 if (disabled)
17122 { 17074 {
@@ -17125,27 +17077,27 @@ namespace WixToolset
17125 17077
17126 if (null == height) 17078 if (null == height)
17127 { 17079 {
17128 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Height")); 17080 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Height"));
17129 } 17081 }
17130 17082
17131 if (null == width) 17083 if (null == width)
17132 { 17084 {
17133 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Width")); 17085 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Width"));
17134 } 17086 }
17135 17087
17136 if (null == x) 17088 if (null == x)
17137 { 17089 {
17138 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "X")); 17090 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "X"));
17139 } 17091 }
17140 17092
17141 if (null == y) 17093 if (null == y)
17142 { 17094 {
17143 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Y")); 17095 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Y"));
17144 } 17096 }
17145 17097
17146 if (null == id) 17098 if (null == id)
17147 { 17099 {
17148 id = this.core.CreateIdentifier("ctl", dialog, x, y, height, width); 17100 id = this.Core.CreateIdentifier("ctl", dialog, x, y, height, width);
17149 } 17101 }
17150 17102
17151 if (isCancel) 17103 if (isCancel)
@@ -17169,16 +17121,16 @@ namespace WixToolset
17169 this.ParseBinaryElement(child); 17121 this.ParseBinaryElement(child);
17170 break; 17122 break;
17171 case "ComboBox": 17123 case "ComboBox":
17172 this.ParseControlGroupElement(child, this.tableDefinitions["ComboBox"], "ListItem"); 17124 this.ParseControlGroupElement(child, TupleDefinitionType.ComboBox, "ListItem");
17173 break; 17125 break;
17174 case "Condition": 17126 case "Condition":
17175 this.ParseConditionElement(child, node.Name.LocalName, id.Id, dialog); 17127 this.ParseConditionElement(child, node.Name.LocalName, id.Id, dialog);
17176 break; 17128 break;
17177 case "ListBox": 17129 case "ListBox":
17178 this.ParseControlGroupElement(child, this.tableDefinitions["ListBox"], "ListItem"); 17130 this.ParseControlGroupElement(child, TupleDefinitionType.ListBox, "ListItem");
17179 break; 17131 break;
17180 case "ListView": 17132 case "ListView":
17181 this.ParseControlGroupElement(child, this.tableDefinitions["ListView"], "ListItem"); 17133 this.ParseControlGroupElement(child, TupleDefinitionType.ListView, "ListItem");
17182 break; 17134 break;
17183 case "Property": 17135 case "Property":
17184 this.ParsePropertyElement(child); 17136 this.ParsePropertyElement(child);
@@ -17200,33 +17152,33 @@ namespace WixToolset
17200 switch (attrib.Name.LocalName) 17152 switch (attrib.Name.LocalName)
17201 { 17153 {
17202 case "SourceFile": 17154 case "SourceFile":
17203 sourceFile = this.core.GetAttributeValue(childSourceLineNumbers, attrib); 17155 sourceFile = this.Core.GetAttributeValue(childSourceLineNumbers, attrib);
17204 break; 17156 break;
17205 default: 17157 default:
17206 this.core.UnexpectedAttribute(child, attrib); 17158 this.Core.UnexpectedAttribute(child, attrib);
17207 break; 17159 break;
17208 } 17160 }
17209 } 17161 }
17210 else 17162 else
17211 { 17163 {
17212 this.core.ParseExtensionAttribute(child, attrib); 17164 this.Core.ParseExtensionAttribute(child, attrib);
17213 } 17165 }
17214 } 17166 }
17215 17167
17216 text = Common.GetInnerText(child); 17168 text = Common.GetInnerText(child);
17217 if (!String.IsNullOrEmpty(text) && null != sourceFile) 17169 if (!String.IsNullOrEmpty(text) && null != sourceFile)
17218 { 17170 {
17219 this.core.OnMessage(WixErrors.IllegalAttributeWithInnerText(childSourceLineNumbers, child.Name.LocalName, "SourceFile")); 17171 this.Core.OnMessage(WixErrors.IllegalAttributeWithInnerText(childSourceLineNumbers, child.Name.LocalName, "SourceFile"));
17220 } 17172 }
17221 break; 17173 break;
17222 default: 17174 default:
17223 this.core.UnexpectedElement(node, child); 17175 this.Core.UnexpectedElement(node, child);
17224 break; 17176 break;
17225 } 17177 }
17226 } 17178 }
17227 else 17179 else
17228 { 17180 {
17229 this.core.ParseExtensionElement(node, child); 17181 this.Core.ParseExtensionElement(node, child);
17230 } 17182 }
17231 } 17183 }
17232 17184
@@ -17255,79 +17207,75 @@ namespace WixToolset
17255 } 17207 }
17256 17208
17257 // the logic for creating control rows is a little tricky because of the way tabable controls are set 17209 // the logic for creating control rows is a little tricky because of the way tabable controls are set
17258 Row row = null; 17210 IntermediateTuple row = null;
17259 if (!this.core.EncounteredError) 17211 if (!this.Core.EncounteredError)
17260 { 17212 {
17261 if ("CheckBox" == controlType) 17213 if ("CheckBox" == controlType)
17262 { 17214 {
17263 if (String.IsNullOrEmpty(property) && String.IsNullOrEmpty(checkBoxPropertyRef)) 17215 if (String.IsNullOrEmpty(property) && String.IsNullOrEmpty(checkBoxPropertyRef))
17264 { 17216 {
17265 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "CheckBoxPropertyRef", true)); 17217 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "CheckBoxPropertyRef", true));
17266 } 17218 }
17267 else if (!String.IsNullOrEmpty(property) && !String.IsNullOrEmpty(checkBoxPropertyRef)) 17219 else if (!String.IsNullOrEmpty(property) && !String.IsNullOrEmpty(checkBoxPropertyRef))
17268 { 17220 {
17269 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "CheckBoxPropertyRef")); 17221 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "CheckBoxPropertyRef"));
17270 } 17222 }
17271 else if (!String.IsNullOrEmpty(property)) 17223 else if (!String.IsNullOrEmpty(property))
17272 { 17224 {
17273 row = this.core.CreateRow(sourceLineNumbers, "CheckBox"); 17225 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CheckBox);
17274 row[0] = property; 17226 row.Set(0, property);
17275 row[1] = checkboxValue; 17227 row.Set(1, checkboxValue);
17276 } 17228 }
17277 else 17229 else
17278 { 17230 {
17279 this.core.CreateSimpleReference(sourceLineNumbers, "CheckBox", checkBoxPropertyRef); 17231 this.Core.CreateSimpleReference(sourceLineNumbers, "CheckBox", checkBoxPropertyRef);
17280 } 17232 }
17281 } 17233 }
17282 17234
17283 row = this.core.CreateRow(sourceLineNumbers, table.Name); 17235 var dialogId = new Identifier(dialog, id.Access);
17284 row.Access = id.Access; 17236
17285 row[0] = dialog; 17237 row = this.Core.CreateRow(sourceLineNumbers, tableName, dialogId);
17286 row[1] = id.Id; 17238 row.Set(1, id.Id);
17287 row[2] = controlType; 17239 row.Set(2, controlType);
17288 row[3] = x; 17240 row.Set(3, x);
17289 row[4] = y; 17241 row.Set(4, y);
17290 row[5] = width; 17242 row.Set(5, width);
17291 row[6] = height; 17243 row.Set(6, height);
17292 row[7] = attributes ^ (MsiInterop.MsidbControlAttributesVisible | MsiInterop.MsidbControlAttributesEnabled); 17244 row.Set(7, attributes ^ (MsiInterop.MsidbControlAttributesVisible | MsiInterop.MsidbControlAttributesEnabled));
17293 if ("BBControl" == table.Name) 17245 if (TupleDefinitionType.BBControl == tableName)
17294 { 17246 {
17295 row[8] = text; // BBControl.Text 17247 row.Set(8, text); // BBControl.Text
17296 17248
17297 if (null != sourceFile) 17249 if (null != sourceFile)
17298 { 17250 {
17299 Row wixBBControlRow = this.core.CreateRow(sourceLineNumbers, "WixBBControl"); 17251 var wixBBControlRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBBControl, dialogId);
17300 wixBBControlRow.Access = id.Access; 17252 wixBBControlRow.Set(1, id.Id);
17301 wixBBControlRow[0] = dialog; 17253 wixBBControlRow.Set(2, sourceFile);
17302 wixBBControlRow[1] = id.Id;
17303 wixBBControlRow[2] = sourceFile;
17304 } 17254 }
17305 } 17255 }
17306 else 17256 else
17307 { 17257 {
17308 row[8] = !String.IsNullOrEmpty(property) ? property : checkBoxPropertyRef; 17258 row.Set(8, !String.IsNullOrEmpty(property) ? property : checkBoxPropertyRef);
17309 row[9] = text; 17259 row.Set(9, text);
17310 if (null != tooltip || null != help) 17260 if (null != tooltip || null != help)
17311 { 17261 {
17312 row[11] = String.Concat(tooltip, "|", help); // Separator is required, even if only one is non-null. 17262 row.Set(11, String.Concat(tooltip, "|", help)); // Separator is required, even if only one is non-null.
17313 } 17263 }
17314 17264
17315 if (null != sourceFile) 17265 if (null != sourceFile)
17316 { 17266 {
17317 Row wixControlRow = this.core.CreateRow(sourceLineNumbers, "WixControl"); 17267 var wixControlRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixControl, dialogId);
17318 wixControlRow.Access = id.Access; 17268 wixControlRow.Set(1, id.Id);
17319 wixControlRow[0] = dialog; 17269 wixControlRow.Set(2, sourceFile);
17320 wixControlRow[1] = id.Id;
17321 wixControlRow[2] = sourceFile;
17322 } 17270 }
17323 } 17271 }
17324 } 17272 }
17325 17273
17326 if (!notTabbable) 17274 if (!notTabbable)
17327 { 17275 {
17328 if ("BBControl" == table.Name) 17276 if (TupleDefinitionType.BBControl == tableName)
17329 { 17277 {
17330 this.core.OnMessage(WixErrors.TabbableControlNotAllowedInBillboard(sourceLineNumbers, node.Name.LocalName, controlType)); 17278 this.Core.OnMessage(WixErrors.TabbableControlNotAllowedInBillboard(sourceLineNumbers, node.Name.LocalName, controlType));
17331 } 17279 }
17332 17280
17333 if (null == firstControl) 17281 if (null == firstControl)
@@ -17337,7 +17285,7 @@ namespace WixToolset
17337 17285
17338 if (null != lastTabRow) 17286 if (null != lastTabRow)
17339 { 17287 {
17340 lastTabRow[10] = id.Id; 17288 lastTabRow.Set(10, id.Id);
17341 } 17289 }
17342 lastTabRow = row; 17290 lastTabRow = row;
17343 } 17291 }
@@ -17346,7 +17294,7 @@ namespace WixToolset
17346 // add a reference if the identifier of the binary entry is known during compilation 17294 // add a reference if the identifier of the binary entry is known during compilation
17347 if (("Bitmap" == controlType || "Icon" == controlType) && Common.IsIdentifier(text)) 17295 if (("Bitmap" == controlType || "Icon" == controlType) && Common.IsIdentifier(text))
17348 { 17296 {
17349 this.core.CreateSimpleReference(sourceLineNumbers, "Binary", text); 17297 this.Core.CreateSimpleReference(sourceLineNumbers, "Binary", text);
17350 } 17298 }
17351 } 17299 }
17352 17300
@@ -17377,67 +17325,67 @@ namespace WixToolset
17377 case "Control": 17325 case "Control":
17378 if (null != control) 17326 if (null != control)
17379 { 17327 {
17380 this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName)); 17328 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
17381 } 17329 }
17382 control = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 17330 control = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
17383 break; 17331 break;
17384 case "Dialog": 17332 case "Dialog":
17385 if (null != dialog) 17333 if (null != dialog)
17386 { 17334 {
17387 this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName)); 17335 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
17388 } 17336 }
17389 dialog = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 17337 dialog = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
17390 this.core.CreateSimpleReference(sourceLineNumbers, "Dialog", dialog); 17338 this.Core.CreateSimpleReference(sourceLineNumbers, "Dialog", dialog);
17391 break; 17339 break;
17392 case "Event": 17340 case "Event":
17393 controlEvent = Compiler.UppercaseFirstChar(this.core.GetAttributeValue(sourceLineNumbers, attrib)); 17341 controlEvent = Compiler.UppercaseFirstChar(this.Core.GetAttributeValue(sourceLineNumbers, attrib));
17394 break; 17342 break;
17395 case "Order": 17343 case "Order":
17396 order = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 2147483647); 17344 order = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 2147483647);
17397 break; 17345 break;
17398 case "Property": 17346 case "Property":
17399 property = String.Concat("[", this.core.GetAttributeValue(sourceLineNumbers, attrib), "]"); 17347 property = String.Concat("[", this.Core.GetAttributeValue(sourceLineNumbers, attrib), "]");
17400 break; 17348 break;
17401 case "Value": 17349 case "Value":
17402 argument = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17350 argument = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17403 break; 17351 break;
17404 default: 17352 default:
17405 this.core.UnexpectedAttribute(node, attrib); 17353 this.Core.UnexpectedAttribute(node, attrib);
17406 break; 17354 break;
17407 } 17355 }
17408 } 17356 }
17409 else 17357 else
17410 { 17358 {
17411 this.core.ParseExtensionAttribute(node, attrib); 17359 this.Core.ParseExtensionAttribute(node, attrib);
17412 } 17360 }
17413 } 17361 }
17414 17362
17415 condition = this.core.GetConditionInnerText(node); 17363 condition = this.Core.GetConditionInnerText(node);
17416 17364
17417 if (null == control) 17365 if (null == control)
17418 { 17366 {
17419 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Control")); 17367 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Control"));
17420 } 17368 }
17421 17369
17422 if (null == dialog) 17370 if (null == dialog)
17423 { 17371 {
17424 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Dialog")); 17372 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Dialog"));
17425 } 17373 }
17426 17374
17427 if (null == controlEvent && null == property) // need to specify at least one 17375 if (null == controlEvent && null == property) // need to specify at least one
17428 { 17376 {
17429 this.core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "Event", "Property")); 17377 this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "Event", "Property"));
17430 } 17378 }
17431 else if (null != controlEvent && null != property) // cannot specify both 17379 else if (null != controlEvent && null != property) // cannot specify both
17432 { 17380 {
17433 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Event", "Property")); 17381 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Event", "Property"));
17434 } 17382 }
17435 17383
17436 if (null == argument) 17384 if (null == argument)
17437 { 17385 {
17438 if (null != controlEvent) 17386 if (null != controlEvent)
17439 { 17387 {
17440 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value", "Event")); 17388 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value", "Event"));
17441 } 17389 }
17442 else if (null != property) 17390 else if (null != property)
17443 { 17391 {
@@ -17446,17 +17394,17 @@ namespace WixToolset
17446 } 17394 }
17447 } 17395 }
17448 17396
17449 this.core.ParseForExtensionElements(node); 17397 this.Core.ParseForExtensionElements(node);
17450 17398
17451 if (!this.core.EncounteredError) 17399 if (!this.Core.EncounteredError)
17452 { 17400 {
17453 Row row = this.core.CreateRow(sourceLineNumbers, "ControlEvent"); 17401 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ControlEvent);
17454 row[0] = dialog; 17402 row.Set(0, dialog);
17455 row[1] = control; 17403 row.Set(1, control);
17456 row[2] = (null != controlEvent ? controlEvent : property); 17404 row.Set(2, (null != controlEvent ? controlEvent : property));
17457 row[3] = argument; 17405 row.Set(3, argument);
17458 row[4] = condition; 17406 row.Set(4, condition);
17459 row[5] = order; 17407 row.Set(5, order);
17460 } 17408 }
17461 17409
17462 if ("DoAction" == controlEvent && null != argument) 17410 if ("DoAction" == controlEvent && null != argument)
@@ -17465,14 +17413,14 @@ namespace WixToolset
17465 // to the custom action. 17413 // to the custom action.
17466 if (!WindowsInstallerStandard.IsStandardAction(argument) && !Common.ContainsProperty(argument)) 17414 if (!WindowsInstallerStandard.IsStandardAction(argument) && !Common.ContainsProperty(argument))
17467 { 17415 {
17468 this.core.CreateSimpleReference(sourceLineNumbers, "CustomAction", argument); 17416 this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", argument);
17469 } 17417 }
17470 } 17418 }
17471 17419
17472 // if we're referring to a dialog but not through a property, add it to the references 17420 // if we're referring to a dialog but not through a property, add it to the references
17473 if (("NewDialog" == controlEvent || "SpawnDialog" == controlEvent || "SpawnWaitDialog" == controlEvent || "SelectionBrowse" == controlEvent) && Common.IsIdentifier(argument)) 17421 if (("NewDialog" == controlEvent || "SpawnDialog" == controlEvent || "SpawnWaitDialog" == controlEvent || "SelectionBrowse" == controlEvent) && Common.IsIdentifier(argument))
17474 { 17422 {
17475 this.core.CreateSimpleReference(sourceLineNumbers, "Dialog", argument); 17423 this.Core.CreateSimpleReference(sourceLineNumbers, "Dialog", argument);
17476 } 17424 }
17477 } 17425 }
17478 17426
@@ -17495,31 +17443,31 @@ namespace WixToolset
17495 switch (attrib.Name.LocalName) 17443 switch (attrib.Name.LocalName)
17496 { 17444 {
17497 case "Attribute": 17445 case "Attribute":
17498 controlAttribute = Compiler.UppercaseFirstChar(this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib)); 17446 controlAttribute = Compiler.UppercaseFirstChar(this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib));
17499 break; 17447 break;
17500 case "Event": 17448 case "Event":
17501 eventMapping = Compiler.UppercaseFirstChar(this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib)); 17449 eventMapping = Compiler.UppercaseFirstChar(this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib));
17502 break; 17450 break;
17503 default: 17451 default:
17504 this.core.UnexpectedAttribute(node, attrib); 17452 this.Core.UnexpectedAttribute(node, attrib);
17505 break; 17453 break;
17506 } 17454 }
17507 } 17455 }
17508 else 17456 else
17509 { 17457 {
17510 this.core.ParseExtensionAttribute(node, attrib); 17458 this.Core.ParseExtensionAttribute(node, attrib);
17511 } 17459 }
17512 } 17460 }
17513 17461
17514 this.core.ParseForExtensionElements(node); 17462 this.Core.ParseForExtensionElements(node);
17515 17463
17516 if (!this.core.EncounteredError) 17464 if (!this.Core.EncounteredError)
17517 { 17465 {
17518 Row row = this.core.CreateRow(sourceLineNumbers, "EventMapping"); 17466 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.EventMapping);
17519 row[0] = dialog; 17467 row.Set(0, dialog);
17520 row[1] = control; 17468 row.Set(1, control);
17521 row[2] = eventMapping; 17469 row.Set(2, eventMapping);
17522 row[3] = controlAttribute; 17470 row.Set(3, controlAttribute);
17523 } 17471 }
17524 } 17472 }
17525 17473
@@ -17539,22 +17487,22 @@ namespace WixToolset
17539 switch (attrib.Name.LocalName) 17487 switch (attrib.Name.LocalName)
17540 { 17488 {
17541 case "Id": 17489 case "Id":
17542 id = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 17490 id = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
17543 break; 17491 break;
17544 default: 17492 default:
17545 this.core.UnexpectedAttribute(node, attrib); 17493 this.Core.UnexpectedAttribute(node, attrib);
17546 break; 17494 break;
17547 } 17495 }
17548 } 17496 }
17549 else 17497 else
17550 { 17498 {
17551 this.core.ParseExtensionAttribute(node, attrib); 17499 this.Core.ParseExtensionAttribute(node, attrib);
17552 } 17500 }
17553 } 17501 }
17554 17502
17555 if (null == id) 17503 if (null == id)
17556 { 17504 {
17557 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 17505 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
17558 } 17506 }
17559 17507
17560 // process the UpgradeVersion children here 17508 // process the UpgradeVersion children here
@@ -17568,23 +17516,22 @@ namespace WixToolset
17568 { 17516 {
17569 case "Property": 17517 case "Property":
17570 this.ParsePropertyElement(child); 17518 this.ParsePropertyElement(child);
17571 this.core.OnMessage(WixWarnings.DeprecatedUpgradeProperty(childSourceLineNumbers)); 17519 this.Core.OnMessage(WixWarnings.DeprecatedUpgradeProperty(childSourceLineNumbers));
17572 break; 17520 break;
17573 case "UpgradeVersion": 17521 case "UpgradeVersion":
17574 this.ParseUpgradeVersionElement(child, id); 17522 this.ParseUpgradeVersionElement(child, id);
17575 break; 17523 break;
17576 default: 17524 default:
17577 this.core.UnexpectedElement(node, child); 17525 this.Core.UnexpectedElement(node, child);
17578 break; 17526 break;
17579 } 17527 }
17580 } 17528 }
17581 else 17529 else
17582 { 17530 {
17583 this.core.ParseExtensionElement(node, child); 17531 this.Core.ParseExtensionElement(node, child);
17584 } 17532 }
17585 } 17533 }
17586 17534
17587
17588 // No rows created here. All row creation is done in ParseUpgradeVersionElement. 17535 // No rows created here. All row creation is done in ParseUpgradeVersionElement.
17589 } 17536 }
17590 17537
@@ -17611,93 +17558,93 @@ namespace WixToolset
17611 switch (attrib.Name.LocalName) 17558 switch (attrib.Name.LocalName)
17612 { 17559 {
17613 case "ExcludeLanguages": 17560 case "ExcludeLanguages":
17614 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 17561 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
17615 { 17562 {
17616 options |= MsiInterop.MsidbUpgradeAttributesLanguagesExclusive; 17563 options |= MsiInterop.MsidbUpgradeAttributesLanguagesExclusive;
17617 } 17564 }
17618 break; 17565 break;
17619 case "IgnoreRemoveFailure": 17566 case "IgnoreRemoveFailure":
17620 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 17567 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
17621 { 17568 {
17622 options |= MsiInterop.MsidbUpgradeAttributesIgnoreRemoveFailure; 17569 options |= MsiInterop.MsidbUpgradeAttributesIgnoreRemoveFailure;
17623 } 17570 }
17624 break; 17571 break;
17625 case "IncludeMaximum": 17572 case "IncludeMaximum":
17626 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 17573 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
17627 { 17574 {
17628 options |= MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive; 17575 options |= MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive;
17629 } 17576 }
17630 break; 17577 break;
17631 case "IncludeMinimum": // this is "yes" by default 17578 case "IncludeMinimum": // this is "yes" by default
17632 if (YesNoType.No == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 17579 if (YesNoType.No == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
17633 { 17580 {
17634 options &= ~MsiInterop.MsidbUpgradeAttributesVersionMinInclusive; 17581 options &= ~MsiInterop.MsidbUpgradeAttributesVersionMinInclusive;
17635 } 17582 }
17636 break; 17583 break;
17637 case "Language": 17584 case "Language":
17638 language = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17585 language = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17639 break; 17586 break;
17640 case "Minimum": 17587 case "Minimum":
17641 minimum = this.core.GetAttributeVersionValue(sourceLineNumbers, attrib); 17588 minimum = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
17642 break; 17589 break;
17643 case "Maximum": 17590 case "Maximum":
17644 maximum = this.core.GetAttributeVersionValue(sourceLineNumbers, attrib); 17591 maximum = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
17645 break; 17592 break;
17646 case "MigrateFeatures": 17593 case "MigrateFeatures":
17647 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 17594 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
17648 { 17595 {
17649 options |= MsiInterop.MsidbUpgradeAttributesMigrateFeatures; 17596 options |= MsiInterop.MsidbUpgradeAttributesMigrateFeatures;
17650 } 17597 }
17651 break; 17598 break;
17652 case "OnlyDetect": 17599 case "OnlyDetect":
17653 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 17600 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
17654 { 17601 {
17655 options |= MsiInterop.MsidbUpgradeAttributesOnlyDetect; 17602 options |= MsiInterop.MsidbUpgradeAttributesOnlyDetect;
17656 } 17603 }
17657 break; 17604 break;
17658 case "Property": 17605 case "Property":
17659 actionProperty = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 17606 actionProperty = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
17660 break; 17607 break;
17661 case "RemoveFeatures": 17608 case "RemoveFeatures":
17662 removeFeatures = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17609 removeFeatures = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17663 break; 17610 break;
17664 default: 17611 default:
17665 this.core.UnexpectedAttribute(node, attrib); 17612 this.Core.UnexpectedAttribute(node, attrib);
17666 break; 17613 break;
17667 } 17614 }
17668 } 17615 }
17669 else 17616 else
17670 { 17617 {
17671 this.core.ParseExtensionAttribute(node, attrib); 17618 this.Core.ParseExtensionAttribute(node, attrib);
17672 } 17619 }
17673 } 17620 }
17674 17621
17675 if (null == actionProperty) 17622 if (null == actionProperty)
17676 { 17623 {
17677 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property")); 17624 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property"));
17678 } 17625 }
17679 else if (actionProperty.ToUpper(CultureInfo.InvariantCulture) != actionProperty) 17626 else if (actionProperty.ToUpper(CultureInfo.InvariantCulture) != actionProperty)
17680 { 17627 {
17681 this.core.OnMessage(WixErrors.SecurePropertyNotUppercase(sourceLineNumbers, node.Name.LocalName, "Property", actionProperty)); 17628 this.Core.OnMessage(WixErrors.SecurePropertyNotUppercase(sourceLineNumbers, node.Name.LocalName, "Property", actionProperty));
17682 } 17629 }
17683 17630
17684 if (null == minimum && null == maximum) 17631 if (null == minimum && null == maximum)
17685 { 17632 {
17686 this.core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "Minimum", "Maximum")); 17633 this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "Minimum", "Maximum"));
17687 } 17634 }
17688 17635
17689 this.core.ParseForExtensionElements(node); 17636 this.Core.ParseForExtensionElements(node);
17690 17637
17691 if (!this.core.EncounteredError) 17638 if (!this.Core.EncounteredError)
17692 { 17639 {
17693 Row row = this.core.CreateRow(sourceLineNumbers, "Upgrade"); 17640 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Upgrade);
17694 row[0] = upgradeId; 17641 row.Set(0, upgradeId);
17695 row[1] = minimum; 17642 row.Set(1, minimum);
17696 row[2] = maximum; 17643 row.Set(2, maximum);
17697 row[3] = language; 17644 row.Set(3, language);
17698 row[4] = options; 17645 row.Set(4, options);
17699 row[5] = removeFeatures; 17646 row.Set(5, removeFeatures);
17700 row[6] = actionProperty; 17647 row.Set(6, actionProperty);
17701 17648
17702 // Ensure the action property is secure. 17649 // Ensure the action property is secure.
17703 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(actionProperty, AccessModifier.Private), false, true, false); 17650 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(actionProperty, AccessModifier.Private), false, true, false);
@@ -17706,7 +17653,7 @@ namespace WixToolset
17706 // if at least one row in Upgrade table lacks the OnlyDetect attribute. 17653 // if at least one row in Upgrade table lacks the OnlyDetect attribute.
17707 if (0 == (options & MsiInterop.MsidbUpgradeAttributesOnlyDetect)) 17654 if (0 == (options & MsiInterop.MsidbUpgradeAttributesOnlyDetect))
17708 { 17655 {
17709 this.core.CreateSimpleReference(sourceLineNumbers, "WixAction", "InstallExecuteSequence", "RemoveExistingProducts"); 17656 this.Core.CreateSimpleReference(sourceLineNumbers, "WixAction", "InstallExecuteSequence", "RemoveExistingProducts");
17710 } 17657 }
17711 } 17658 }
17712 } 17659 }
@@ -17737,101 +17684,101 @@ namespace WixToolset
17737 switch (attrib.Name.LocalName) 17684 switch (attrib.Name.LocalName)
17738 { 17685 {
17739 case "Id": 17686 case "Id":
17740 id = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17687 id = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17741 break; 17688 break;
17742 case "Argument": 17689 case "Argument":
17743 argument = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17690 argument = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17744 break; 17691 break;
17745 case "Command": 17692 case "Command":
17746 command = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17693 command = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17747 break; 17694 break;
17748 case "Sequence": 17695 case "Sequence":
17749 sequence = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); 17696 sequence = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue);
17750 break; 17697 break;
17751 case "Target": 17698 case "Target":
17752 target = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17699 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17753 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "TargetFile", "TargetProperty")); 17700 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "TargetFile", "TargetProperty"));
17754 break; 17701 break;
17755 case "TargetFile": 17702 case "TargetFile":
17756 targetFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17703 targetFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17757 this.core.CreateSimpleReference(sourceLineNumbers, "File", targetFile); 17704 this.Core.CreateSimpleReference(sourceLineNumbers, "File", targetFile);
17758 break; 17705 break;
17759 case "TargetProperty": 17706 case "TargetProperty":
17760 targetProperty = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17707 targetProperty = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17761 break; 17708 break;
17762 default: 17709 default:
17763 this.core.UnexpectedAttribute(node, attrib); 17710 this.Core.UnexpectedAttribute(node, attrib);
17764 break; 17711 break;
17765 } 17712 }
17766 } 17713 }
17767 else 17714 else
17768 { 17715 {
17769 this.core.ParseExtensionAttribute(node, attrib); 17716 this.Core.ParseExtensionAttribute(node, attrib);
17770 } 17717 }
17771 } 17718 }
17772 17719
17773 if (null == id) 17720 if (null == id)
17774 { 17721 {
17775 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 17722 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
17776 } 17723 }
17777 17724
17778 if (null != target && null != targetFile) 17725 if (null != target && null != targetFile)
17779 { 17726 {
17780 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Target", "TargetFile")); 17727 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Target", "TargetFile"));
17781 } 17728 }
17782 17729
17783 if (null != target && null != targetProperty) 17730 if (null != target && null != targetProperty)
17784 { 17731 {
17785 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Target", "TargetProperty")); 17732 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Target", "TargetProperty"));
17786 } 17733 }
17787 17734
17788 if (null != targetFile && null != targetProperty) 17735 if (null != targetFile && null != targetProperty)
17789 { 17736 {
17790 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "TargetFile", "TargetProperty")); 17737 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "TargetFile", "TargetProperty"));
17791 } 17738 }
17792 17739
17793 this.core.ParseForExtensionElements(node); 17740 this.Core.ParseForExtensionElements(node);
17794 17741
17795 if (YesNoType.Yes == advertise) 17742 if (YesNoType.Yes == advertise)
17796 { 17743 {
17797 if (null != target) 17744 if (null != target)
17798 { 17745 {
17799 this.core.OnMessage(WixErrors.IllegalAttributeWhenAdvertised(sourceLineNumbers, node.Name.LocalName, "Target")); 17746 this.Core.OnMessage(WixErrors.IllegalAttributeWhenAdvertised(sourceLineNumbers, node.Name.LocalName, "Target"));
17800 } 17747 }
17801 17748
17802 if (null != targetFile) 17749 if (null != targetFile)
17803 { 17750 {
17804 this.core.OnMessage(WixErrors.IllegalAttributeWhenAdvertised(sourceLineNumbers, node.Name.LocalName, "TargetFile")); 17751 this.Core.OnMessage(WixErrors.IllegalAttributeWhenAdvertised(sourceLineNumbers, node.Name.LocalName, "TargetFile"));
17805 } 17752 }
17806 17753
17807 if (null != targetProperty) 17754 if (null != targetProperty)
17808 { 17755 {
17809 this.core.OnMessage(WixErrors.IllegalAttributeWhenAdvertised(sourceLineNumbers, node.Name.LocalName, "TargetProperty")); 17756 this.Core.OnMessage(WixErrors.IllegalAttributeWhenAdvertised(sourceLineNumbers, node.Name.LocalName, "TargetProperty"));
17810 } 17757 }
17811 17758
17812 if (!this.core.EncounteredError) 17759 if (!this.Core.EncounteredError)
17813 { 17760 {
17814 Row row = this.core.CreateRow(sourceLineNumbers, "Verb"); 17761 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Verb);
17815 row[0] = extension; 17762 row.Set(0, extension);
17816 row[1] = id; 17763 row.Set(1, id);
17817 if (CompilerConstants.IntegerNotSet != sequence) 17764 if (CompilerConstants.IntegerNotSet != sequence)
17818 { 17765 {
17819 row[2] = sequence; 17766 row.Set(2, sequence);
17820 } 17767 }
17821 row[3] = command; 17768 row.Set(3, command);
17822 row[4] = argument; 17769 row.Set(4, argument);
17823 } 17770 }
17824 } 17771 }
17825 else if (YesNoType.No == advertise) 17772 else if (YesNoType.No == advertise)
17826 { 17773 {
17827 if (CompilerConstants.IntegerNotSet != sequence) 17774 if (CompilerConstants.IntegerNotSet != sequence)
17828 { 17775 {
17829 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Sequence", "Advertise", "no")); 17776 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Sequence", "Advertise", "no"));
17830 } 17777 }
17831 17778
17832 if (null == target && null == targetFile && null == targetProperty) 17779 if (null == target && null == targetFile && null == targetProperty)
17833 { 17780 {
17834 this.core.OnMessage(WixErrors.ExpectedAttributesWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "TargetFile", "TargetProperty", "Advertise", "no")); 17781 this.Core.OnMessage(WixErrors.ExpectedAttributesWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "TargetFile", "TargetProperty", "Advertise", "no"));
17835 } 17782 }
17836 17783
17837 if (null == target) 17784 if (null == target)
@@ -17856,10 +17803,10 @@ namespace WixToolset
17856 17803
17857 if (null != command) 17804 if (null != command)
17858 { 17805 {
17859 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(prefix, "\\shell\\", id), String.Empty, command, componentId); 17806 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(prefix, "\\shell\\", id), String.Empty, command, componentId);
17860 } 17807 }
17861 17808
17862 this.core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(prefix, "\\shell\\", id, "\\command"), String.Empty, target, componentId); 17809 this.Core.CreateRegistryRow(sourceLineNumbers, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat(prefix, "\\shell\\", id, "\\command"), String.Empty, target, componentId);
17863 } 17810 }
17864 } 17811 }
17865 17812
@@ -17883,36 +17830,36 @@ namespace WixToolset
17883 switch (attrib.Name.LocalName) 17830 switch (attrib.Name.LocalName)
17884 { 17831 {
17885 case "Id": 17832 case "Id":
17886 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 17833 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
17887 break; 17834 break;
17888 case "Key": 17835 case "Key":
17889 key = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17836 key = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17890 break; 17837 break;
17891 case "Value": 17838 case "Value":
17892 valueName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17839 valueName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17893 break; 17840 break;
17894 case "Win64": 17841 case "Win64":
17895 win64 = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 17842 win64 = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
17896 break; 17843 break;
17897 default: 17844 default:
17898 this.core.UnexpectedAttribute(node, attrib); 17845 this.Core.UnexpectedAttribute(node, attrib);
17899 break; 17846 break;
17900 } 17847 }
17901 } 17848 }
17902 else 17849 else
17903 { 17850 {
17904 this.core.ParseExtensionAttribute(node, attrib); 17851 this.Core.ParseExtensionAttribute(node, attrib);
17905 } 17852 }
17906 } 17853 }
17907 17854
17908 if (null == id) 17855 if (null == id)
17909 { 17856 {
17910 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 17857 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
17911 } 17858 }
17912 17859
17913 if (null == key) 17860 if (null == key)
17914 { 17861 {
17915 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); 17862 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
17916 } 17863 }
17917 17864
17918 BundleApprovedExeForElevationAttributes attributes = BundleApprovedExeForElevationAttributes.None; 17865 BundleApprovedExeForElevationAttributes attributes = BundleApprovedExeForElevationAttributes.None;
@@ -17922,14 +17869,14 @@ namespace WixToolset
17922 attributes |= BundleApprovedExeForElevationAttributes.Win64; 17869 attributes |= BundleApprovedExeForElevationAttributes.Win64;
17923 } 17870 }
17924 17871
17925 this.core.ParseForExtensionElements(node); 17872 this.Core.ParseForExtensionElements(node);
17926 17873
17927 if (!this.core.EncounteredError) 17874 if (!this.Core.EncounteredError)
17928 { 17875 {
17929 WixApprovedExeForElevationRow wixApprovedExeForElevationRow = (WixApprovedExeForElevationRow)this.core.CreateRow(sourceLineNumbers, "WixApprovedExeForElevation", id); 17876 var wixApprovedExeForElevationRow = (WixApprovedExeForElevationTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixApprovedExeForElevation, id);
17930 wixApprovedExeForElevationRow.Key = key; 17877 wixApprovedExeForElevationRow.Key = key;
17931 wixApprovedExeForElevationRow.ValueName = valueName; 17878 wixApprovedExeForElevationRow.Value = valueName;
17932 wixApprovedExeForElevationRow.Attributes = attributes; 17879 wixApprovedExeForElevationRow.Attributes = (int)attributes;
17933 } 17880 }
17934 } 17881 }
17935 17882
@@ -17969,19 +17916,19 @@ namespace WixToolset
17969 switch (attrib.Name.LocalName) 17916 switch (attrib.Name.LocalName)
17970 { 17917 {
17971 case "AboutUrl": 17918 case "AboutUrl":
17972 aboutUrl = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17919 aboutUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17973 break; 17920 break;
17974 case "Compressed": 17921 case "Compressed":
17975 compressed = this.core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); 17922 compressed = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
17976 break; 17923 break;
17977 case "Condition": 17924 case "Condition":
17978 condition = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17925 condition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17979 break; 17926 break;
17980 case "Copyright": 17927 case "Copyright":
17981 copyright = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17928 copyright = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17982 break; 17929 break;
17983 case "DisableModify": 17930 case "DisableModify":
17984 string value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17931 string value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
17985 switch (value) 17932 switch (value)
17986 { 17933 {
17987 case "button": 17934 case "button":
@@ -17994,51 +17941,51 @@ namespace WixToolset
17994 disableModify = 0; 17941 disableModify = 0;
17995 break; 17942 break;
17996 default: 17943 default:
17997 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "button", "yes", "no")); 17944 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "button", "yes", "no"));
17998 break; 17945 break;
17999 } 17946 }
18000 break; 17947 break;
18001 case "DisableRemove": 17948 case "DisableRemove":
18002 disableRemove = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 17949 disableRemove = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
18003 break; 17950 break;
18004 case "DisableRepair": 17951 case "DisableRepair":
18005 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); 17952 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
18006 break; 17953 break;
18007 case "HelpTelephone": 17954 case "HelpTelephone":
18008 helpTelephone = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17955 helpTelephone = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18009 break; 17956 break;
18010 case "HelpUrl": 17957 case "HelpUrl":
18011 helpUrl = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17958 helpUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18012 break; 17959 break;
18013 case "Manufacturer": 17960 case "Manufacturer":
18014 manufacturer = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17961 manufacturer = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18015 break; 17962 break;
18016 case "IconSourceFile": 17963 case "IconSourceFile":
18017 iconSourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17964 iconSourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18018 break; 17965 break;
18019 case "Name": 17966 case "Name":
18020 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17967 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18021 break; 17968 break;
18022 case "ParentName": 17969 case "ParentName":
18023 parentName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17970 parentName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18024 break; 17971 break;
18025 case "SplashScreenSourceFile": 17972 case "SplashScreenSourceFile":
18026 splashScreenSourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17973 splashScreenSourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18027 break; 17974 break;
18028 case "Tag": 17975 case "Tag":
18029 tag = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17976 tag = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18030 break; 17977 break;
18031 case "UpdateUrl": 17978 case "UpdateUrl":
18032 updateUrl = this.core.GetAttributeValue(sourceLineNumbers, attrib); 17979 updateUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18033 break; 17980 break;
18034 case "UpgradeCode": 17981 case "UpgradeCode":
18035 upgradeCode = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 17982 upgradeCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
18036 break; 17983 break;
18037 case "Version": 17984 case "Version":
18038 version = this.core.GetAttributeVersionValue(sourceLineNumbers, attrib); 17985 version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
18039 break; 17986 break;
18040 default: 17987 default:
18041 this.core.UnexpectedAttribute(node, attrib); 17988 this.Core.UnexpectedAttribute(node, attrib);
18042 break; 17989 break;
18043 } 17990 }
18044 } 17991 }
@@ -18046,16 +17993,16 @@ namespace WixToolset
18046 17993
18047 if (String.IsNullOrEmpty(version)) 17994 if (String.IsNullOrEmpty(version))
18048 { 17995 {
18049 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version")); 17996 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
18050 } 17997 }
18051 else if (!CompilerCore.IsValidModuleOrBundleVersion(version)) 17998 else if (!CompilerCore.IsValidModuleOrBundleVersion(version))
18052 { 17999 {
18053 this.core.OnMessage(WixWarnings.InvalidModuleOrBundleVersion(sourceLineNumbers, "Bundle", version)); 18000 this.Core.OnMessage(WixWarnings.InvalidModuleOrBundleVersion(sourceLineNumbers, "Bundle", version));
18054 } 18001 }
18055 18002
18056 if (String.IsNullOrEmpty(upgradeCode)) 18003 if (String.IsNullOrEmpty(upgradeCode))
18057 { 18004 {
18058 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "UpgradeCode")); 18005 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "UpgradeCode"));
18059 } 18006 }
18060 18007
18061 if (String.IsNullOrEmpty(copyright)) 18008 if (String.IsNullOrEmpty(copyright))
@@ -18082,14 +18029,14 @@ namespace WixToolset
18082 } 18029 }
18083 18030
18084 this.activeName = String.IsNullOrEmpty(name) ? Common.GenerateGuid() : name; 18031 this.activeName = String.IsNullOrEmpty(name) ? Common.GenerateGuid() : name;
18085 this.core.CreateActiveSection(this.activeName, SectionType.Bundle, 0); 18032 this.Core.CreateActiveSection(this.activeName, SectionType.Bundle, 0, this.Context.CompilationId);
18086 18033
18087 // Now that the active section is initialized, process only extension attributes. 18034 // Now that the active section is initialized, process only extension attributes.
18088 foreach (XAttribute attrib in node.Attributes()) 18035 foreach (XAttribute attrib in node.Attributes())
18089 { 18036 {
18090 if (!String.IsNullOrEmpty(attrib.Name.NamespaceName) && CompilerCore.WixNamespace != attrib.Name.Namespace) 18037 if (!String.IsNullOrEmpty(attrib.Name.NamespaceName) && CompilerCore.WixNamespace != attrib.Name.Namespace)
18091 { 18038 {
18092 this.core.ParseExtensionAttribute(node, attrib); 18039 this.Core.ParseExtensionAttribute(node, attrib);
18093 } 18040 }
18094 } 18041 }
18095 18042
@@ -18110,7 +18057,7 @@ namespace WixToolset
18110 if (baSeen) 18057 if (baSeen)
18111 { 18058 {
18112 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); 18059 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
18113 this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, "BootstrapperApplication")); 18060 this.Core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, "BootstrapperApplication"));
18114 } 18061 }
18115 this.ParseBootstrapperApplicationElement(child); 18062 this.ParseBootstrapperApplicationElement(child);
18116 baSeen = true; 18063 baSeen = true;
@@ -18128,7 +18075,7 @@ namespace WixToolset
18128 if (chainSeen) 18075 if (chainSeen)
18129 { 18076 {
18130 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); 18077 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
18131 this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, "Chain")); 18078 this.Core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, "Chain"));
18132 } 18079 }
18133 this.ParseChainElement(child); 18080 this.ParseChainElement(child);
18134 chainSeen = true; 18081 chainSeen = true;
@@ -18143,7 +18090,7 @@ namespace WixToolset
18143 if (logSeen) 18090 if (logSeen)
18144 { 18091 {
18145 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); 18092 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
18146 this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, "Log")); 18093 this.Core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, "Log"));
18147 } 18094 }
18148 logVariablePrefixAndExtension = this.ParseLogElement(child, fileSystemSafeBundleName); 18095 logVariablePrefixAndExtension = this.ParseLogElement(child, fileSystemSafeBundleName);
18149 logSeen = true; 18096 logSeen = true;
@@ -18167,86 +18114,86 @@ namespace WixToolset
18167 this.ParseWixVariableElement(child); 18114 this.ParseWixVariableElement(child);
18168 break; 18115 break;
18169 default: 18116 default:
18170 this.core.UnexpectedElement(node, child); 18117 this.Core.UnexpectedElement(node, child);
18171 break; 18118 break;
18172 } 18119 }
18173 } 18120 }
18174 else 18121 else
18175 { 18122 {
18176 this.core.ParseExtensionElement(node, child); 18123 this.Core.ParseExtensionElement(node, child);
18177 } 18124 }
18178 } 18125 }
18179 18126
18180 18127
18181 if (!chainSeen) 18128 if (!chainSeen)
18182 { 18129 {
18183 this.core.OnMessage(WixErrors.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "Chain")); 18130 this.Core.OnMessage(WixErrors.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "Chain"));
18184 } 18131 }
18185 18132
18186 if (!this.core.EncounteredError) 18133 if (!this.Core.EncounteredError)
18187 { 18134 {
18188 if (null != upgradeCode) 18135 if (null != upgradeCode)
18189 { 18136 {
18190 Row relatedBundleRow = this.core.CreateRow(sourceLineNumbers, "WixRelatedBundle"); 18137 var relatedBundleRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixRelatedBundle);
18191 relatedBundleRow[0] = upgradeCode; 18138 relatedBundleRow.Set(0, upgradeCode);
18192 relatedBundleRow[1] = (int)Wix.RelatedBundle.ActionType.Upgrade; 18139 relatedBundleRow.Set(1, (int)Wix.RelatedBundle.ActionType.Upgrade);
18193 } 18140 }
18194 18141
18195 WixBundleContainerRow containerRow = (WixBundleContainerRow)this.core.CreateRow(sourceLineNumbers, "WixBundleContainer"); 18142 var containerRow = (WixBundleContainerTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleContainer);
18196 containerRow.Id = Compiler.BurnDefaultAttachedContainerId; 18143 containerRow.WixBundleContainer = Compiler.BurnDefaultAttachedContainerId;
18197 containerRow.Name = "bundle-attached.cab"; 18144 containerRow.Name = "bundle-attached.cab";
18198 containerRow.Type = ContainerType.Attached; 18145 containerRow.Type = ContainerType.Attached;
18199 18146
18200 Row row = this.core.CreateRow(sourceLineNumbers, "WixBundle"); 18147 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundle);
18201 row[0] = version; 18148 row.Set(0, version);
18202 row[1] = copyright; 18149 row.Set(1, copyright);
18203 row[2] = name; 18150 row.Set(2, name);
18204 row[3] = aboutUrl; 18151 row.Set(3, aboutUrl);
18205 if (-1 != disableModify) 18152 if (-1 != disableModify)
18206 { 18153 {
18207 row[4] = disableModify; 18154 row.Set(4, disableModify);
18208 } 18155 }
18209 if (YesNoType.NotSet != disableRemove) 18156 if (YesNoType.NotSet != disableRemove)
18210 { 18157 {
18211 row[5] = (YesNoType.Yes == disableRemove) ? 1 : 0; 18158 row.Set(5, (YesNoType.Yes == disableRemove) ? 1 : 0);
18212 } 18159 }
18213 // row[6] - (deprecated) "disable repair" 18160 // row.Set(6] - (deprecated) "disable repair"
18214 row[7] = helpTelephone; 18161 row.Set(7, helpTelephone);
18215 row[8] = helpUrl; 18162 row.Set(8, helpUrl);
18216 row[9] = manufacturer; 18163 row.Set(9, manufacturer);
18217 row[10] = updateUrl; 18164 row.Set(10, updateUrl);
18218 if (YesNoDefaultType.Default != compressed) 18165 if (YesNoDefaultType.Default != compressed)
18219 { 18166 {
18220 row[11] = (YesNoDefaultType.Yes == compressed) ? 1 : 0; 18167 row.Set(11, (YesNoDefaultType.Yes == compressed) ? 1 : 0);
18221 } 18168 }
18222 18169
18223 row[12] = logVariablePrefixAndExtension; 18170 row.Set(12, logVariablePrefixAndExtension);
18224 row[13] = iconSourceFile; 18171 row.Set(13, iconSourceFile);
18225 row[14] = splashScreenSourceFile; 18172 row.Set(14, splashScreenSourceFile);
18226 row[15] = condition; 18173 row.Set(15, condition);
18227 row[16] = tag; 18174 row.Set(16, tag);
18228 row[17] = this.CurrentPlatform.ToString(); 18175 row.Set(17, this.CurrentPlatform.ToString());
18229 row[18] = parentName; 18176 row.Set(18, parentName);
18230 row[19] = upgradeCode; 18177 row.Set(19, upgradeCode);
18231 18178
18232 // Ensure that the bundle stores the well-known persisted values. 18179 // Ensure that the bundle stores the well-known persisted values.
18233 WixBundleVariableRow bundleNameWellKnownVariable = (WixBundleVariableRow)this.core.CreateRow(sourceLineNumbers, "WixBundleVariable"); 18180 var bundleNameWellKnownVariable = (WixBundleVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleVariable);
18234 bundleNameWellKnownVariable.Id = Compiler.BURN_BUNDLE_NAME; 18181 bundleNameWellKnownVariable.WixBundleVariable = Compiler.BURN_BUNDLE_NAME;
18235 bundleNameWellKnownVariable.Hidden = false; 18182 bundleNameWellKnownVariable.Hidden = false;
18236 bundleNameWellKnownVariable.Persisted = true; 18183 bundleNameWellKnownVariable.Persisted = true;
18237 18184
18238 WixBundleVariableRow bundleOriginalSourceWellKnownVariable = (WixBundleVariableRow)this.core.CreateRow(sourceLineNumbers, "WixBundleVariable"); 18185 var bundleOriginalSourceWellKnownVariable = (WixBundleVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleVariable);
18239 bundleOriginalSourceWellKnownVariable.Id = Compiler.BURN_BUNDLE_ORIGINAL_SOURCE; 18186 bundleOriginalSourceWellKnownVariable.WixBundleVariable = Compiler.BURN_BUNDLE_ORIGINAL_SOURCE;
18240 bundleOriginalSourceWellKnownVariable.Hidden = false; 18187 bundleOriginalSourceWellKnownVariable.Hidden = false;
18241 bundleOriginalSourceWellKnownVariable.Persisted = true; 18188 bundleOriginalSourceWellKnownVariable.Persisted = true;
18242 18189
18243 WixBundleVariableRow bundleOriginalSourceFolderWellKnownVariable = (WixBundleVariableRow)this.core.CreateRow(sourceLineNumbers, "WixBundleVariable"); 18190 var bundleOriginalSourceFolderWellKnownVariable = (WixBundleVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleVariable);
18244 bundleOriginalSourceFolderWellKnownVariable.Id = Compiler.BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER; 18191 bundleOriginalSourceFolderWellKnownVariable.WixBundleVariable = Compiler.BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER;
18245 bundleOriginalSourceFolderWellKnownVariable.Hidden = false; 18192 bundleOriginalSourceFolderWellKnownVariable.Hidden = false;
18246 bundleOriginalSourceFolderWellKnownVariable.Persisted = true; 18193 bundleOriginalSourceFolderWellKnownVariable.Persisted = true;
18247 18194
18248 WixBundleVariableRow bundleLastUsedSourceWellKnownVariable = (WixBundleVariableRow)this.core.CreateRow(sourceLineNumbers, "WixBundleVariable"); 18195 var bundleLastUsedSourceWellKnownVariable = (WixBundleVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleVariable);
18249 bundleLastUsedSourceWellKnownVariable.Id = Compiler.BURN_BUNDLE_LAST_USED_SOURCE; 18196 bundleLastUsedSourceWellKnownVariable.WixBundleVariable = Compiler.BURN_BUNDLE_LAST_USED_SOURCE;
18250 bundleLastUsedSourceWellKnownVariable.Hidden = false; 18197 bundleLastUsedSourceWellKnownVariable.Hidden = false;
18251 bundleLastUsedSourceWellKnownVariable.Persisted = true; 18198 bundleLastUsedSourceWellKnownVariable.Persisted = true;
18252 } 18199 }
@@ -18271,25 +18218,25 @@ namespace WixToolset
18271 switch (attrib.Name.LocalName) 18218 switch (attrib.Name.LocalName)
18272 { 18219 {
18273 case "Disable": 18220 case "Disable":
18274 disableLog = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 18221 disableLog = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
18275 break; 18222 break;
18276 case "PathVariable": 18223 case "PathVariable":
18277 variable = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 18224 variable = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
18278 break; 18225 break;
18279 case "Prefix": 18226 case "Prefix":
18280 logPrefix = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18227 logPrefix = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18281 break; 18228 break;
18282 case "Extension": 18229 case "Extension":
18283 logExtension = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18230 logExtension = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18284 break; 18231 break;
18285 default: 18232 default:
18286 this.core.UnexpectedAttribute(node, attrib); 18233 this.Core.UnexpectedAttribute(node, attrib);
18287 break; 18234 break;
18288 } 18235 }
18289 } 18236 }
18290 else 18237 else
18291 { 18238 {
18292 this.core.ParseExtensionAttribute(node, attrib); 18239 this.Core.ParseExtensionAttribute(node, attrib);
18293 } 18240 }
18294 } 18241 }
18295 18242
@@ -18298,7 +18245,7 @@ namespace WixToolset
18298 logExtension = String.Concat(".", logExtension); 18245 logExtension = String.Concat(".", logExtension);
18299 } 18246 }
18300 18247
18301 this.core.ParseForExtensionElements(node); 18248 this.Core.ParseForExtensionElements(node);
18302 18249
18303 return YesNoType.Yes == disableLog ? null : String.Concat(variable, ":", logPrefix, logExtension); 18250 return YesNoType.Yes == disableLog ? null : String.Concat(variable, ":", logPrefix, logExtension);
18304 } 18251 }
@@ -18320,13 +18267,13 @@ namespace WixToolset
18320 switch (attrib.Name.LocalName) 18267 switch (attrib.Name.LocalName)
18321 { 18268 {
18322 case "Id": 18269 case "Id":
18323 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 18270 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
18324 break; 18271 break;
18325 case "SourceFile": 18272 case "SourceFile":
18326 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18273 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18327 break; 18274 break;
18328 default: 18275 default:
18329 this.core.UnexpectedAttribute(node, attrib); 18276 this.Core.UnexpectedAttribute(node, attrib);
18330 break; 18277 break;
18331 } 18278 }
18332 } 18279 }
@@ -18334,23 +18281,23 @@ namespace WixToolset
18334 18281
18335 if (null == id) 18282 if (null == id)
18336 { 18283 {
18337 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 18284 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
18338 } 18285 }
18339 18286
18340 if (null == sourceFile) 18287 if (null == sourceFile)
18341 { 18288 {
18342 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); 18289 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
18343 } 18290 }
18344 18291
18345 this.core.ParseForExtensionElements(node); 18292 this.Core.ParseForExtensionElements(node);
18346 18293
18347 // Create catalog row 18294 // Create catalog row
18348 if (!this.core.EncounteredError) 18295 if (!this.Core.EncounteredError)
18349 { 18296 {
18350 this.CreatePayloadRow(sourceLineNumbers, id, Path.GetFileName(sourceFile), sourceFile, null, ComplexReferenceParentType.Container, Compiler.BurnUXContainerId, ComplexReferenceChildType.Unknown, null, YesNoDefaultType.Yes, YesNoType.Yes, null, null, null); 18297 this.CreatePayloadRow(sourceLineNumbers, id, Path.GetFileName(sourceFile), sourceFile, null, ComplexReferenceParentType.Container, Compiler.BurnUXContainerId, ComplexReferenceChildType.Unknown, null, YesNoDefaultType.Yes, YesNoType.Yes, null, null, null);
18351 18298
18352 WixBundleCatalogRow wixCatalogRow = (WixBundleCatalogRow)this.core.CreateRow(sourceLineNumbers, "WixBundleCatalog", id); 18299 var wixCatalogRow = (WixBundleCatalogTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleCatalog, id);
18353 wixCatalogRow.Payload = id.Id; 18300 wixCatalogRow.Payload_ = id.Id;
18354 } 18301 }
18355 } 18302 }
18356 18303
@@ -18373,29 +18320,29 @@ namespace WixToolset
18373 switch (attrib.Name.LocalName) 18320 switch (attrib.Name.LocalName)
18374 { 18321 {
18375 case "Id": 18322 case "Id":
18376 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 18323 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
18377 break; 18324 break;
18378 case "DownloadUrl": 18325 case "DownloadUrl":
18379 downloadUrl = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18326 downloadUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18380 break; 18327 break;
18381 case "Name": 18328 case "Name":
18382 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18329 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18383 break; 18330 break;
18384 case "Type": 18331 case "Type":
18385 string typeString = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18332 string typeString = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18386 if (!Enum.TryParse<ContainerType>(typeString, out type)) 18333 if (!Enum.TryParse<ContainerType>(typeString, out type))
18387 { 18334 {
18388 this.core.OnMessage(WixErrors.IllegalAttributeValueWithLegalList(sourceLineNumbers, node.Name.LocalName, "Type", typeString, "attached, detached")); 18335 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithLegalList(sourceLineNumbers, node.Name.LocalName, "Type", typeString, "attached, detached"));
18389 } 18336 }
18390 break; 18337 break;
18391 default: 18338 default:
18392 this.core.UnexpectedAttribute(node, attrib); 18339 this.Core.UnexpectedAttribute(node, attrib);
18393 break; 18340 break;
18394 } 18341 }
18395 } 18342 }
18396 else 18343 else
18397 { 18344 {
18398 this.core.ParseExtensionAttribute(node, attrib); 18345 this.Core.ParseExtensionAttribute(node, attrib);
18399 } 18346 }
18400 } 18347 }
18401 18348
@@ -18403,17 +18350,17 @@ namespace WixToolset
18403 { 18350 {
18404 if (!String.IsNullOrEmpty(name)) 18351 if (!String.IsNullOrEmpty(name))
18405 { 18352 {
18406 id = this.core.CreateIdentifierFromFilename(name); 18353 id = this.Core.CreateIdentifierFromFilename(name);
18407 } 18354 }
18408 18355
18409 if (null == id) 18356 if (null == id)
18410 { 18357 {
18411 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 18358 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
18412 id = Identifier.Invalid; 18359 id = Identifier.Invalid;
18413 } 18360 }
18414 else if (!Common.IsIdentifier(id.Id)) 18361 else if (!Common.IsIdentifier(id.Id))
18415 { 18362 {
18416 this.core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id)); 18363 this.Core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id));
18417 } 18364 }
18418 } 18365 }
18419 else if (null == name) 18366 else if (null == name)
@@ -18423,7 +18370,7 @@ namespace WixToolset
18423 18370
18424 if (!String.IsNullOrEmpty(downloadUrl) && ContainerType.Detached != type) 18371 if (!String.IsNullOrEmpty(downloadUrl) && ContainerType.Detached != type)
18425 { 18372 {
18426 this.core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DownloadUrl", "Type", "attached")); 18373 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DownloadUrl", "Type", "attached"));
18427 } 18374 }
18428 18375
18429 foreach (XElement child in node.Elements()) 18376 foreach (XElement child in node.Elements())
@@ -18436,20 +18383,20 @@ namespace WixToolset
18436 this.ParsePackageGroupRefElement(child, ComplexReferenceParentType.Container, id.Id); 18383 this.ParsePackageGroupRefElement(child, ComplexReferenceParentType.Container, id.Id);
18437 break; 18384 break;
18438 default: 18385 default:
18439 this.core.UnexpectedElement(node, child); 18386 this.Core.UnexpectedElement(node, child);
18440 break; 18387 break;
18441 } 18388 }
18442 } 18389 }
18443 else 18390 else
18444 { 18391 {
18445 this.core.ParseExtensionElement(node, child); 18392 this.Core.ParseExtensionElement(node, child);
18446 } 18393 }
18447 } 18394 }
18448 18395
18449 18396
18450 if (!this.core.EncounteredError) 18397 if (!this.Core.EncounteredError)
18451 { 18398 {
18452 WixBundleContainerRow row = (WixBundleContainerRow)this.core.CreateRow(sourceLineNumbers, "WixBundleContainer", id); 18399 var row = (WixBundleContainerTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleContainer, id);
18453 row.Name = name; 18400 row.Name = name;
18454 row.Type = type; 18401 row.Type = type;
18455 row.DownloadUrl = downloadUrl; 18402 row.DownloadUrl = downloadUrl;
@@ -18490,13 +18437,13 @@ namespace WixToolset
18490 previousType = ComplexReferenceChildType.PayloadGroup; 18437 previousType = ComplexReferenceChildType.PayloadGroup;
18491 break; 18438 break;
18492 default: 18439 default:
18493 this.core.UnexpectedElement(node, child); 18440 this.Core.UnexpectedElement(node, child);
18494 break; 18441 break;
18495 } 18442 }
18496 } 18443 }
18497 else 18444 else
18498 { 18445 {
18499 this.core.ParseExtensionElement(node, child); 18446 this.Core.ParseExtensionElement(node, child);
18500 } 18447 }
18501 } 18448 }
18502 18449
@@ -18505,21 +18452,21 @@ namespace WixToolset
18505 // We need *either* <Payload> or <PayloadGroupRef> or even just @SourceFile on the BA... 18452 // We need *either* <Payload> or <PayloadGroupRef> or even just @SourceFile on the BA...
18506 // but we just say there's a missing <Payload>. 18453 // but we just say there's a missing <Payload>.
18507 // TODO: Is there a better message for this? 18454 // TODO: Is there a better message for this?
18508 this.core.OnMessage(WixErrors.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "Payload")); 18455 this.Core.OnMessage(WixErrors.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "Payload"));
18509 } 18456 }
18510 18457
18511 // Add the application as an attached container and if an Id was provided add that too. 18458 // Add the application as an attached container and if an Id was provided add that too.
18512 if (!this.core.EncounteredError) 18459 if (!this.Core.EncounteredError)
18513 { 18460 {
18514 WixBundleContainerRow containerRow = (WixBundleContainerRow)this.core.CreateRow(sourceLineNumbers, "WixBundleContainer"); 18461 var containerRow = (WixBundleContainerTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleContainer);
18515 containerRow.Id = Compiler.BurnUXContainerId; 18462 containerRow.WixBundleContainer = Compiler.BurnUXContainerId;
18516 containerRow.Name = "bundle-ux.cab"; 18463 containerRow.Name = "bundle-ux.cab";
18517 containerRow.Type = ContainerType.Attached; 18464 containerRow.Type = ContainerType.Attached;
18518 18465
18519 if (!String.IsNullOrEmpty(id)) 18466 if (!String.IsNullOrEmpty(id))
18520 { 18467 {
18521 Row row = this.core.CreateRow(sourceLineNumbers, "WixBootstrapperApplication"); 18468 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBootstrapperApplication);
18522 row[0] = id; 18469 row.Set(0, id);
18523 } 18470 }
18524 } 18471 }
18525 } 18472 }
@@ -18542,16 +18489,16 @@ namespace WixToolset
18542 switch (attrib.Name.LocalName) 18489 switch (attrib.Name.LocalName)
18543 { 18490 {
18544 case "Id": 18491 case "Id":
18545 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 18492 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
18546 break; 18493 break;
18547 default: 18494 default:
18548 this.core.UnexpectedAttribute(node, attrib); 18495 this.Core.UnexpectedAttribute(node, attrib);
18549 break; 18496 break;
18550 } 18497 }
18551 } 18498 }
18552 else 18499 else
18553 { 18500 {
18554 this.core.ParseExtensionAttribute(node, attrib); 18501 this.Core.ParseExtensionAttribute(node, attrib);
18555 } 18502 }
18556 } 18503 }
18557 18504
@@ -18570,24 +18517,24 @@ namespace WixToolset
18570 previousType = ComplexReferenceChildType.PayloadGroup; 18517 previousType = ComplexReferenceChildType.PayloadGroup;
18571 break; 18518 break;
18572 default: 18519 default:
18573 this.core.UnexpectedElement(node, child); 18520 this.Core.UnexpectedElement(node, child);
18574 break; 18521 break;
18575 } 18522 }
18576 } 18523 }
18577 else 18524 else
18578 { 18525 {
18579 this.core.ParseExtensionElement(node, child); 18526 this.Core.ParseExtensionElement(node, child);
18580 } 18527 }
18581 } 18528 }
18582 18529
18583 18530
18584 if (String.IsNullOrEmpty(id)) 18531 if (String.IsNullOrEmpty(id))
18585 { 18532 {
18586 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 18533 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
18587 } 18534 }
18588 else 18535 else
18589 { 18536 {
18590 this.core.CreateSimpleReference(sourceLineNumbers, "WixBootstrapperApplication", id); 18537 this.Core.CreateSimpleReference(sourceLineNumbers, "WixBootstrapperApplication", id);
18591 } 18538 }
18592 } 18539 }
18593 18540
@@ -18616,28 +18563,28 @@ namespace WixToolset
18616 switch (attrib.Name.LocalName) 18563 switch (attrib.Name.LocalName)
18617 { 18564 {
18618 case "Manufacturer": 18565 case "Manufacturer":
18619 manufacturer = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18566 manufacturer = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18620 break; 18567 break;
18621 case "Department": 18568 case "Department":
18622 department = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18569 department = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18623 break; 18570 break;
18624 case "ProductFamily": 18571 case "ProductFamily":
18625 productFamily = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18572 productFamily = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18626 break; 18573 break;
18627 case "Name": 18574 case "Name":
18628 name = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18575 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18629 break; 18576 break;
18630 case "Classification": 18577 case "Classification":
18631 classification = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18578 classification = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18632 break; 18579 break;
18633 default: 18580 default:
18634 this.core.UnexpectedAttribute(node, attrib); 18581 this.Core.UnexpectedAttribute(node, attrib);
18635 break; 18582 break;
18636 } 18583 }
18637 } 18584 }
18638 else 18585 else
18639 { 18586 {
18640 this.core.ParseExtensionAttribute(node, attrib); 18587 this.Core.ParseExtensionAttribute(node, attrib);
18641 } 18588 }
18642 } 18589 }
18643 18590
@@ -18649,7 +18596,7 @@ namespace WixToolset
18649 } 18596 }
18650 else 18597 else
18651 { 18598 {
18652 this.core.OnMessage(WixErrors.ExpectedAttributeInElementOrParent(sourceLineNumbers, node.Name.LocalName, "Manufacturer", node.Parent.Name.LocalName)); 18599 this.Core.OnMessage(WixErrors.ExpectedAttributeInElementOrParent(sourceLineNumbers, node.Name.LocalName, "Manufacturer", node.Parent.Name.LocalName));
18653 } 18600 }
18654 } 18601 }
18655 18602
@@ -18669,25 +18616,25 @@ namespace WixToolset
18669 } 18616 }
18670 else 18617 else
18671 { 18618 {
18672 this.core.OnMessage(WixErrors.ExpectedAttributeInElementOrParent(sourceLineNumbers, node.Name.LocalName, "Name", node.Parent.Name.LocalName)); 18619 this.Core.OnMessage(WixErrors.ExpectedAttributeInElementOrParent(sourceLineNumbers, node.Name.LocalName, "Name", node.Parent.Name.LocalName));
18673 } 18620 }
18674 } 18621 }
18675 18622
18676 if (String.IsNullOrEmpty(classification)) 18623 if (String.IsNullOrEmpty(classification))
18677 { 18624 {
18678 this.core.OnMessage(WixErrors.IllegalEmptyAttributeValue(sourceLineNumbers, node.Name.LocalName, "Classification", defaultClassification)); 18625 this.Core.OnMessage(WixErrors.IllegalEmptyAttributeValue(sourceLineNumbers, node.Name.LocalName, "Classification", defaultClassification));
18679 } 18626 }
18680 18627
18681 this.core.ParseForExtensionElements(node); 18628 this.Core.ParseForExtensionElements(node);
18682 18629
18683 if (!this.core.EncounteredError) 18630 if (!this.Core.EncounteredError)
18684 { 18631 {
18685 Row row = this.core.CreateRow(sourceLineNumbers, "WixUpdateRegistration"); 18632 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixUpdateRegistration);
18686 row[0] = manufacturer; 18633 row.Set(0, manufacturer);
18687 row[1] = department; 18634 row.Set(1, department);
18688 row[2] = productFamily; 18635 row.Set(2, productFamily);
18689 row[3] = name; 18636 row.Set(3, name);
18690 row[4] = classification; 18637 row.Set(4, classification);
18691 } 18638 }
18692 } 18639 }
18693 18640
@@ -18713,13 +18660,13 @@ namespace WixToolset
18713 switch (child.Name.LocalName) 18660 switch (child.Name.LocalName)
18714 { 18661 {
18715 default: 18662 default:
18716 this.core.UnexpectedElement(node, child); 18663 this.Core.UnexpectedElement(node, child);
18717 break; 18664 break;
18718 } 18665 }
18719 } 18666 }
18720 else 18667 else
18721 { 18668 {
18722 this.core.ParseExtensionElement(node, child, context); 18669 this.Core.ParseExtensionElement(node, child, context);
18723 } 18670 }
18724 } 18671 }
18725 18672
@@ -18756,25 +18703,25 @@ namespace WixToolset
18756 switch (attrib.Name.LocalName) 18703 switch (attrib.Name.LocalName)
18757 { 18704 {
18758 case "Id": 18705 case "Id":
18759 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 18706 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
18760 break; 18707 break;
18761 case "Compressed": 18708 case "Compressed":
18762 compressed = this.core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); 18709 compressed = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
18763 break; 18710 break;
18764 case "Name": 18711 case "Name":
18765 name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true); 18712 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true);
18766 break; 18713 break;
18767 case "SourceFile": 18714 case "SourceFile":
18768 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18715 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18769 break; 18716 break;
18770 case "DownloadUrl": 18717 case "DownloadUrl":
18771 downloadUrl = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18718 downloadUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18772 break; 18719 break;
18773 case "EnableSignatureVerification": 18720 case "EnableSignatureVerification":
18774 enableSignatureVerification = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 18721 enableSignatureVerification = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
18775 break; 18722 break;
18776 default: 18723 default:
18777 this.core.UnexpectedAttribute(node, attrib); 18724 this.Core.UnexpectedAttribute(node, attrib);
18778 break; 18725 break;
18779 } 18726 }
18780 } 18727 }
@@ -18792,7 +18739,7 @@ namespace WixToolset
18792 18739
18793 if (null == id) 18740 if (null == id)
18794 { 18741 {
18795 id = this.core.CreateIdentifier("pay", (null != sourceFile) ? sourceFile.ToUpperInvariant() : String.Empty); 18742 id = this.Core.CreateIdentifier("pay", (null != sourceFile) ? sourceFile.ToUpperInvariant() : String.Empty);
18796 } 18743 }
18797 18744
18798 // Now that the PayloadId is known, we can parse the extension attributes. 18745 // Now that the PayloadId is known, we can parse the extension attributes.
@@ -18801,7 +18748,7 @@ namespace WixToolset
18801 18748
18802 foreach (XAttribute extensionAttribute in extensionAttributes) 18749 foreach (XAttribute extensionAttribute in extensionAttributes)
18803 { 18750 {
18804 this.core.ParseExtensionAttribute(node, extensionAttribute, context); 18751 this.Core.ParseExtensionAttribute(node, extensionAttribute, context);
18805 } 18752 }
18806 18753
18807 // We only handle the elements we care about. Let caller handle other children. 18754 // We only handle the elements we care about. Let caller handle other children.
@@ -18811,13 +18758,13 @@ namespace WixToolset
18811 18758
18812 if (CompilerCore.WixNamespace == node.Name.Namespace && node.Name.LocalName != "ExePackage") 18759 if (CompilerCore.WixNamespace == node.Name.Namespace && node.Name.LocalName != "ExePackage")
18813 { 18760 {
18814 this.core.OnMessage(WixErrors.RemotePayloadUnsupported(childSourceLineNumbers)); 18761 this.Core.OnMessage(WixErrors.RemotePayloadUnsupported(childSourceLineNumbers));
18815 continue; 18762 continue;
18816 } 18763 }
18817 18764
18818 if (null != remotePayload) 18765 if (null != remotePayload)
18819 { 18766 {
18820 this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName)); 18767 this.Core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName));
18821 } 18768 }
18822 18769
18823 remotePayload = this.ParseRemotePayloadElement(child); 18770 remotePayload = this.ParseRemotePayloadElement(child);
@@ -18825,11 +18772,11 @@ namespace WixToolset
18825 18772
18826 if (null != sourceFile && null != remotePayload) 18773 if (null != sourceFile && null != remotePayload)
18827 { 18774 {
18828 this.core.OnMessage(WixErrors.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name.LocalName, "RemotePayload", "SourceFile")); 18775 this.Core.OnMessage(WixErrors.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name.LocalName, "RemotePayload", "SourceFile"));
18829 } 18776 }
18830 else if (null == sourceFile && null == remotePayload) 18777 else if (null == sourceFile && null == remotePayload)
18831 { 18778 {
18832 this.core.OnMessage(WixErrors.ExpectedAttributeOrElement(sourceLineNumbers, node.Name.LocalName, "SourceFile", "RemotePayload")); 18779 this.Core.OnMessage(WixErrors.ExpectedAttributeOrElement(sourceLineNumbers, node.Name.LocalName, "SourceFile", "RemotePayload"));
18833 } 18780 }
18834 else if (null == sourceFile) 18781 else if (null == sourceFile)
18835 { 18782 {
@@ -18838,14 +18785,14 @@ namespace WixToolset
18838 18785
18839 if (null == downloadUrl && null != remotePayload) 18786 if (null == downloadUrl && null != remotePayload)
18840 { 18787 {
18841 this.core.OnMessage(WixErrors.ExpectedAttributeWithElement(sourceLineNumbers, node.Name.LocalName, "DownloadUrl", "RemotePayload")); 18788 this.Core.OnMessage(WixErrors.ExpectedAttributeWithElement(sourceLineNumbers, node.Name.LocalName, "DownloadUrl", "RemotePayload"));
18842 } 18789 }
18843 18790
18844 if (Compiler.BurnUXContainerId == parentId) 18791 if (Compiler.BurnUXContainerId == parentId)
18845 { 18792 {
18846 if (compressed == YesNoDefaultType.No) 18793 if (compressed == YesNoDefaultType.No)
18847 { 18794 {
18848 core.OnMessage(WixWarnings.UxPayloadsOnlySupportEmbedding(sourceLineNumbers, sourceFile)); 18795 Core.OnMessage(WixWarnings.UxPayloadsOnlySupportEmbedding(sourceLineNumbers, sourceFile));
18849 } 18796 }
18850 18797
18851 compressed = YesNoDefaultType.Yes; 18798 compressed = YesNoDefaultType.Yes;
@@ -18868,60 +18815,60 @@ namespace WixToolset
18868 switch (attrib.Name.LocalName) 18815 switch (attrib.Name.LocalName)
18869 { 18816 {
18870 case "CertificatePublicKey": 18817 case "CertificatePublicKey":
18871 remotePayload.CertificatePublicKey = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18818 remotePayload.CertificatePublicKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18872 break; 18819 break;
18873 case "CertificateThumbprint": 18820 case "CertificateThumbprint":
18874 remotePayload.CertificateThumbprint = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18821 remotePayload.CertificateThumbprint = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18875 break; 18822 break;
18876 case "Description": 18823 case "Description":
18877 remotePayload.Description = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18824 remotePayload.Description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18878 break; 18825 break;
18879 case "Hash": 18826 case "Hash":
18880 remotePayload.Hash = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18827 remotePayload.Hash = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18881 break; 18828 break;
18882 case "ProductName": 18829 case "ProductName":
18883 remotePayload.ProductName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18830 remotePayload.ProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18884 break; 18831 break;
18885 case "Size": 18832 case "Size":
18886 remotePayload.Size = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 18833 remotePayload.Size = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
18887 break; 18834 break;
18888 case "Version": 18835 case "Version":
18889 remotePayload.Version = this.core.GetAttributeValue(sourceLineNumbers, attrib); 18836 remotePayload.Version = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
18890 break; 18837 break;
18891 default: 18838 default:
18892 this.core.UnexpectedAttribute(node, attrib); 18839 this.Core.UnexpectedAttribute(node, attrib);
18893 break; 18840 break;
18894 } 18841 }
18895 } 18842 }
18896 else 18843 else
18897 { 18844 {
18898 this.core.ParseExtensionAttribute(node, attrib); 18845 this.Core.ParseExtensionAttribute(node, attrib);
18899 } 18846 }
18900 } 18847 }
18901 18848
18902 if (String.IsNullOrEmpty(remotePayload.ProductName)) 18849 if (String.IsNullOrEmpty(remotePayload.ProductName))
18903 { 18850 {
18904 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ProductName")); 18851 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ProductName"));
18905 } 18852 }
18906 18853
18907 if (String.IsNullOrEmpty(remotePayload.Description)) 18854 if (String.IsNullOrEmpty(remotePayload.Description))
18908 { 18855 {
18909 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description")); 18856 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description"));
18910 } 18857 }
18911 18858
18912 if (String.IsNullOrEmpty(remotePayload.Hash)) 18859 if (String.IsNullOrEmpty(remotePayload.Hash))
18913 { 18860 {
18914 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Hash")); 18861 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Hash"));
18915 } 18862 }
18916 18863
18917 if (0 == remotePayload.Size) 18864 if (0 == remotePayload.Size)
18918 { 18865 {
18919 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Size")); 18866 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Size"));
18920 } 18867 }
18921 18868
18922 if (String.IsNullOrEmpty(remotePayload.Version)) 18869 if (String.IsNullOrEmpty(remotePayload.Version))
18923 { 18870 {
18924 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version")); 18871 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
18925 } 18872 }
18926 18873
18927 return remotePayload; 18874 return remotePayload;
@@ -18933,15 +18880,15 @@ namespace WixToolset
18933 /// <param name="node">Element to parse</param> 18880 /// <param name="node">Element to parse</param>
18934 /// <param name="parentType">ComplexReferenceParentType of parent element</param> 18881 /// <param name="parentType">ComplexReferenceParentType of parent element</param>
18935 /// <param name="parentId">Identifier of parent element.</param> 18882 /// <param name="parentId">Identifier of parent element.</param>
18936 private WixBundlePayloadRow CreatePayloadRow(SourceLineNumber sourceLineNumbers, Identifier id, string name, string sourceFile, string downloadUrl, ComplexReferenceParentType parentType, 18883 private WixBundlePayloadTuple CreatePayloadRow(SourceLineNumber sourceLineNumbers, Identifier id, string name, string sourceFile, string downloadUrl, ComplexReferenceParentType parentType,
18937 string parentId, ComplexReferenceChildType previousType, string previousId, YesNoDefaultType compressed, YesNoType enableSignatureVerification, string displayName, string description, 18884 string parentId, ComplexReferenceChildType previousType, string previousId, YesNoDefaultType compressed, YesNoType enableSignatureVerification, string displayName, string description,
18938 Wix.RemotePayload remotePayload) 18885 Wix.RemotePayload remotePayload)
18939 { 18886 {
18940 WixBundlePayloadRow row = null; 18887 WixBundlePayloadTuple row = null;
18941 18888
18942 if (!this.core.EncounteredError) 18889 if (!this.Core.EncounteredError)
18943 { 18890 {
18944 row = (WixBundlePayloadRow)this.core.CreateRow(sourceLineNumbers, "WixBundlePayload", id); 18891 row = (WixBundlePayloadTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePayload, id);
18945 row.Name = String.IsNullOrEmpty(name) ? Path.GetFileName(sourceFile) : name; 18892 row.Name = String.IsNullOrEmpty(name) ? Path.GetFileName(sourceFile) : name;
18946 row.SourceFile = sourceFile; 18893 row.SourceFile = sourceFile;
18947 row.DownloadUrl = downloadUrl; 18894 row.DownloadUrl = downloadUrl;
@@ -18988,22 +18935,22 @@ namespace WixToolset
18988 switch (attrib.Name.LocalName) 18935 switch (attrib.Name.LocalName)
18989 { 18936 {
18990 case "Id": 18937 case "Id":
18991 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 18938 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
18992 break; 18939 break;
18993 default: 18940 default:
18994 this.core.UnexpectedAttribute(node, attrib); 18941 this.Core.UnexpectedAttribute(node, attrib);
18995 break; 18942 break;
18996 } 18943 }
18997 } 18944 }
18998 else 18945 else
18999 { 18946 {
19000 this.core.ParseExtensionAttribute(node, attrib); 18947 this.Core.ParseExtensionAttribute(node, attrib);
19001 } 18948 }
19002 } 18949 }
19003 18950
19004 if (null == id) 18951 if (null == id)
19005 { 18952 {
19006 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 18953 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
19007 id = Identifier.Invalid; 18954 id = Identifier.Invalid;
19008 } 18955 }
19009 18956
@@ -19024,20 +18971,20 @@ namespace WixToolset
19024 previousType = ComplexReferenceChildType.PayloadGroup; 18971 previousType = ComplexReferenceChildType.PayloadGroup;
19025 break; 18972 break;
19026 default: 18973 default:
19027 this.core.UnexpectedElement(node, child); 18974 this.Core.UnexpectedElement(node, child);
19028 break; 18975 break;
19029 } 18976 }
19030 } 18977 }
19031 else 18978 else
19032 { 18979 {
19033 this.core.ParseExtensionElement(node, child); 18980 this.Core.ParseExtensionElement(node, child);
19034 } 18981 }
19035 } 18982 }
19036 18983
19037 18984
19038 if (!this.core.EncounteredError) 18985 if (!this.Core.EncounteredError)
19039 { 18986 {
19040 this.core.CreateRow(sourceLineNumbers, "WixBundlePayloadGroup", id); 18987 this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePayloadGroup, id);
19041 18988
19042 this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PayloadGroup, id.Id, ComplexReferenceChildType.Unknown, null); 18989 this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PayloadGroup, id.Id, ComplexReferenceChildType.Unknown, null);
19043 } 18990 }
@@ -19064,26 +19011,26 @@ namespace WixToolset
19064 switch (attrib.Name.LocalName) 19011 switch (attrib.Name.LocalName)
19065 { 19012 {
19066 case "Id": 19013 case "Id":
19067 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 19014 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
19068 this.core.CreateSimpleReference(sourceLineNumbers, "WixBundlePayloadGroup", id); 19015 this.Core.CreateSimpleReference(sourceLineNumbers, "WixBundlePayloadGroup", id);
19069 break; 19016 break;
19070 default: 19017 default:
19071 this.core.UnexpectedAttribute(node, attrib); 19018 this.Core.UnexpectedAttribute(node, attrib);
19072 break; 19019 break;
19073 } 19020 }
19074 } 19021 }
19075 else 19022 else
19076 { 19023 {
19077 this.core.ParseExtensionAttribute(node, attrib); 19024 this.Core.ParseExtensionAttribute(node, attrib);
19078 } 19025 }
19079 } 19026 }
19080 19027
19081 if (null == id) 19028 if (null == id)
19082 { 19029 {
19083 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 19030 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
19084 } 19031 }
19085 19032
19086 this.core.ParseForExtensionElements(node); 19033 this.Core.ParseForExtensionElements(node);
19087 19034
19088 this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PayloadGroup, id, previousType, previousId); 19035 this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PayloadGroup, id, previousType, previousId);
19089 19036
@@ -19107,7 +19054,7 @@ namespace WixToolset
19107 { 19054 {
19108 if (ComplexReferenceParentType.Unknown != parentType && null != parentId) 19055 if (ComplexReferenceParentType.Unknown != parentType && null != parentId)
19109 { 19056 {
19110 this.core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, type, id); 19057 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, type, id);
19111 } 19058 }
19112 19059
19113 if (ComplexReferenceChildType.Unknown != previousType && null != previousId) 19060 if (ComplexReferenceChildType.Unknown != previousType && null != previousId)
@@ -19124,8 +19071,8 @@ namespace WixToolset
19124 private void ParseExitCodeElement(XElement node, string packageId) 19071 private void ParseExitCodeElement(XElement node, string packageId)
19125 { 19072 {
19126 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 19073 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
19127 int value = CompilerConstants.IntegerNotSet; 19074 var value = CompilerConstants.IntegerNotSet;
19128 ExitCodeBehaviorType behavior = ExitCodeBehaviorType.NotSet; 19075 var behavior = ExitCodeBehaviorType.NotSet;
19129 19076
19130 foreach (XAttribute attrib in node.Attributes()) 19077 foreach (XAttribute attrib in node.Attributes())
19131 { 19078 {
@@ -19134,36 +19081,36 @@ namespace WixToolset
19134 switch (attrib.Name.LocalName) 19081 switch (attrib.Name.LocalName)
19135 { 19082 {
19136 case "Value": 19083 case "Value":
19137 value = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, int.MinValue + 2, int.MaxValue); 19084 value = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, int.MinValue + 2, int.MaxValue);
19138 break; 19085 break;
19139 case "Behavior": 19086 case "Behavior":
19140 string behaviorString = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19087 string behaviorString = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19141 if (!Enum.TryParse<ExitCodeBehaviorType>(behaviorString, true, out behavior)) 19088 if (!Enum.TryParse<ExitCodeBehaviorType>(behaviorString, true, out behavior))
19142 { 19089 {
19143 this.core.OnMessage(WixErrors.IllegalAttributeValueWithLegalList(sourceLineNumbers, node.Name.LocalName, "Behavior", behaviorString, "success, error, scheduleReboot, forceReboot")); 19090 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithLegalList(sourceLineNumbers, node.Name.LocalName, "Behavior", behaviorString, "success, error, scheduleReboot, forceReboot"));
19144 } 19091 }
19145 break; 19092 break;
19146 default: 19093 default:
19147 this.core.UnexpectedAttribute(node, attrib); 19094 this.Core.UnexpectedAttribute(node, attrib);
19148 break; 19095 break;
19149 } 19096 }
19150 } 19097 }
19151 else 19098 else
19152 { 19099 {
19153 this.core.ParseExtensionAttribute(node, attrib); 19100 this.Core.ParseExtensionAttribute(node, attrib);
19154 } 19101 }
19155 } 19102 }
19156 19103
19157 if (ExitCodeBehaviorType.NotSet == behavior) 19104 if (ExitCodeBehaviorType.NotSet == behavior)
19158 { 19105 {
19159 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Behavior")); 19106 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Behavior"));
19160 } 19107 }
19161 19108
19162 this.core.ParseForExtensionElements(node); 19109 this.Core.ParseForExtensionElements(node);
19163 19110
19164 if (!this.core.EncounteredError) 19111 if (!this.Core.EncounteredError)
19165 { 19112 {
19166 WixBundlePackageExitCodeRow row = (WixBundlePackageExitCodeRow)this.core.CreateRow(sourceLineNumbers, "WixBundlePackageExitCode"); 19113 var row = (WixBundlePackageExitCodeTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePackageExitCode);
19167 row.ChainPackageId = packageId; 19114 row.ChainPackageId = packageId;
19168 row.Code = value; 19115 row.Code = value;
19169 row.Behavior = behavior; 19116 row.Behavior = behavior;
@@ -19177,7 +19124,7 @@ namespace WixToolset
19177 private void ParseChainElement(XElement node) 19124 private void ParseChainElement(XElement node)
19178 { 19125 {
19179 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 19126 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
19180 WixChainAttributes attributes = WixChainAttributes.None; 19127 var attributes = WixChainAttributes.None;
19181 19128
19182 foreach (XAttribute attrib in node.Attributes()) 19129 foreach (XAttribute attrib in node.Attributes())
19183 { 19130 {
@@ -19186,31 +19133,31 @@ namespace WixToolset
19186 switch (attrib.Name.LocalName) 19133 switch (attrib.Name.LocalName)
19187 { 19134 {
19188 case "DisableRollback": 19135 case "DisableRollback":
19189 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 19136 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
19190 { 19137 {
19191 attributes |= WixChainAttributes.DisableRollback; 19138 attributes |= WixChainAttributes.DisableRollback;
19192 } 19139 }
19193 break; 19140 break;
19194 case "DisableSystemRestore": 19141 case "DisableSystemRestore":
19195 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 19142 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
19196 { 19143 {
19197 attributes |= WixChainAttributes.DisableSystemRestore; 19144 attributes |= WixChainAttributes.DisableSystemRestore;
19198 } 19145 }
19199 break; 19146 break;
19200 case "ParallelCache": 19147 case "ParallelCache":
19201 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 19148 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
19202 { 19149 {
19203 attributes |= WixChainAttributes.ParallelCache; 19150 attributes |= WixChainAttributes.ParallelCache;
19204 } 19151 }
19205 break; 19152 break;
19206 default: 19153 default:
19207 this.core.UnexpectedAttribute(node, attrib); 19154 this.Core.UnexpectedAttribute(node, attrib);
19208 break; 19155 break;
19209 } 19156 }
19210 } 19157 }
19211 else 19158 else
19212 { 19159 {
19213 this.core.ParseExtensionAttribute(node, attrib); 19160 this.Core.ParseExtensionAttribute(node, attrib);
19214 } 19161 }
19215 } 19162 }
19216 19163
@@ -19251,25 +19198,25 @@ namespace WixToolset
19251 previousType = ComplexReferenceChildType.PackageGroup; 19198 previousType = ComplexReferenceChildType.PackageGroup;
19252 break; 19199 break;
19253 default: 19200 default:
19254 this.core.UnexpectedElement(node, child); 19201 this.Core.UnexpectedElement(node, child);
19255 break; 19202 break;
19256 } 19203 }
19257 } 19204 }
19258 else 19205 else
19259 { 19206 {
19260 this.core.ParseExtensionElement(node, child); 19207 this.Core.ParseExtensionElement(node, child);
19261 } 19208 }
19262 } 19209 }
19263 19210
19264 19211
19265 if (null == previousId) 19212 if (null == previousId)
19266 { 19213 {
19267 this.core.OnMessage(WixErrors.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "MsiPackage", "ExePackage", "PackageGroupRef")); 19214 this.Core.OnMessage(WixErrors.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "MsiPackage", "ExePackage", "PackageGroupRef"));
19268 } 19215 }
19269 19216
19270 if (!this.core.EncounteredError) 19217 if (!this.Core.EncounteredError)
19271 { 19218 {
19272 WixChainRow row = (WixChainRow)this.core.CreateRow(sourceLineNumbers, "WixChain"); 19219 var row = (WixChainTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixChain);
19273 row.Attributes = attributes; 19220 row.Attributes = attributes;
19274 } 19221 }
19275 } 19222 }
@@ -19361,13 +19308,13 @@ namespace WixToolset
19361 switch (attrib.Name.LocalName) 19308 switch (attrib.Name.LocalName)
19362 { 19309 {
19363 case "Id": 19310 case "Id":
19364 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 19311 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
19365 break; 19312 break;
19366 case "Vital": 19313 case "Vital":
19367 vital = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 19314 vital = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
19368 break; 19315 break;
19369 case "Transaction": 19316 case "Transaction":
19370 transaction = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 19317 transaction = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
19371 break; 19318 break;
19372 default: 19319 default:
19373 allowed = false; 19320 allowed = false;
@@ -19376,7 +19323,7 @@ namespace WixToolset
19376 19323
19377 if (!allowed) 19324 if (!allowed)
19378 { 19325 {
19379 this.core.UnexpectedAttribute(node, attrib); 19326 this.Core.UnexpectedAttribute(node, attrib);
19380 } 19327 }
19381 } 19328 }
19382 else 19329 else
@@ -19390,17 +19337,17 @@ namespace WixToolset
19390 { 19337 {
19391 if (!String.IsNullOrEmpty(previousId)) 19338 if (!String.IsNullOrEmpty(previousId))
19392 { 19339 {
19393 id = this.core.CreateIdentifier("rba", previousId); 19340 id = this.Core.CreateIdentifier("rba", previousId);
19394 } 19341 }
19395 19342
19396 if (null == id) 19343 if (null == id)
19397 { 19344 {
19398 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 19345 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
19399 id = Identifier.Invalid; 19346 id = Identifier.Invalid;
19400 } 19347 }
19401 else if (!Common.IsIdentifier(id.Id)) 19348 else if (!Common.IsIdentifier(id.Id))
19402 { 19349 {
19403 this.core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id)); 19350 this.Core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id));
19404 } 19351 }
19405 } 19352 }
19406 19353
@@ -19409,12 +19356,12 @@ namespace WixToolset
19409 contextValues["RollbackBoundaryId"] = id.Id; 19356 contextValues["RollbackBoundaryId"] = id.Id;
19410 foreach (XAttribute attribute in extensionAttributes) 19357 foreach (XAttribute attribute in extensionAttributes)
19411 { 19358 {
19412 this.core.ParseExtensionAttribute(node, attribute, contextValues); 19359 this.Core.ParseExtensionAttribute(node, attribute, contextValues);
19413 } 19360 }
19414 19361
19415 this.core.ParseForExtensionElements(node); 19362 this.Core.ParseForExtensionElements(node);
19416 19363
19417 if (!this.core.EncounteredError) 19364 if (!this.Core.EncounteredError)
19418 { 19365 {
19419 this.CreateRollbackBoundary(sourceLineNumbers, id, vital, transaction, parentType, parentId, previousType, previousId); 19366 this.CreateRollbackBoundary(sourceLineNumbers, id, vital, transaction, parentType, parentId, previousType, previousId);
19420 } 19367 }
@@ -19487,112 +19434,112 @@ namespace WixToolset
19487 switch (attrib.Name.LocalName) 19434 switch (attrib.Name.LocalName)
19488 { 19435 {
19489 case "Id": 19436 case "Id":
19490 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 19437 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
19491 break; 19438 break;
19492 case "Name": 19439 case "Name":
19493 name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true); 19440 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true);
19494 if (!this.core.IsValidLongFilename(name, false, true)) 19441 if (!this.Core.IsValidLongFilename(name, false, true))
19495 { 19442 {
19496 this.core.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Name", name)); 19443 this.Core.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Name", name));
19497 } 19444 }
19498 break; 19445 break;
19499 case "SourceFile": 19446 case "SourceFile":
19500 sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19447 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19501 break; 19448 break;
19502 case "DownloadUrl": 19449 case "DownloadUrl":
19503 downloadUrl = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19450 downloadUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19504 break; 19451 break;
19505 case "After": 19452 case "After":
19506 after = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19453 after = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19507 break; 19454 break;
19508 case "InstallCondition": 19455 case "InstallCondition":
19509 installCondition = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19456 installCondition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19510 break; 19457 break;
19511 case "Cache": 19458 case "Cache":
19512 cache = this.core.GetAttributeYesNoAlwaysValue(sourceLineNumbers, attrib); 19459 cache = this.Core.GetAttributeYesNoAlwaysValue(sourceLineNumbers, attrib);
19513 break; 19460 break;
19514 case "CacheId": 19461 case "CacheId":
19515 cacheId = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19462 cacheId = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19516 break; 19463 break;
19517 case "Description": 19464 case "Description":
19518 description = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19465 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19519 break; 19466 break;
19520 case "DisplayName": 19467 case "DisplayName":
19521 displayName = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19468 displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19522 break; 19469 break;
19523 case "DisplayInternalUI": 19470 case "DisplayInternalUI":
19524 displayInternalUI = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 19471 displayInternalUI = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
19525 allowed = (packageType == WixBundlePackageType.Msi || packageType == WixBundlePackageType.Msp); 19472 allowed = (packageType == WixBundlePackageType.Msi || packageType == WixBundlePackageType.Msp);
19526 break; 19473 break;
19527 case "EnableFeatureSelection": 19474 case "EnableFeatureSelection":
19528 enableFeatureSelection = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 19475 enableFeatureSelection = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
19529 allowed = (packageType == WixBundlePackageType.Msi); 19476 allowed = (packageType == WixBundlePackageType.Msi);
19530 break; 19477 break;
19531 case "ForcePerMachine": 19478 case "ForcePerMachine":
19532 forcePerMachine = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 19479 forcePerMachine = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
19533 allowed = (packageType == WixBundlePackageType.Msi); 19480 allowed = (packageType == WixBundlePackageType.Msi);
19534 break; 19481 break;
19535 case "LogPathVariable": 19482 case "LogPathVariable":
19536 logPathVariable = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 19483 logPathVariable = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
19537 break; 19484 break;
19538 case "RollbackLogPathVariable": 19485 case "RollbackLogPathVariable":
19539 rollbackPathVariable = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 19486 rollbackPathVariable = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
19540 break; 19487 break;
19541 case "Permanent": 19488 case "Permanent":
19542 permanent = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 19489 permanent = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
19543 break; 19490 break;
19544 case "Visible": 19491 case "Visible":
19545 visible = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 19492 visible = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
19546 allowed = (packageType == WixBundlePackageType.Msi); 19493 allowed = (packageType == WixBundlePackageType.Msi);
19547 break; 19494 break;
19548 case "Vital": 19495 case "Vital":
19549 vital = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 19496 vital = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
19550 break; 19497 break;
19551 case "InstallCommand": 19498 case "InstallCommand":
19552 installCommand = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19499 installCommand = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19553 allowed = (packageType == WixBundlePackageType.Exe); 19500 allowed = (packageType == WixBundlePackageType.Exe);
19554 break; 19501 break;
19555 case "RepairCommand": 19502 case "RepairCommand":
19556 repairCommand = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 19503 repairCommand = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
19557 repairable = YesNoType.Yes; 19504 repairable = YesNoType.Yes;
19558 allowed = (packageType == WixBundlePackageType.Exe); 19505 allowed = (packageType == WixBundlePackageType.Exe);
19559 break; 19506 break;
19560 case "UninstallCommand": 19507 case "UninstallCommand":
19561 uninstallCommand = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19508 uninstallCommand = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19562 allowed = (packageType == WixBundlePackageType.Exe); 19509 allowed = (packageType == WixBundlePackageType.Exe);
19563 break; 19510 break;
19564 case "PerMachine": 19511 case "PerMachine":
19565 perMachine = this.core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); 19512 perMachine = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
19566 allowed = (packageType == WixBundlePackageType.Exe || packageType == WixBundlePackageType.Msp); 19513 allowed = (packageType == WixBundlePackageType.Exe || packageType == WixBundlePackageType.Msp);
19567 break; 19514 break;
19568 case "DetectCondition": 19515 case "DetectCondition":
19569 detectCondition = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19516 detectCondition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19570 allowed = (packageType == WixBundlePackageType.Exe || packageType == WixBundlePackageType.Msu); 19517 allowed = (packageType == WixBundlePackageType.Exe || packageType == WixBundlePackageType.Msu);
19571 break; 19518 break;
19572 case "Protocol": 19519 case "Protocol":
19573 protocol = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19520 protocol = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19574 allowed = (packageType == WixBundlePackageType.Exe); 19521 allowed = (packageType == WixBundlePackageType.Exe);
19575 break; 19522 break;
19576 case "InstallSize": 19523 case "InstallSize":
19577 installSize = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); 19524 installSize = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
19578 break; 19525 break;
19579 case "KB": 19526 case "KB":
19580 msuKB = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19527 msuKB = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19581 allowed = (packageType == WixBundlePackageType.Msu); 19528 allowed = (packageType == WixBundlePackageType.Msu);
19582 break; 19529 break;
19583 case "Compressed": 19530 case "Compressed":
19584 compressed = this.core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); 19531 compressed = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
19585 break; 19532 break;
19586 case "SuppressLooseFilePayloadGeneration": 19533 case "SuppressLooseFilePayloadGeneration":
19587 this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); 19534 this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
19588 suppressLooseFilePayloadGeneration = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 19535 suppressLooseFilePayloadGeneration = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
19589 allowed = (packageType == WixBundlePackageType.Msi); 19536 allowed = (packageType == WixBundlePackageType.Msi);
19590 break; 19537 break;
19591 case "EnableSignatureVerification": 19538 case "EnableSignatureVerification":
19592 enableSignatureVerification = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 19539 enableSignatureVerification = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
19593 break; 19540 break;
19594 case "Slipstream": 19541 case "Slipstream":
19595 slipstream = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 19542 slipstream = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
19596 allowed = (packageType == WixBundlePackageType.Msp); 19543 allowed = (packageType == WixBundlePackageType.Msp);
19597 break; 19544 break;
19598 default: 19545 default:
@@ -19602,7 +19549,7 @@ namespace WixToolset
19602 19549
19603 if (!allowed) 19550 if (!allowed)
19604 { 19551 {
19605 this.core.UnexpectedAttribute(node, attrib); 19552 this.Core.UnexpectedAttribute(node, attrib);
19606 } 19553 }
19607 } 19554 }
19608 else 19555 else
@@ -19619,13 +19566,13 @@ namespace WixToolset
19619 19566
19620 if (CompilerCore.WixNamespace == node.Name.Namespace && node.Name.LocalName != "ExePackage" && node.Name.LocalName != "MsuPackage") 19567 if (CompilerCore.WixNamespace == node.Name.Namespace && node.Name.LocalName != "ExePackage" && node.Name.LocalName != "MsuPackage")
19621 { 19568 {
19622 this.core.OnMessage(WixErrors.RemotePayloadUnsupported(childSourceLineNumbers)); 19569 this.Core.OnMessage(WixErrors.RemotePayloadUnsupported(childSourceLineNumbers));
19623 continue; 19570 continue;
19624 } 19571 }
19625 19572
19626 if (null != remotePayload) 19573 if (null != remotePayload)
19627 { 19574 {
19628 this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName)); 19575 this.Core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName));
19629 } 19576 }
19630 19577
19631 remotePayload = this.ParseRemotePayloadElement(child); 19578 remotePayload = this.ParseRemotePayloadElement(child);
@@ -19635,7 +19582,7 @@ namespace WixToolset
19635 { 19582 {
19636 if (String.IsNullOrEmpty(name)) 19583 if (String.IsNullOrEmpty(name))
19637 { 19584 {
19638 this.core.OnMessage(WixErrors.ExpectedAttributesWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", "SourceFile")); 19585 this.Core.OnMessage(WixErrors.ExpectedAttributesWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", "SourceFile"));
19639 } 19586 }
19640 else if (null == remotePayload) 19587 else if (null == remotePayload)
19641 { 19588 {
@@ -19648,13 +19595,13 @@ namespace WixToolset
19648 } 19595 }
19649 else if (null != remotePayload) 19596 else if (null != remotePayload)
19650 { 19597 {
19651 this.core.OnMessage(WixErrors.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name.LocalName, "RemotePayload", "SourceFile")); 19598 this.Core.OnMessage(WixErrors.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name.LocalName, "RemotePayload", "SourceFile"));
19652 } 19599 }
19653 else if (sourceFile.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) 19600 else if (sourceFile.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
19654 { 19601 {
19655 if (String.IsNullOrEmpty(name)) 19602 if (String.IsNullOrEmpty(name))
19656 { 19603 {
19657 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name", "SourceFile", sourceFile)); 19604 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name", "SourceFile", sourceFile));
19658 } 19605 }
19659 else 19606 else
19660 { 19607 {
@@ -19664,34 +19611,34 @@ namespace WixToolset
19664 19611
19665 if (null == downloadUrl && null != remotePayload) 19612 if (null == downloadUrl && null != remotePayload)
19666 { 19613 {
19667 this.core.OnMessage(WixErrors.ExpectedAttributeWithElement(sourceLineNumbers, node.Name.LocalName, "DownloadUrl", "RemotePayload")); 19614 this.Core.OnMessage(WixErrors.ExpectedAttributeWithElement(sourceLineNumbers, node.Name.LocalName, "DownloadUrl", "RemotePayload"));
19668 } 19615 }
19669 19616
19670 if (YesNoDefaultType.No != compressed && null != remotePayload) 19617 if (YesNoDefaultType.No != compressed && null != remotePayload)
19671 { 19618 {
19672 compressed = YesNoDefaultType.No; 19619 compressed = YesNoDefaultType.No;
19673 this.core.OnMessage(WixWarnings.RemotePayloadsMustNotAlsoBeCompressed(sourceLineNumbers, node.Name.LocalName)); 19620 this.Core.OnMessage(WixWarnings.RemotePayloadsMustNotAlsoBeCompressed(sourceLineNumbers, node.Name.LocalName));
19674 } 19621 }
19675 19622
19676 if (null == id) 19623 if (null == id)
19677 { 19624 {
19678 if (!String.IsNullOrEmpty(name)) 19625 if (!String.IsNullOrEmpty(name))
19679 { 19626 {
19680 id = this.core.CreateIdentifierFromFilename(Path.GetFileName(name)); 19627 id = this.Core.CreateIdentifierFromFilename(Path.GetFileName(name));
19681 } 19628 }
19682 else if (!String.IsNullOrEmpty(sourceFile)) 19629 else if (!String.IsNullOrEmpty(sourceFile))
19683 { 19630 {
19684 id = this.core.CreateIdentifierFromFilename(Path.GetFileName(sourceFile)); 19631 id = this.Core.CreateIdentifierFromFilename(Path.GetFileName(sourceFile));
19685 } 19632 }
19686 19633
19687 if (null == id) 19634 if (null == id)
19688 { 19635 {
19689 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 19636 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
19690 id = Identifier.Invalid; 19637 id = Identifier.Invalid;
19691 } 19638 }
19692 else if (!Common.IsIdentifier(id.Id)) 19639 else if (!Common.IsIdentifier(id.Id))
19693 { 19640 {
19694 this.core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id)); 19641 this.Core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id));
19695 } 19642 }
19696 } 19643 }
19697 19644
@@ -19707,7 +19654,7 @@ namespace WixToolset
19707 19654
19708 if (!String.IsNullOrEmpty(protocol) && !protocol.Equals("burn", StringComparison.Ordinal) && !protocol.Equals("netfx4", StringComparison.Ordinal) && !protocol.Equals("none", StringComparison.Ordinal)) 19655 if (!String.IsNullOrEmpty(protocol) && !protocol.Equals("burn", StringComparison.Ordinal) && !protocol.Equals("netfx4", StringComparison.Ordinal) && !protocol.Equals("none", StringComparison.Ordinal))
19709 { 19656 {
19710 this.core.OnMessage(WixErrors.IllegalAttributeValueWithLegalList(sourceLineNumbers, node.Name.LocalName, "Protocol", protocol, "none, burn, netfx4")); 19657 this.Core.OnMessage(WixErrors.IllegalAttributeValueWithLegalList(sourceLineNumbers, node.Name.LocalName, "Protocol", protocol, "none, burn, netfx4"));
19711 } 19658 }
19712 19659
19713 if (!String.IsNullOrEmpty(protocol) && protocol.Equals("netfx4", StringComparison.Ordinal)) 19660 if (!String.IsNullOrEmpty(protocol) && protocol.Equals("netfx4", StringComparison.Ordinal))
@@ -19716,17 +19663,17 @@ namespace WixToolset
19716 { 19663 {
19717 if (null == installCommand || -1 == installCommand.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase)) 19664 if (null == installCommand || -1 == installCommand.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase))
19718 { 19665 {
19719 this.core.OnMessage(WixWarnings.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "InstallCommand", installCommand, expectedArgument, "Protocol", "netfx4")); 19666 this.Core.OnMessage(WixWarnings.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "InstallCommand", installCommand, expectedArgument, "Protocol", "netfx4"));
19720 } 19667 }
19721 19668
19722 if (null == repairCommand || -1 == repairCommand.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase)) 19669 if (null == repairCommand || -1 == repairCommand.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase))
19723 { 19670 {
19724 this.core.OnMessage(WixWarnings.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "RepairCommand", repairCommand, expectedArgument, "Protocol", "netfx4")); 19671 this.Core.OnMessage(WixWarnings.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "RepairCommand", repairCommand, expectedArgument, "Protocol", "netfx4"));
19725 } 19672 }
19726 19673
19727 if (null == uninstallCommand || -1 == uninstallCommand.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase)) 19674 if (null == uninstallCommand || -1 == uninstallCommand.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase))
19728 { 19675 {
19729 this.core.OnMessage(WixWarnings.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "UninstallCommand", uninstallCommand, expectedArgument, "Protocol", "netfx4")); 19676 this.Core.OnMessage(WixWarnings.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "UninstallCommand", uninstallCommand, expectedArgument, "Protocol", "netfx4"));
19730 } 19677 }
19731 } 19678 }
19732 } 19679 }
@@ -19741,7 +19688,7 @@ namespace WixToolset
19741 Dictionary<string, string> contextValues = new Dictionary<string, string>() { { "PackageId", id.Id } }; 19688 Dictionary<string, string> contextValues = new Dictionary<string, string>() { { "PackageId", id.Id } };
19742 foreach (XAttribute attribute in extensionAttributes) 19689 foreach (XAttribute attribute in extensionAttributes)
19743 { 19690 {
19744 this.core.ParseExtensionAttribute(node, attribute, contextValues); 19691 this.Core.ParseExtensionAttribute(node, attribute, contextValues);
19745 } 19692 }
19746 19693
19747 foreach (XElement child in node.Elements()) 19694 foreach (XElement child in node.Elements())
@@ -19795,31 +19742,31 @@ namespace WixToolset
19795 19742
19796 if (!allowed) 19743 if (!allowed)
19797 { 19744 {
19798 this.core.UnexpectedElement(node, child); 19745 this.Core.UnexpectedElement(node, child);
19799 } 19746 }
19800 } 19747 }
19801 else 19748 else
19802 { 19749 {
19803 Dictionary<string, string> context = new Dictionary<string, string>() { { "Id", id.Id } }; 19750 Dictionary<string, string> context = new Dictionary<string, string>() { { "Id", id.Id } };
19804 this.core.ParseExtensionElement(node, child, context); 19751 this.Core.ParseExtensionElement(node, child, context);
19805 } 19752 }
19806 } 19753 }
19807 19754
19808 if (!this.core.EncounteredError) 19755 if (!this.Core.EncounteredError)
19809 { 19756 {
19810 // We create the package contents as a payload with this package as the parent 19757 // We create the package contents as a payload with this package as the parent
19811 this.CreatePayloadRow(sourceLineNumbers, id, name, sourceFile, downloadUrl, ComplexReferenceParentType.Package, id.Id, 19758 this.CreatePayloadRow(sourceLineNumbers, id, name, sourceFile, downloadUrl, ComplexReferenceParentType.Package, id.Id,
19812 ComplexReferenceChildType.Unknown, null, compressed, enableSignatureVerification, displayName, description, remotePayload); 19759 ComplexReferenceChildType.Unknown, null, compressed, enableSignatureVerification, displayName, description, remotePayload);
19813 19760
19814 WixChainItemRow chainItemRow = (WixChainItemRow)this.core.CreateRow(sourceLineNumbers, "WixChainItem", id); 19761 var chainItemRow = (WixChainItemTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixChainItem, id);
19815 19762
19816 WixBundlePackageAttributes attributes = 0; 19763 WixBundlePackageAttributes attributes = 0;
19817 attributes |= (YesNoType.Yes == permanent) ? WixBundlePackageAttributes.Permanent : 0; 19764 attributes |= (YesNoType.Yes == permanent) ? WixBundlePackageAttributes.Permanent : 0;
19818 attributes |= (YesNoType.Yes == visible) ? WixBundlePackageAttributes.Visible : 0; 19765 attributes |= (YesNoType.Yes == visible) ? WixBundlePackageAttributes.Visible : 0;
19819 19766
19820 WixBundlePackageRow chainPackageRow = (WixBundlePackageRow)this.core.CreateRow(sourceLineNumbers, "WixBundlePackage", id); 19767 var chainPackageRow = (WixBundlePackageTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePackage, id);
19821 chainPackageRow.Type = packageType; 19768 chainPackageRow.Type = packageType;
19822 chainPackageRow.PackagePayload = id.Id; 19769 chainPackageRow.Payload_ = id.Id;
19823 chainPackageRow.Attributes = attributes; 19770 chainPackageRow.Attributes = attributes;
19824 19771
19825 chainPackageRow.InstallCondition = installCondition; 19772 chainPackageRow.InstallCondition = installCondition;
@@ -19833,7 +19780,7 @@ namespace WixToolset
19833 19780
19834 if (YesNoType.NotSet != vital) 19781 if (YesNoType.NotSet != vital)
19835 { 19782 {
19836 chainPackageRow.Vital = vital; 19783 chainPackageRow.Vital = (vital == YesNoType.Yes);
19837 } 19784 }
19838 19785
19839 if (YesNoDefaultType.NotSet != perMachine) 19786 if (YesNoDefaultType.NotSet != perMachine)
@@ -19855,7 +19802,7 @@ namespace WixToolset
19855 WixBundleExePackageAttributes exeAttributes = 0; 19802 WixBundleExePackageAttributes exeAttributes = 0;
19856 exeAttributes |= (YesNoType.Yes == repairable) ? WixBundleExePackageAttributes.Repairable : 0; 19803 exeAttributes |= (YesNoType.Yes == repairable) ? WixBundleExePackageAttributes.Repairable : 0;
19857 19804
19858 WixBundleExePackageRow exeRow = (WixBundleExePackageRow)this.core.CreateRow(sourceLineNumbers, "WixBundleExePackage", id); 19805 var exeRow = (WixBundleExePackageTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleExePackage, id);
19859 exeRow.Attributes = exeAttributes; 19806 exeRow.Attributes = exeAttributes;
19860 exeRow.DetectCondition = detectCondition; 19807 exeRow.DetectCondition = detectCondition;
19861 exeRow.InstallCommand = installCommand; 19808 exeRow.InstallCommand = installCommand;
@@ -19871,7 +19818,7 @@ namespace WixToolset
19871 msiAttributes |= (YesNoType.Yes == forcePerMachine) ? WixBundleMsiPackageAttributes.ForcePerMachine : 0; 19818 msiAttributes |= (YesNoType.Yes == forcePerMachine) ? WixBundleMsiPackageAttributes.ForcePerMachine : 0;
19872 msiAttributes |= (YesNoType.Yes == suppressLooseFilePayloadGeneration) ? WixBundleMsiPackageAttributes.SuppressLooseFilePayloadGeneration : 0; 19819 msiAttributes |= (YesNoType.Yes == suppressLooseFilePayloadGeneration) ? WixBundleMsiPackageAttributes.SuppressLooseFilePayloadGeneration : 0;
19873 19820
19874 WixBundleMsiPackageRow msiRow = (WixBundleMsiPackageRow)this.core.CreateRow(sourceLineNumbers, "WixBundleMsiPackage", id); 19821 var msiRow = (WixBundleMsiPackageTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleMsiPackage, id);
19875 msiRow.Attributes = msiAttributes; 19822 msiRow.Attributes = msiAttributes;
19876 break; 19823 break;
19877 19824
@@ -19880,12 +19827,12 @@ namespace WixToolset
19880 mspAttributes |= (YesNoType.Yes == displayInternalUI) ? WixBundleMspPackageAttributes.DisplayInternalUI : 0; 19827 mspAttributes |= (YesNoType.Yes == displayInternalUI) ? WixBundleMspPackageAttributes.DisplayInternalUI : 0;
19881 mspAttributes |= (YesNoType.Yes == slipstream) ? WixBundleMspPackageAttributes.Slipstream : 0; 19828 mspAttributes |= (YesNoType.Yes == slipstream) ? WixBundleMspPackageAttributes.Slipstream : 0;
19882 19829
19883 WixBundleMspPackageRow mspRow = (WixBundleMspPackageRow)this.core.CreateRow(sourceLineNumbers, "WixBundleMspPackage", id); 19830 var mspRow = (WixBundleMspPackageTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleMspPackage, id);
19884 mspRow.Attributes = mspAttributes; 19831 mspRow.Attributes = mspAttributes;
19885 break; 19832 break;
19886 19833
19887 case WixBundlePackageType.Msu: 19834 case WixBundlePackageType.Msu:
19888 WixBundleMsuPackageRow msuRow = (WixBundleMsuPackageRow)this.core.CreateRow(sourceLineNumbers, "WixBundleMsuPackage", id); 19835 var msuRow = (WixBundleMsuPackageTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleMsuPackage, id);
19889 msuRow.DetectCondition = detectCondition; 19836 msuRow.DetectCondition = detectCondition;
19890 msuRow.MsuKB = msuKB; 19837 msuRow.MsuKB = msuKB;
19891 break; 19838 break;
@@ -19916,39 +19863,39 @@ namespace WixToolset
19916 switch (attrib.Name.LocalName) 19863 switch (attrib.Name.LocalName)
19917 { 19864 {
19918 case "InstallArgument": 19865 case "InstallArgument":
19919 installArgument = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19866 installArgument = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19920 break; 19867 break;
19921 case "UninstallArgument": 19868 case "UninstallArgument":
19922 uninstallArgument = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19869 uninstallArgument = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19923 break; 19870 break;
19924 case "RepairArgument": 19871 case "RepairArgument":
19925 repairArgument = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19872 repairArgument = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19926 break; 19873 break;
19927 case "Condition": 19874 case "Condition":
19928 condition = this.core.GetAttributeValue(sourceLineNumbers, attrib); 19875 condition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
19929 break; 19876 break;
19930 default: 19877 default:
19931 this.core.UnexpectedAttribute(node, attrib); 19878 this.Core.UnexpectedAttribute(node, attrib);
19932 break; 19879 break;
19933 } 19880 }
19934 } 19881 }
19935 else 19882 else
19936 { 19883 {
19937 this.core.ParseExtensionAttribute(node, attrib); 19884 this.Core.ParseExtensionAttribute(node, attrib);
19938 } 19885 }
19939 } 19886 }
19940 19887
19941 if (String.IsNullOrEmpty(condition)) 19888 if (String.IsNullOrEmpty(condition))
19942 { 19889 {
19943 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Condition")); 19890 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Condition"));
19944 } 19891 }
19945 19892
19946 this.core.ParseForExtensionElements(node); 19893 this.Core.ParseForExtensionElements(node);
19947 19894
19948 if (!this.core.EncounteredError) 19895 if (!this.Core.EncounteredError)
19949 { 19896 {
19950 WixBundlePackageCommandLineRow row = (WixBundlePackageCommandLineRow)this.core.CreateRow(sourceLineNumbers, "WixBundlePackageCommandLine"); 19897 var row = (WixBundlePackageCommandLineTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePackageCommandLine);
19951 row.ChainPackageId = packageId; 19898 row.WixBundlePackage_ = packageId;
19952 row.InstallArgument = installArgument; 19899 row.InstallArgument = installArgument;
19953 row.UninstallArgument = uninstallArgument; 19900 row.UninstallArgument = uninstallArgument;
19954 row.RepairArgument = repairArgument; 19901 row.RepairArgument = repairArgument;
@@ -19972,22 +19919,22 @@ namespace WixToolset
19972 switch (attrib.Name.LocalName) 19919 switch (attrib.Name.LocalName)
19973 { 19920 {
19974 case "Id": 19921 case "Id":
19975 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 19922 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
19976 break; 19923 break;
19977 default: 19924 default:
19978 this.core.UnexpectedAttribute(node, attrib); 19925 this.Core.UnexpectedAttribute(node, attrib);
19979 break; 19926 break;
19980 } 19927 }
19981 } 19928 }
19982 else 19929 else
19983 { 19930 {
19984 this.core.ParseExtensionAttribute(node, attrib); 19931 this.Core.ParseExtensionAttribute(node, attrib);
19985 } 19932 }
19986 } 19933 }
19987 19934
19988 if (null == id) 19935 if (null == id)
19989 { 19936 {
19990 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 19937 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
19991 id = Identifier.Invalid; 19938 id = Identifier.Invalid;
19992 } 19939 }
19993 19940
@@ -20024,20 +19971,20 @@ namespace WixToolset
20024 previousType = ComplexReferenceChildType.PackageGroup; 19971 previousType = ComplexReferenceChildType.PackageGroup;
20025 break; 19972 break;
20026 default: 19973 default:
20027 this.core.UnexpectedElement(node, child); 19974 this.Core.UnexpectedElement(node, child);
20028 break; 19975 break;
20029 } 19976 }
20030 } 19977 }
20031 else 19978 else
20032 { 19979 {
20033 this.core.ParseExtensionElement(node, child); 19980 this.Core.ParseExtensionElement(node, child);
20034 } 19981 }
20035 } 19982 }
20036 19983
20037 19984
20038 if (!this.core.EncounteredError) 19985 if (!this.Core.EncounteredError)
20039 { 19986 {
20040 this.core.CreateRow(sourceLineNumbers, "WixBundlePackageGroup", id); 19987 this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePackageGroup, id);
20041 } 19988 }
20042 } 19989 }
20043 19990
@@ -20078,39 +20025,39 @@ namespace WixToolset
20078 switch (attrib.Name.LocalName) 20025 switch (attrib.Name.LocalName)
20079 { 20026 {
20080 case "Id": 20027 case "Id":
20081 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 20028 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
20082 this.core.CreateSimpleReference(sourceLineNumbers, "WixBundlePackageGroup", id); 20029 this.Core.CreateSimpleReference(sourceLineNumbers, "WixBundlePackageGroup", id);
20083 break; 20030 break;
20084 case "After": 20031 case "After":
20085 after = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 20032 after = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
20086 break; 20033 break;
20087 default: 20034 default:
20088 this.core.UnexpectedAttribute(node, attrib); 20035 this.Core.UnexpectedAttribute(node, attrib);
20089 break; 20036 break;
20090 } 20037 }
20091 } 20038 }
20092 else 20039 else
20093 { 20040 {
20094 this.core.ParseExtensionAttribute(node, attrib); 20041 this.Core.ParseExtensionAttribute(node, attrib);
20095 20042
20096 } 20043 }
20097 } 20044 }
20098 20045
20099 if (null == id) 20046 if (null == id)
20100 { 20047 {
20101 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 20048 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
20102 } 20049 }
20103 20050
20104 if (null != after && ComplexReferenceParentType.Container == parentType) 20051 if (null != after && ComplexReferenceParentType.Container == parentType)
20105 { 20052 {
20106 this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "After", parentId)); 20053 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "After", parentId));
20107 } 20054 }
20108 20055
20109 this.core.ParseForExtensionElements(node); 20056 this.Core.ParseForExtensionElements(node);
20110 20057
20111 if (ComplexReferenceParentType.Container == parentType) 20058 if (ComplexReferenceParentType.Container == parentType)
20112 { 20059 {
20113 this.core.CreateWixGroupRow(sourceLineNumbers, ComplexReferenceParentType.Container, parentId, ComplexReferenceChildType.PackageGroup, id); 20060 this.Core.CreateWixGroupRow(sourceLineNumbers, ComplexReferenceParentType.Container, parentId, ComplexReferenceChildType.PackageGroup, id);
20114 } 20061 }
20115 else 20062 else
20116 { 20063 {
@@ -20132,17 +20079,17 @@ namespace WixToolset
20132 /// <param name="previousId">Identifier of previous item, if any.</param> 20079 /// <param name="previousId">Identifier of previous item, if any.</param>
20133 private void CreateRollbackBoundary(SourceLineNumber sourceLineNumbers, Identifier id, YesNoType vital, YesNoType transaction, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId) 20080 private void CreateRollbackBoundary(SourceLineNumber sourceLineNumbers, Identifier id, YesNoType vital, YesNoType transaction, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId)
20134 { 20081 {
20135 WixChainItemRow row = (WixChainItemRow)this.core.CreateRow(sourceLineNumbers, "WixChainItem", id); 20082 var row = (WixChainItemTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixChainItem, id);
20136 20083
20137 WixBundleRollbackBoundaryRow rollbackBoundary = (WixBundleRollbackBoundaryRow)this.core.CreateRow(sourceLineNumbers, "WixBundleRollbackBoundary", id); 20084 var rollbackBoundary = (WixBundleRollbackBoundaryTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleRollbackBoundary, id);
20138 20085
20139 if (YesNoType.NotSet != vital) 20086 if (YesNoType.NotSet != vital)
20140 { 20087 {
20141 rollbackBoundary.Vital = vital; 20088 rollbackBoundary.Vital = (vital == YesNoType.Yes);
20142 } 20089 }
20143 if (YesNoType.NotSet != transaction) 20090 if (YesNoType.NotSet != transaction)
20144 { 20091 {
20145 rollbackBoundary.Transaction = transaction; 20092 rollbackBoundary.Transaction = (transaction == YesNoType.Yes);
20146 } 20093 }
20147 20094
20148 this.CreateChainPackageMetaRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Package, id.Id, previousType, previousId, null); 20095 this.CreateChainPackageMetaRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Package, id.Id, previousType, previousId, null);
@@ -20181,13 +20128,13 @@ namespace WixToolset
20181 ComplexReferenceChildType itemType, string itemId, 20128 ComplexReferenceChildType itemType, string itemId,
20182 ComplexReferenceChildType dependsOnType, string dependsOnId) 20129 ComplexReferenceChildType dependsOnType, string dependsOnId)
20183 { 20130 {
20184 if (!this.core.EncounteredError) 20131 if (!this.Core.EncounteredError)
20185 { 20132 {
20186 Row row = this.core.CreateRow(sourceLineNumbers, "WixOrdering"); 20133 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixOrdering);
20187 row[0] = itemType.ToString(); 20134 row.Set(0, itemType.ToString());
20188 row[1] = itemId; 20135 row.Set(1, itemId);
20189 row[2] = dependsOnType.ToString(); 20136 row.Set(2, dependsOnType.ToString());
20190 row[3] = dependsOnId; 20137 row.Set(3, dependsOnId);
20191 } 20138 }
20192 } 20139 }
20193 20140
@@ -20210,41 +20157,41 @@ namespace WixToolset
20210 switch (attrib.Name.LocalName) 20157 switch (attrib.Name.LocalName)
20211 { 20158 {
20212 case "Name": 20159 case "Name":
20213 name = this.core.GetAttributeMsiPropertyNameValue(sourceLineNumbers, attrib); 20160 name = this.Core.GetAttributeMsiPropertyNameValue(sourceLineNumbers, attrib);
20214 break; 20161 break;
20215 case "Value": 20162 case "Value":
20216 value = this.core.GetAttributeValue(sourceLineNumbers, attrib); 20163 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
20217 break; 20164 break;
20218 case "Condition": 20165 case "Condition":
20219 condition = this.core.GetAttributeValue(sourceLineNumbers, attrib); 20166 condition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
20220 break; 20167 break;
20221 default: 20168 default:
20222 this.core.UnexpectedAttribute(node, attrib); 20169 this.Core.UnexpectedAttribute(node, attrib);
20223 break; 20170 break;
20224 } 20171 }
20225 } 20172 }
20226 else 20173 else
20227 { 20174 {
20228 this.core.ParseExtensionAttribute(node, attrib); 20175 this.Core.ParseExtensionAttribute(node, attrib);
20229 } 20176 }
20230 } 20177 }
20231 20178
20232 if (null == name) 20179 if (null == name)
20233 { 20180 {
20234 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 20181 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
20235 } 20182 }
20236 20183
20237 if (null == value) 20184 if (null == value)
20238 { 20185 {
20239 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 20186 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
20240 } 20187 }
20241 20188
20242 this.core.ParseForExtensionElements(node); 20189 this.Core.ParseForExtensionElements(node);
20243 20190
20244 if (!this.core.EncounteredError) 20191 if (!this.Core.EncounteredError)
20245 { 20192 {
20246 WixBundleMsiPropertyRow row = (WixBundleMsiPropertyRow)this.core.CreateRow(sourceLineNumbers, "WixBundleMsiProperty"); 20193 var row = (WixBundleMsiPropertyTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleMsiProperty);
20247 row.ChainPackageId = packageId; 20194 row.WixBundlePackage_ = packageId;
20248 row.Name = name; 20195 row.Name = name;
20249 row.Value = value; 20196 row.Value = value;
20250 20197
@@ -20272,32 +20219,32 @@ namespace WixToolset
20272 switch (attrib.Name.LocalName) 20219 switch (attrib.Name.LocalName)
20273 { 20220 {
20274 case "Id": 20221 case "Id":
20275 id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 20222 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
20276 this.core.CreateSimpleReference(sourceLineNumbers, "WixBundlePackage", id); 20223 this.Core.CreateSimpleReference(sourceLineNumbers, "WixBundlePackage", id);
20277 break; 20224 break;
20278 default: 20225 default:
20279 this.core.UnexpectedAttribute(node, attrib); 20226 this.Core.UnexpectedAttribute(node, attrib);
20280 break; 20227 break;
20281 } 20228 }
20282 } 20229 }
20283 else 20230 else
20284 { 20231 {
20285 this.core.ParseExtensionAttribute(node, attrib); 20232 this.Core.ParseExtensionAttribute(node, attrib);
20286 } 20233 }
20287 } 20234 }
20288 20235
20289 if (null == id) 20236 if (null == id)
20290 { 20237 {
20291 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 20238 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
20292 } 20239 }
20293 20240
20294 this.core.ParseForExtensionElements(node); 20241 this.Core.ParseForExtensionElements(node);
20295 20242
20296 if (!this.core.EncounteredError) 20243 if (!this.Core.EncounteredError)
20297 { 20244 {
20298 WixBundleSlipstreamMspRow row = (WixBundleSlipstreamMspRow)this.core.CreateRow(sourceLineNumbers, "WixBundleSlipstreamMsp"); 20245 var row = (WixBundleSlipstreamMspTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleSlipstreamMsp);
20299 row.ChainPackageId = packageId; 20246 row.WixBundlePackage_ = packageId;
20300 row.MspPackageId = id; 20247 row.WixBundlePackage_Msp = id;
20301 } 20248 }
20302 } 20249 }
20303 20250
@@ -20319,25 +20266,25 @@ namespace WixToolset
20319 switch (attrib.Name.LocalName) 20266 switch (attrib.Name.LocalName)
20320 { 20267 {
20321 case "Id": 20268 case "Id":
20322 id = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 20269 id = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
20323 break; 20270 break;
20324 case "Action": 20271 case "Action":
20325 action = this.core.GetAttributeValue(sourceLineNumbers, attrib); 20272 action = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
20326 break; 20273 break;
20327 default: 20274 default:
20328 this.core.UnexpectedAttribute(node, attrib); 20275 this.Core.UnexpectedAttribute(node, attrib);
20329 break; 20276 break;
20330 } 20277 }
20331 } 20278 }
20332 else 20279 else
20333 { 20280 {
20334 this.core.ParseExtensionAttribute(node, attrib); 20281 this.Core.ParseExtensionAttribute(node, attrib);
20335 } 20282 }
20336 } 20283 }
20337 20284
20338 if (null == id) 20285 if (null == id)
20339 { 20286 {
20340 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 20287 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
20341 } 20288 }
20342 20289
20343 if (!String.IsNullOrEmpty(action)) 20290 if (!String.IsNullOrEmpty(action))
@@ -20354,18 +20301,18 @@ namespace WixToolset
20354 case Wix.RelatedBundle.ActionType.Patch: 20301 case Wix.RelatedBundle.ActionType.Patch:
20355 break; 20302 break;
20356 default: 20303 default:
20357 this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Action", action, "Detect", "Upgrade", "Addon", "Patch")); 20304 this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Action", action, "Detect", "Upgrade", "Addon", "Patch"));
20358 break; 20305 break;
20359 } 20306 }
20360 } 20307 }
20361 20308
20362 this.core.ParseForExtensionElements(node); 20309 this.Core.ParseForExtensionElements(node);
20363 20310
20364 if (!this.core.EncounteredError) 20311 if (!this.Core.EncounteredError)
20365 { 20312 {
20366 Row row = this.core.CreateRow(sourceLineNumbers, "WixRelatedBundle"); 20313 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixRelatedBundle);
20367 row[0] = id; 20314 row.Set(0, id);
20368 row[1] = (int)actionType; 20315 row.Set(1, (int)actionType);
20369 } 20316 }
20370 } 20317 }
20371 20318
@@ -20385,30 +20332,30 @@ namespace WixToolset
20385 switch (attrib.Name.LocalName) 20332 switch (attrib.Name.LocalName)
20386 { 20333 {
20387 case "Location": 20334 case "Location":
20388 location = this.core.GetAttributeValue(sourceLineNumbers, attrib); 20335 location = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
20389 break; 20336 break;
20390 default: 20337 default:
20391 this.core.UnexpectedAttribute(node, attrib); 20338 this.Core.UnexpectedAttribute(node, attrib);
20392 break; 20339 break;
20393 } 20340 }
20394 } 20341 }
20395 else 20342 else
20396 { 20343 {
20397 this.core.ParseExtensionAttribute(node, attrib); 20344 this.Core.ParseExtensionAttribute(node, attrib);
20398 } 20345 }
20399 } 20346 }
20400 20347
20401 if (null == location) 20348 if (null == location)
20402 { 20349 {
20403 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Location")); 20350 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Location"));
20404 } 20351 }
20405 20352
20406 this.core.ParseForExtensionElements(node); 20353 this.Core.ParseForExtensionElements(node);
20407 20354
20408 if (!this.core.EncounteredError) 20355 if (!this.Core.EncounteredError)
20409 { 20356 {
20410 Row row = this.core.CreateRow(sourceLineNumbers, "WixBundleUpdate"); 20357 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleUpdate);
20411 row[0] = location; 20358 row.Set(0, location);
20412 } 20359 }
20413 } 20360 }
20414 20361
@@ -20432,44 +20379,44 @@ namespace WixToolset
20432 switch (attrib.Name.LocalName) 20379 switch (attrib.Name.LocalName)
20433 { 20380 {
20434 case "Hidden": 20381 case "Hidden":
20435 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 20382 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
20436 { 20383 {
20437 hidden = true; 20384 hidden = true;
20438 } 20385 }
20439 break; 20386 break;
20440 case "Name": 20387 case "Name":
20441 name = this.core.GetAttributeBundleVariableValue(sourceLineNumbers, attrib); 20388 name = this.Core.GetAttributeBundleVariableValue(sourceLineNumbers, attrib);
20442 break; 20389 break;
20443 case "Persisted": 20390 case "Persisted":
20444 if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 20391 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
20445 { 20392 {
20446 persisted = true; 20393 persisted = true;
20447 } 20394 }
20448 break; 20395 break;
20449 case "Value": 20396 case "Value":
20450 value = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 20397 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
20451 break; 20398 break;
20452 case "Type": 20399 case "Type":
20453 type = this.core.GetAttributeValue(sourceLineNumbers, attrib); 20400 type = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
20454 break; 20401 break;
20455 default: 20402 default:
20456 this.core.UnexpectedAttribute(node, attrib); 20403 this.Core.UnexpectedAttribute(node, attrib);
20457 break; 20404 break;
20458 } 20405 }
20459 } 20406 }
20460 else 20407 else
20461 { 20408 {
20462 this.core.ParseExtensionAttribute(node, attrib); 20409 this.Core.ParseExtensionAttribute(node, attrib);
20463 } 20410 }
20464 } 20411 }
20465 20412
20466 if (null == name) 20413 if (null == name)
20467 { 20414 {
20468 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); 20415 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
20469 } 20416 }
20470 else if (name.StartsWith("Wix", StringComparison.OrdinalIgnoreCase)) 20417 else if (name.StartsWith("Wix", StringComparison.OrdinalIgnoreCase))
20471 { 20418 {
20472 this.core.OnMessage(WixErrors.ReservedNamespaceViolation(sourceLineNumbers, node.Name.LocalName, "Name", "Wix")); 20419 this.Core.OnMessage(WixErrors.ReservedNamespaceViolation(sourceLineNumbers, node.Name.LocalName, "Name", "Wix"));
20473 } 20420 }
20474 20421
20475 if (null == type && null != value) 20422 if (null == type && null != value)
@@ -20515,15 +20462,15 @@ namespace WixToolset
20515 20462
20516 if (null == value && null != type) 20463 if (null == value && null != type)
20517 { 20464 {
20518 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, "Variable", "Value", "Type")); 20465 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, "Variable", "Value", "Type"));
20519 } 20466 }
20520 20467
20521 this.core.ParseForExtensionElements(node); 20468 this.Core.ParseForExtensionElements(node);
20522 20469
20523 if (!this.core.EncounteredError) 20470 if (!this.Core.EncounteredError)
20524 { 20471 {
20525 WixBundleVariableRow row = (WixBundleVariableRow)this.core.CreateRow(sourceLineNumbers, "WixBundleVariable"); 20472 var row = (WixBundleVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleVariable);
20526 row.Id = name; 20473 row.WixBundleVariable = name;
20527 row.Value = value; 20474 row.Value = value;
20528 row.Type = type; 20475 row.Type = type;
20529 row.Hidden = hidden; 20476 row.Hidden = hidden;
@@ -20549,22 +20496,22 @@ namespace WixToolset
20549 switch (attrib.Name.LocalName) 20496 switch (attrib.Name.LocalName)
20550 { 20497 {
20551 case "RequiredVersion": 20498 case "RequiredVersion":
20552 requiredVersion = this.core.GetAttributeVersionValue(sourceLineNumbers, attrib); 20499 requiredVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
20553 break; 20500 break;
20554 default: 20501 default:
20555 this.core.UnexpectedAttribute(node, attrib); 20502 this.Core.UnexpectedAttribute(node, attrib);
20556 break; 20503 break;
20557 } 20504 }
20558 } 20505 }
20559 else 20506 else
20560 { 20507 {
20561 this.core.ParseExtensionAttribute(node, attrib); 20508 this.Core.ParseExtensionAttribute(node, attrib);
20562 } 20509 }
20563 } 20510 }
20564 20511
20565 if (null != requiredVersion) 20512 if (null != requiredVersion)
20566 { 20513 {
20567 this.core.VerifyRequiredVersion(sourceLineNumbers, requiredVersion); 20514 this.Core.VerifyRequiredVersion(sourceLineNumbers, requiredVersion);
20568 } 20515 }
20569 20516
20570 foreach (XElement child in node.Elements()) 20517 foreach (XElement child in node.Elements())
@@ -20592,13 +20539,13 @@ namespace WixToolset
20592 this.ParsePatchElement(child); 20539 this.ParsePatchElement(child);
20593 break; 20540 break;
20594 default: 20541 default:
20595 this.core.UnexpectedElement(node, child); 20542 this.Core.UnexpectedElement(node, child);
20596 break; 20543 break;
20597 } 20544 }
20598 } 20545 }
20599 else 20546 else
20600 { 20547 {
20601 this.core.ParseExtensionElement(node, child); 20548 this.Core.ParseExtensionElement(node, child);
20602 } 20549 }
20603 } 20550 }
20604 } 20551 }
@@ -20621,40 +20568,40 @@ namespace WixToolset
20621 switch (attrib.Name.LocalName) 20568 switch (attrib.Name.LocalName)
20622 { 20569 {
20623 case "Id": 20570 case "Id":
20624 id = this.core.GetAttributeIdentifier(sourceLineNumbers, attrib); 20571 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
20625 break; 20572 break;
20626 case "Overridable": 20573 case "Overridable":
20627 overridable = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)); 20574 overridable = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
20628 break; 20575 break;
20629 case "Value": 20576 case "Value":
20630 value = this.core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 20577 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
20631 break; 20578 break;
20632 default: 20579 default:
20633 this.core.UnexpectedAttribute(node, attrib); 20580 this.Core.UnexpectedAttribute(node, attrib);
20634 break; 20581 break;
20635 } 20582 }
20636 } 20583 }
20637 else 20584 else
20638 { 20585 {
20639 this.core.ParseExtensionAttribute(node, attrib); 20586 this.Core.ParseExtensionAttribute(node, attrib);
20640 } 20587 }
20641 } 20588 }
20642 20589
20643 if (null == id) 20590 if (null == id)
20644 { 20591 {
20645 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); 20592 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
20646 } 20593 }
20647 20594
20648 if (null == value) 20595 if (null == value)
20649 { 20596 {
20650 this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); 20597 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
20651 } 20598 }
20652 20599
20653 this.core.ParseForExtensionElements(node); 20600 this.Core.ParseForExtensionElements(node);
20654 20601
20655 if (!this.core.EncounteredError) 20602 if (!this.Core.EncounteredError)
20656 { 20603 {
20657 WixVariableRow wixVariableRow = (WixVariableRow)this.core.CreateRow(sourceLineNumbers, "WixVariable", id); 20604 var wixVariableRow = (WixVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixVariable, id);
20658 wixVariableRow.Value = value; 20605 wixVariableRow.Value = value;
20659 wixVariableRow.Overridable = overridable; 20606 wixVariableRow.Overridable = overridable;
20660 } 20607 }
diff --git a/src/WixToolset.Core/CompilerCore.cs b/src/WixToolset.Core/CompilerCore.cs
index 8f4703f7..46a2e435 100644
--- a/src/WixToolset.Core/CompilerCore.cs
+++ b/src/WixToolset.Core/CompilerCore.cs
@@ -15,7 +15,7 @@ namespace WixToolset
15 using System.Text.RegularExpressions; 15 using System.Text.RegularExpressions;
16 using System.Xml.Linq; 16 using System.Xml.Linq;
17 using WixToolset.Data; 17 using WixToolset.Data;
18 using WixToolset.Data.Rows; 18 using WixToolset.Data.Tuples;
19 using WixToolset.Extensibility; 19 using WixToolset.Extensibility;
20 using Wix = WixToolset.Data.Serialize; 20 using Wix = WixToolset.Data.Serialize;
21 21
@@ -40,7 +40,7 @@ namespace WixToolset
40 /// <summary> 40 /// <summary>
41 /// Core class for the compiler. 41 /// Core class for the compiler.
42 /// </summary> 42 /// </summary>
43 internal sealed class CompilerCore : ICompilerCore 43 internal sealed class CompilerCore //: ICompilerCore
44 { 44 {
45 internal static readonly XNamespace W3SchemaPrefix = "http://www.w3.org/"; 45 internal static readonly XNamespace W3SchemaPrefix = "http://www.w3.org/";
46 internal static readonly XNamespace WixNamespace = "http://wixtoolset.org/schemas/v4/wxs"; 46 internal static readonly XNamespace WixNamespace = "http://wixtoolset.org/schemas/v4/wxs";
@@ -140,10 +140,9 @@ namespace WixToolset
140 "REMOVE" 140 "REMOVE"
141 }); 141 });
142 142
143 private TableDefinitionCollection tableDefinitions;
144 private Dictionary<XNamespace, ICompilerExtension> extensions; 143 private Dictionary<XNamespace, ICompilerExtension> extensions;
144 private ITupleDefinitionCreator creator;
145 private Intermediate intermediate; 145 private Intermediate intermediate;
146 private bool showPedanticMessages;
147 146
148 private HashSet<string> activeSectionInlinedDirectoryIds; 147 private HashSet<string> activeSectionInlinedDirectoryIds;
149 private HashSet<string> activeSectionSimpleReferences; 148 private HashSet<string> activeSectionSimpleReferences;
@@ -152,12 +151,11 @@ namespace WixToolset
152 /// Constructor for all compiler core. 151 /// Constructor for all compiler core.
153 /// </summary> 152 /// </summary>
154 /// <param name="intermediate">The Intermediate object representing compiled source document.</param> 153 /// <param name="intermediate">The Intermediate object representing compiled source document.</param>
155 /// <param name="tableDefinitions">The loaded table definition collection.</param>
156 /// <param name="extensions">The WiX extensions collection.</param> 154 /// <param name="extensions">The WiX extensions collection.</param>
157 internal CompilerCore(Intermediate intermediate, TableDefinitionCollection tableDefinitions, Dictionary<XNamespace, ICompilerExtension> extensions) 155 internal CompilerCore(Intermediate intermediate, ITupleDefinitionCreator creator, Dictionary<XNamespace, ICompilerExtension> extensions)
158 { 156 {
159 this.tableDefinitions = tableDefinitions;
160 this.extensions = extensions; 157 this.extensions = extensions;
158 this.creator = creator;
161 this.intermediate = intermediate; 159 this.intermediate = intermediate;
162 } 160 }
163 161
@@ -165,7 +163,7 @@ namespace WixToolset
165 /// Gets the section the compiler is currently emitting symbols into. 163 /// Gets the section the compiler is currently emitting symbols into.
166 /// </summary> 164 /// </summary>
167 /// <value>The section the compiler is currently emitting symbols into.</value> 165 /// <value>The section the compiler is currently emitting symbols into.</value>
168 public Section ActiveSection { get; private set; } 166 public IntermediateSection ActiveSection { get; private set; }
169 167
170 /// <summary> 168 /// <summary>
171 /// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements. 169 /// Gets or sets the platform which the compiler will use when defaulting 64-bit attributes and elements.
@@ -177,29 +175,13 @@ namespace WixToolset
177 /// Gets whether the compiler core encountered an error while processing. 175 /// Gets whether the compiler core encountered an error while processing.
178 /// </summary> 176 /// </summary>
179 /// <value>Flag if core encountered an error during processing.</value> 177 /// <value>Flag if core encountered an error during processing.</value>
180 public bool EncounteredError 178 public bool EncounteredError => Messaging.Instance.EncounteredError;
181 {
182 get { return Messaging.Instance.EncounteredError; }
183 }
184 179
185 /// <summary> 180 /// <summary>
186 /// Gets or sets the option to show pedantic messages. 181 /// Gets or sets the option to show pedantic messages.
187 /// </summary> 182 /// </summary>
188 /// <value>The option to show pedantic messages.</value> 183 /// <value>The option to show pedantic messages.</value>
189 public bool ShowPedanticMessages 184 public bool ShowPedanticMessages { get; set; }
190 {
191 get { return this.showPedanticMessages; }
192 set { this.showPedanticMessages = value; }
193 }
194
195 /// <summary>
196 /// Gets the table definitions used by the compiler core.
197 /// </summary>
198 /// <value>Table definition collection.</value>
199 public TableDefinitionCollection TableDefinitions
200 {
201 get { return this.tableDefinitions; }
202 }
203 185
204 /// <summary> 186 /// <summary>
205 /// Convert a bit array into an int value. 187 /// Convert a bit array into an int value.
@@ -483,32 +465,39 @@ namespace WixToolset
483 /// Creates a row in the active section. 465 /// Creates a row in the active section.
484 /// </summary> 466 /// </summary>
485 /// <param name="sourceLineNumbers">Source and line number of current row.</param> 467 /// <param name="sourceLineNumbers">Source and line number of current row.</param>
486 /// <param name="tableName">Name of table to create row in.</param> 468 /// <param name="tupleType">Name of table to create row in.</param>
487 /// <returns>New row.</returns> 469 /// <returns>New row.</returns>
488 public Row CreateRow(SourceLineNumber sourceLineNumbers, string tableName, Identifier identifier = null) 470 public IntermediateTuple CreateRow(SourceLineNumber sourceLineNumbers, TupleDefinitionType tupleType, Identifier identifier = null)
489 { 471 {
490 return this.CreateRow(sourceLineNumbers, tableName, this.ActiveSection, identifier); 472 return this.CreateRow(sourceLineNumbers, tupleType, this.ActiveSection, identifier);
491 } 473 }
492 474
493 /// <summary> 475 /// <summary>
494 /// Creates a row in the active given <paramref name="section"/>. 476 /// Creates a row in the active given <paramref name="section"/>.
495 /// </summary> 477 /// </summary>
496 /// <param name="sourceLineNumbers">Source and line number of current row.</param> 478 /// <param name="sourceLineNumbers">Source and line number of current row.</param>
497 /// <param name="tableName">Name of table to create row in.</param> 479 /// <param name="tupleType">Name of table to create row in.</param>
498 /// <param name="section">The section to which the row is added. If null, the row is added to the active section.</param> 480 /// <param name="section">The section to which the row is added. If null, the row is added to the active section.</param>
499 /// <returns>New row.</returns> 481 /// <returns>New row.</returns>
500 internal Row CreateRow(SourceLineNumber sourceLineNumbers, string tableName, Section section, Identifier identifier = null) 482 internal IntermediateTuple CreateRow(SourceLineNumber sourceLineNumbers, TupleDefinitionType tupleType, IntermediateSection section, Identifier identifier = null)
501 { 483 {
502 TableDefinition tableDefinition = this.tableDefinitions[tableName]; 484 var tupleDefinition = TupleDefinitions.ByType(tupleType);
503 Table table = section.EnsureTable(tableDefinition); 485 var row = tupleDefinition.CreateTuple(sourceLineNumbers, identifier);
504 Row row = table.CreateRow(sourceLineNumbers);
505 486
506 if (null != identifier) 487 if (null != identifier)
507 { 488 {
508 row.Access = identifier.Access; 489 if (row.Definition.FieldDefinitions[0].Type == IntermediateFieldType.Number)
509 row[0] = identifier.Id; 490 {
491 row.Set(0, Convert.ToInt32(identifier.Id));
492 }
493 else
494 {
495 row.Set(0, identifier.Id);
496 }
510 } 497 }
511 498
499 section.Tuples.Add(row);
500
512 return row; 501 return row;
513 } 502 }
514 503
@@ -572,9 +561,9 @@ namespace WixToolset
572 /// <returns>New row.</returns> 561 /// <returns>New row.</returns>
573 public void CreatePatchFamilyChildReference(SourceLineNumber sourceLineNumbers, string tableName, params string[] primaryKeys) 562 public void CreatePatchFamilyChildReference(SourceLineNumber sourceLineNumbers, string tableName, params string[] primaryKeys)
574 { 563 {
575 Row patchReferenceRow = this.CreateRow(sourceLineNumbers, "WixPatchRef"); 564 var patchReferenceRow = this.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchRef);
576 patchReferenceRow[0] = tableName; 565 patchReferenceRow.Set(0, tableName);
577 patchReferenceRow[1] = String.Join("/", primaryKeys); 566 patchReferenceRow.Set(1, String.Join("/", primaryKeys));
578 } 567 }
579 568
580 /// <summary> 569 /// <summary>
@@ -615,12 +604,13 @@ namespace WixToolset
615 } 604 }
616 605
617 id = this.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), key.ToLowerInvariant(), (null != name ? name.ToLowerInvariant() : name)); 606 id = this.CreateIdentifier("reg", componentId, root.ToString(CultureInfo.InvariantCulture.NumberFormat), key.ToLowerInvariant(), (null != name ? name.ToLowerInvariant() : name));
618 Row row = this.CreateRow(sourceLineNumbers, "Registry", id); 607
619 row[1] = root; 608 var row = this.CreateRow(sourceLineNumbers, TupleDefinitionType.Registry, id);
620 row[2] = key; 609 row.Set(1, root);
621 row[3] = name; 610 row.Set(2, key);
622 row[4] = value; 611 row.Set(3, name);
623 row[5] = componentId; 612 row.Set(4, value);
613 row.Set(5, componentId);
624 } 614 }
625 615
626 return id; 616 return id;
@@ -656,8 +646,8 @@ namespace WixToolset
656 // If this simple reference hasn't been added to the active section already, add it. 646 // If this simple reference hasn't been added to the active section already, add it.
657 if (this.activeSectionSimpleReferences.Add(id)) 647 if (this.activeSectionSimpleReferences.Add(id))
658 { 648 {
659 WixSimpleReferenceRow wixSimpleReferenceRow = (WixSimpleReferenceRow)this.CreateRow(sourceLineNumbers, "WixSimpleReference"); 649 var wixSimpleReferenceRow = (WixSimpleReferenceTuple)this.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSimpleReference);
660 wixSimpleReferenceRow.TableName = tableName; 650 wixSimpleReferenceRow.Table = tableName;
661 wixSimpleReferenceRow.PrimaryKeys = joinedKeys; 651 wixSimpleReferenceRow.PrimaryKeys = joinedKeys;
662 } 652 }
663 } 653 }
@@ -685,11 +675,11 @@ namespace WixToolset
685 throw new ArgumentNullException("childId"); 675 throw new ArgumentNullException("childId");
686 } 676 }
687 677
688 WixGroupRow WixGroupRow = (WixGroupRow)this.CreateRow(sourceLineNumbers, "WixGroup"); 678 var row = (WixGroupTuple)this.CreateRow(sourceLineNumbers, TupleDefinitionType.WixGroup);
689 WixGroupRow.ParentId = parentId; 679 row.ParentId = parentId;
690 WixGroupRow.ParentType = parentType; 680 row.ParentType = parentType;
691 WixGroupRow.ChildId = childId; 681 row.ChildId = childId;
692 WixGroupRow.ChildType = childType; 682 row.ChildType = childType;
693 } 683 }
694 } 684 }
695 685
@@ -703,13 +693,13 @@ namespace WixToolset
703 { 693 {
704 if (!this.EncounteredError) 694 if (!this.EncounteredError)
705 { 695 {
706 Row row = this.CreateRow(sourceLineNumbers, "WixEnsureTable"); 696 var row = this.CreateRow(sourceLineNumbers, TupleDefinitionType.WixEnsureTable);
707 row[0] = tableName; 697 row.Set(0, tableName);
708 698
709 // We don't add custom table definitions to the tableDefinitions collection, 699 // We don't add custom table definitions to the tableDefinitions collection,
710 // so if it's not in there, it better be a custom table. If the Id is just wrong, 700 // so if it's not in there, it better be a custom table. If the Id is just wrong,
711 // instead of a custom table, we get an unresolved reference at link time. 701 // instead of a custom table, we get an unresolved reference at link time.
712 if (!this.tableDefinitions.Contains(tableName)) 702 if (!this.creator.TryGetTupleDefinitionByName(tableName, out var ignored))
713 { 703 {
714 this.CreateSimpleReference(sourceLineNumbers, "WixCustomTable", tableName); 704 this.CreateSimpleReference(sourceLineNumbers, "WixCustomTable", tableName);
715 } 705 }
@@ -1016,7 +1006,7 @@ namespace WixToolset
1016 1006
1017 string uppercaseGuid = guid.ToString().ToUpper(CultureInfo.InvariantCulture); 1007 string uppercaseGuid = guid.ToString().ToUpper(CultureInfo.InvariantCulture);
1018 1008
1019 if (this.showPedanticMessages) 1009 if (this.ShowPedanticMessages)
1020 { 1010 {
1021 if (uppercaseGuid != value) 1011 if (uppercaseGuid != value)
1022 { 1012 {
@@ -1505,8 +1495,7 @@ namespace WixToolset
1505 return; 1495 return;
1506 } 1496 }
1507 1497
1508 ICompilerExtension extension; 1498 if (this.TryFindExtension(attribute.Name.NamespaceName, out var extension))
1509 if (this.TryFindExtension(attribute.Name.NamespaceName, out extension))
1510 { 1499 {
1511 extension.ParseAttribute(element, attribute, context); 1500 extension.ParseAttribute(element, attribute, context);
1512 } 1501 }
@@ -1525,8 +1514,7 @@ namespace WixToolset
1525 /// <param name="context">Extra information about the context in which this element is being parsed.</param> 1514 /// <param name="context">Extra information about the context in which this element is being parsed.</param>
1526 public void ParseExtensionElement(XElement parentElement, XElement element, IDictionary<string, string> context = null) 1515 public void ParseExtensionElement(XElement parentElement, XElement element, IDictionary<string, string> context = null)
1527 { 1516 {
1528 ICompilerExtension extension; 1517 if (this.TryFindExtension(element.Name.Namespace, out var extension))
1529 if (this.TryFindExtension(element.Name.Namespace, out extension))
1530 { 1518 {
1531 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(parentElement); 1519 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(parentElement);
1532 extension.ParseElement(parentElement, element, context); 1520 extension.ParseElement(parentElement, element, context);
@@ -1651,9 +1639,9 @@ namespace WixToolset
1651 /// <param name="type">Type of section to create.</param> 1639 /// <param name="type">Type of section to create.</param>
1652 /// <param name="codepage">Codepage for the resulting database for this ection.</param> 1640 /// <param name="codepage">Codepage for the resulting database for this ection.</param>
1653 /// <returns>New section.</returns> 1641 /// <returns>New section.</returns>
1654 internal Section CreateActiveSection(string id, SectionType type, int codepage) 1642 internal IntermediateSection CreateActiveSection(string id, SectionType type, int codepage, string compilationId)
1655 { 1643 {
1656 this.ActiveSection = this.CreateSection(id, type, codepage); 1644 this.ActiveSection = this.CreateSection(id, type, codepage, compilationId);
1657 1645
1658 this.activeSectionInlinedDirectoryIds = new HashSet<string>(); 1646 this.activeSectionInlinedDirectoryIds = new HashSet<string>();
1659 this.activeSectionSimpleReferences = new HashSet<string>(); 1647 this.activeSectionSimpleReferences = new HashSet<string>();
@@ -1668,12 +1656,14 @@ namespace WixToolset
1668 /// <param name="type">Type of section to create.</param> 1656 /// <param name="type">Type of section to create.</param>
1669 /// <param name="codepage">Codepage for the resulting database for this ection.</param> 1657 /// <param name="codepage">Codepage for the resulting database for this ection.</param>
1670 /// <returns>New section.</returns> 1658 /// <returns>New section.</returns>
1671 internal Section CreateSection(string id, SectionType type, int codepage) 1659 internal IntermediateSection CreateSection(string id, SectionType type, int codepage, string compilationId)
1672 { 1660 {
1673 Section newSection = new Section(id, type, codepage); 1661 var section = new IntermediateSection(id, type, codepage);
1674 this.intermediate.AddSection(newSection); 1662 section.CompilationId = compilationId;
1663
1664 this.intermediate.Sections.Add(section);
1675 1665
1676 return newSection; 1666 return section;
1677 } 1667 }
1678 1668
1679 /// <summary> 1669 /// <summary>
@@ -1690,11 +1680,11 @@ namespace WixToolset
1690 { 1680 {
1691 if (!this.EncounteredError) 1681 if (!this.EncounteredError)
1692 { 1682 {
1693 WixComplexReferenceRow wixComplexReferenceRow = (WixComplexReferenceRow)this.CreateRow(sourceLineNumbers, "WixComplexReference"); 1683 var wixComplexReferenceRow = (WixComplexReferenceTuple)this.CreateRow(sourceLineNumbers, TupleDefinitionType.WixComplexReference);
1694 wixComplexReferenceRow.ParentId = parentId; 1684 wixComplexReferenceRow.Parent = parentId;
1695 wixComplexReferenceRow.ParentType = parentType; 1685 wixComplexReferenceRow.ParentType = parentType;
1696 wixComplexReferenceRow.ParentLanguage = parentLanguage; 1686 wixComplexReferenceRow.ParentLanguage = parentLanguage;
1697 wixComplexReferenceRow.ChildId = childId; 1687 wixComplexReferenceRow.Child = childId;
1698 wixComplexReferenceRow.ChildType = childType; 1688 wixComplexReferenceRow.ChildType = childType;
1699 wixComplexReferenceRow.IsPrimary = isPrimary; 1689 wixComplexReferenceRow.IsPrimary = isPrimary;
1700 } 1690 }
@@ -1775,9 +1765,9 @@ namespace WixToolset
1775 } 1765 }
1776 } 1766 }
1777 1767
1778 Row row = this.CreateRow(sourceLineNumbers, "Directory", id); 1768 var row = this.CreateRow(sourceLineNumbers, TupleDefinitionType.Directory, id);
1779 row[1] = parentId; 1769 row.Set(1, parentId);
1780 row[2] = defaultDir; 1770 row.Set(2, defaultDir);
1781 return id; 1771 return id;
1782 } 1772 }
1783 1773
diff --git a/src/WixToolset.Core/Inscriber.cs b/src/WixToolset.Core/Inscriber.cs
index f01e0629..81781ad4 100644
--- a/src/WixToolset.Core/Inscriber.cs
+++ b/src/WixToolset.Core/Inscriber.cs
@@ -10,14 +10,6 @@ namespace WixToolset
10 /// </summary> 10 /// </summary>
11 public sealed class Inscriber : IMessageHandler 11 public sealed class Inscriber : IMessageHandler
12 { 12 {
13 // private TempFileCollection tempFiles;
14 private TableDefinitionCollection tableDefinitions;
15
16 public Inscriber()
17 {
18 this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions());
19 }
20
21 /// <summary> 13 /// <summary>
22 /// Gets or sets the temp files collection. 14 /// Gets or sets the temp files collection.
23 /// </summary> 15 /// </summary>
diff --git a/src/WixToolset.Core/Librarian.cs b/src/WixToolset.Core/Librarian.cs
index 092d81dc..50357d8a 100644
--- a/src/WixToolset.Core/Librarian.cs
+++ b/src/WixToolset.Core/Librarian.cs
@@ -6,40 +6,50 @@ namespace WixToolset.Core
6 using System.Collections.Generic; 6 using System.Collections.Generic;
7 using System.Linq; 7 using System.Linq;
8 using WixToolset.Core.Bind; 8 using WixToolset.Core.Bind;
9 using WixToolset.Core.Link;
9 using WixToolset.Data; 10 using WixToolset.Data;
10 using WixToolset.Link; 11 using WixToolset.Extensibility;
11 12
12 /// <summary> 13 /// <summary>
13 /// Core librarian tool. 14 /// Core librarian tool.
14 /// </summary> 15 /// </summary>
15 public sealed class Librarian 16 public sealed class Librarian
16 { 17 {
17 public Librarian(LibraryContext context) 18 private ILibraryContext Context { get; set; }
18 {
19 this.Context = context;
20 }
21
22 private LibraryContext Context { get; }
23 19
24 /// <summary> 20 /// <summary>
25 /// Create a library by combining several intermediates (objects). 21 /// Create a library by combining several intermediates (objects).
26 /// </summary> 22 /// </summary>
27 /// <param name="sections">The sections to combine into a library.</param> 23 /// <param name="sections">The sections to combine into a library.</param>
28 /// <returns>Returns the new library.</returns> 24 /// <returns>Returns the new library.</returns>
29 public Library Combine() 25 public Intermediate Combine(ILibraryContext context)
30 { 26 {
27 this.Context = context ?? throw new ArgumentNullException(nameof(context));
28
29 if (String.IsNullOrEmpty(this.Context.LibraryId))
30 {
31 this.Context.LibraryId = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).TrimEnd('=').Replace('+', '.').Replace('/', '_');
32 }
33
31 foreach (var extension in this.Context.Extensions) 34 foreach (var extension in this.Context.Extensions)
32 { 35 {
33 extension.PreCombine(this.Context); 36 extension.PreCombine(this.Context);
34 } 37 }
35 38
39 var sections = this.Context.Intermediates.SelectMany(i => i.Sections).ToList();
40
36 var fileResolver = new FileResolver(this.Context.BindPaths, this.Context.Extensions); 41 var fileResolver = new FileResolver(this.Context.BindPaths, this.Context.Extensions);
37 42
43 var embedFilePaths = ResolveFilePathsToEmbed(sections, fileResolver);
44
38 var localizationsByCulture = CollateLocalizations(this.Context.Localizations); 45 var localizationsByCulture = CollateLocalizations(this.Context.Localizations);
39 46
40 var embedFilePaths = ResolveFilePathsToEmbed(this.Context.Sections, fileResolver); 47 foreach (var section in sections)
48 {
49 section.LibraryId = this.Context.LibraryId;
50 }
41 51
42 var library = new Library(this.Context.Sections, localizationsByCulture, embedFilePaths); 52 var library = new Intermediate(this.Context.LibraryId, sections, localizationsByCulture, embedFilePaths);
43 53
44 this.Validate(library); 54 this.Validate(library);
45 55
@@ -55,7 +65,7 @@ namespace WixToolset.Core
55 /// Validate that a library contains one entry section and no duplicate symbols. 65 /// Validate that a library contains one entry section and no duplicate symbols.
56 /// </summary> 66 /// </summary>
57 /// <param name="library">Library to validate.</param> 67 /// <param name="library">Library to validate.</param>
58 private Library Validate(Library library) 68 private Intermediate Validate(Intermediate library)
59 { 69 {
60 FindEntrySectionAndLoadSymbolsCommand find = new FindEntrySectionAndLoadSymbolsCommand(library.Sections); 70 FindEntrySectionAndLoadSymbolsCommand find = new FindEntrySectionAndLoadSymbolsCommand(library.Sections);
61 find.Execute(); 71 find.Execute();
@@ -92,39 +102,35 @@ namespace WixToolset.Core
92 return localizationsByCulture; 102 return localizationsByCulture;
93 } 103 }
94 104
95 private List<string> ResolveFilePathsToEmbed(IEnumerable<Section> sections, FileResolver fileResolver) 105 private List<string> ResolveFilePathsToEmbed(IEnumerable<IntermediateSection> sections, FileResolver fileResolver)
96 { 106 {
97 var embedFilePaths = new List<string>(); 107 var embedFilePaths = new List<string>();
98 108
99 // Resolve paths to files that are to be embedded in the library. 109 // Resolve paths to files that are to be embedded in the library.
100 if (this.Context.BindFiles) 110 if (this.Context.BindFiles)
101 { 111 {
102 foreach (Table table in sections.SelectMany(s => s.Tables)) 112 foreach (var tuple in sections.SelectMany(s => s.Tuples))
103 { 113 {
104 foreach (Row row in table.Rows) 114 foreach (var field in tuple.Fields.Where(f => f.Type == IntermediateFieldType.Path))
105 { 115 {
106 foreach (ObjectField objectField in row.Fields.OfType<ObjectField>()) 116 var pathField = field.AsPath();
117
118 if (pathField != null)
107 { 119 {
108 if (null != objectField.Data) 120 var resolvedPath = this.Context.WixVariableResolver.ResolveVariables(tuple.SourceLineNumbers, pathField.Path, false);
121
122 var file = fileResolver.Resolve(tuple.SourceLineNumbers, tuple.Definition.Name, resolvedPath);
123
124 if (!String.IsNullOrEmpty(file))
109 { 125 {
110 string resolvedPath = this.Context.WixVariableResolver.ResolveVariables(row.SourceLineNumbers, (string)objectField.Data, false); 126 // File was successfully resolved so track the embedded index as the embedded file index.
111 127 field.Set(new IntermediateFieldPathValue { EmbeddedFileIndex = embedFilePaths.Count });
112 string file = fileResolver.Resolve(row.SourceLineNumbers, table.Name, resolvedPath); 128
113 129 embedFilePaths.Add(file);
114 if (!String.IsNullOrEmpty(file))
115 {
116 // File was successfully resolved so track the embedded index as the embedded file index.
117 objectField.EmbeddedFileIndex = embedFilePaths.Count;
118 embedFilePaths.Add(file);
119 }
120 else
121 {
122 Messaging.Instance.OnMessage(WixDataErrors.FileNotFound(row.SourceLineNumbers, (string)objectField.Data, table.Name));
123 }
124 } 130 }
125 else // clear out embedded file id in case there was one there before. 131 else
126 { 132 {
127 objectField.EmbeddedFileIndex = null; 133 this.Context.Messaging.OnMessage(WixDataErrors.FileNotFound(tuple.SourceLineNumbers, pathField.Path, tuple.Definition.Name));
128 } 134 }
129 } 135 }
130 } 136 }
diff --git a/src/WixToolset.Core/LibraryContext.cs b/src/WixToolset.Core/LibraryContext.cs
index 36e38739..b3efbffa 100644
--- a/src/WixToolset.Core/LibraryContext.cs
+++ b/src/WixToolset.Core/LibraryContext.cs
@@ -2,21 +2,28 @@
2 2
3namespace WixToolset.Core 3namespace WixToolset.Core
4{ 4{
5 using System;
5 using System.Collections.Generic; 6 using System.Collections.Generic;
6 using WixToolset.Data; 7 using WixToolset.Data;
7 using WixToolset.Extensibility; 8 using WixToolset.Extensibility;
8 9
9 public class LibraryContext : ILibraryContext 10 public class LibraryContext : ILibraryContext
10 { 11 {
12 public IServiceProvider ServiceProvider { get; }
13
14 public Messaging Messaging { get; set; }
15
11 public bool BindFiles { get; set; } 16 public bool BindFiles { get; set; }
12 17
13 public IEnumerable<BindPath> BindPaths { get; set; } 18 public IEnumerable<BindPath> BindPaths { get; set; }
14 19
15 public IEnumerable<ILibrarianExtension> Extensions { get; set; } 20 public IEnumerable<ILibrarianExtension> Extensions { get; set; }
16 21
22 public string LibraryId { get; set; }
23
17 public IEnumerable<Localization> Localizations { get; set; } 24 public IEnumerable<Localization> Localizations { get; set; }
18 25
19 public IEnumerable<Section> Sections { get; set; } 26 public IEnumerable<Intermediate> Intermediates { get; set; }
20 27
21 public IBindVariableResolver WixVariableResolver { get; set; } 28 public IBindVariableResolver WixVariableResolver { get; set; }
22 } 29 }
diff --git a/src/WixToolset.Core/Link/ConnectToFeature.cs b/src/WixToolset.Core/Link/ConnectToFeature.cs
index 6e046b89..bc85426a 100644
--- a/src/WixToolset.Core/Link/ConnectToFeature.cs
+++ b/src/WixToolset.Core/Link/ConnectToFeature.cs
@@ -2,7 +2,7 @@
2 2
3namespace WixToolset.Link 3namespace WixToolset.Link
4{ 4{
5 using System.Collections.Specialized; 5 using System.Collections.Generic;
6 using WixToolset.Data; 6 using WixToolset.Data;
7 7
8 /// <summary> 8 /// <summary>
@@ -10,19 +10,12 @@ namespace WixToolset.Link
10 /// </summary> 10 /// </summary>
11 public sealed class ConnectToFeature 11 public sealed class ConnectToFeature
12 { 12 {
13 private Section section;
14 private string childId;
15
16 private string primaryFeature;
17 private bool explicitPrimaryFeature;
18 private StringCollection connectFeatures;
19
20 /// <summary> 13 /// <summary>
21 /// Creates a new connect to feature. 14 /// Creates a new connect to feature.
22 /// </summary> 15 /// </summary>
23 /// <param name="section">Section this connect belongs to.</param> 16 /// <param name="section">Section this connect belongs to.</param>
24 /// <param name="childId">Id of the child.</param> 17 /// <param name="childId">Id of the child.</param>
25 public ConnectToFeature(Section section, string childId) : 18 public ConnectToFeature(IntermediateSection section, string childId) :
26 this(section, childId, null, false) 19 this(section, childId, null, false)
27 { 20 {
28 } 21 }
@@ -34,62 +27,43 @@ namespace WixToolset.Link
34 /// <param name="childId">Id of the child.</param> 27 /// <param name="childId">Id of the child.</param>
35 /// <param name="primaryFeature">Sets the primary feature for the connection.</param> 28 /// <param name="primaryFeature">Sets the primary feature for the connection.</param>
36 /// <param name="explicitPrimaryFeature">Sets if this is explicit primary.</param> 29 /// <param name="explicitPrimaryFeature">Sets if this is explicit primary.</param>
37 public ConnectToFeature(Section section, string childId, string primaryFeature, bool explicitPrimaryFeature) 30 public ConnectToFeature(IntermediateSection section, string childId, string primaryFeature, bool explicitPrimaryFeature)
38 { 31 {
39 this.section = section; 32 this.Section = section;
40 this.childId = childId; 33 this.ChildId = childId;
41 34
42 this.primaryFeature = primaryFeature; 35 this.PrimaryFeature = primaryFeature;
43 this.explicitPrimaryFeature = explicitPrimaryFeature; 36 this.IsExplicitPrimaryFeature = explicitPrimaryFeature;
44
45 this.connectFeatures = new StringCollection();
46 } 37 }
47 38
48 /// <summary> 39 /// <summary>
49 /// Gets the section. 40 /// Gets the section.
50 /// </summary> 41 /// </summary>
51 /// <value>Section.</value> 42 /// <value>Section.</value>
52 public Section Section 43 public IntermediateSection Section { get; }
53 {
54 get { return this.section; }
55 }
56 44
57 /// <summary> 45 /// <summary>
58 /// Gets the child identifier. 46 /// Gets the child identifier.
59 /// </summary> 47 /// </summary>
60 /// <value>The child identifier.</value> 48 /// <value>The child identifier.</value>
61 public string ChildId 49 public string ChildId { get; }
62 {
63 get { return this.childId; }
64 }
65 50
66 /// <summary> 51 /// <summary>
67 /// Gets or sets if the flag for if the primary feature was set explicitly. 52 /// Gets or sets if the flag for if the primary feature was set explicitly.
68 /// </summary> 53 /// </summary>
69 /// <value>The flag for if the primary feature was set explicitly.</value> 54 /// <value>The flag for if the primary feature was set explicitly.</value>
70 public bool IsExplicitPrimaryFeature 55 public bool IsExplicitPrimaryFeature { get; set; }
71 {
72 get { return this.explicitPrimaryFeature; }
73 set { this.explicitPrimaryFeature = value; }
74 }
75 56
76 /// <summary> 57 /// <summary>
77 /// Gets or sets the primary feature. 58 /// Gets or sets the primary feature.
78 /// </summary> 59 /// </summary>
79 /// <value>The primary feature.</value> 60 /// <value>The primary feature.</value>
80 public string PrimaryFeature 61 public string PrimaryFeature { get; set; }
81 {
82 get { return this.primaryFeature; }
83 set { this.primaryFeature = value; }
84 }
85 62
86 /// <summary> 63 /// <summary>
87 /// Gets the features connected to. 64 /// Gets the features connected to.
88 /// </summary> 65 /// </summary>
89 /// <value>Features connected to.</value> 66 /// <value>Features connected to.</value>
90 public StringCollection ConnectFeatures 67 public List<string> ConnectFeatures { get; } = new List<string>();
91 {
92 get { return this.connectFeatures; }
93 }
94 } 68 }
95} 69}
diff --git a/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs b/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs
index effb06e4..00613ca1 100644
--- a/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs
+++ b/src/WixToolset.Core/Link/FindEntrySectionAndLoadSymbolsCommand.cs
@@ -1,6 +1,6 @@
1// 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. 1// 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.
2 2
3namespace WixToolset.Link 3namespace WixToolset.Core.Link
4{ 4{
5 using System; 5 using System;
6 using System.Collections.Generic; 6 using System.Collections.Generic;
@@ -9,13 +9,13 @@ namespace WixToolset.Link
9 9
10 internal class FindEntrySectionAndLoadSymbolsCommand : ICommand 10 internal class FindEntrySectionAndLoadSymbolsCommand : ICommand
11 { 11 {
12 private IEnumerable<Section> sections; 12 public FindEntrySectionAndLoadSymbolsCommand(IEnumerable<IntermediateSection> sections)
13
14 public FindEntrySectionAndLoadSymbolsCommand(IEnumerable<Section> sections)
15 { 13 {
16 this.sections = sections; 14 this.Sections = sections;
17 } 15 }
18 16
17 private IEnumerable<IntermediateSection> Sections { get; }
18
19 /// <summary> 19 /// <summary>
20 /// Sets the expected entry output type, based on output file extension provided to the linker. 20 /// Sets the expected entry output type, based on output file extension provided to the linker.
21 /// </summary> 21 /// </summary>
@@ -24,13 +24,16 @@ namespace WixToolset.Link
24 /// <summary> 24 /// <summary>
25 /// Gets the located entry section after the command is executed. 25 /// Gets the located entry section after the command is executed.
26 /// </summary> 26 /// </summary>
27 public Section EntrySection { get; private set; } 27 public IntermediateSection EntrySection { get; private set; }
28 28
29 /// <summary> 29 /// <summary>
30 /// Gets the collection of loaded symbols. 30 /// Gets the collection of loaded symbols.
31 /// </summary> 31 /// </summary>
32 public IDictionary<string, Symbol> Symbols { get; private set; } 32 public IDictionary<string, Symbol> Symbols { get; private set; }
33 33
34 /// <summary>
35 /// Gets the collection of possibly conflicting symbols.
36 /// </summary>
34 public IEnumerable<Symbol> PossiblyConflictingSymbols { get; private set; } 37 public IEnumerable<Symbol> PossiblyConflictingSymbols { get; private set; }
35 38
36 public void Execute() 39 public void Execute()
@@ -38,22 +41,22 @@ namespace WixToolset.Link
38 Dictionary<string, Symbol> symbols = new Dictionary<string, Symbol>(); 41 Dictionary<string, Symbol> symbols = new Dictionary<string, Symbol>();
39 HashSet<Symbol> possibleConflicts = new HashSet<Symbol>(); 42 HashSet<Symbol> possibleConflicts = new HashSet<Symbol>();
40 43
41 SectionType expectedEntrySectionType; 44 if (!Enum.TryParse(this.ExpectedOutputType.ToString(), out SectionType expectedEntrySectionType))
42 if (!Enum.TryParse<SectionType>(this.ExpectedOutputType.ToString(), out expectedEntrySectionType))
43 { 45 {
44 expectedEntrySectionType = SectionType.Unknown; 46 expectedEntrySectionType = SectionType.Unknown;
45 } 47 }
46 48
47 foreach (Section section in this.sections) 49 foreach (var section in this.Sections)
48 { 50 {
49 // Try to find the one and only entry section. 51 // Try to find the one and only entry section.
50 if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type || SectionType.Patch == section.Type || SectionType.Bundle == section.Type) 52 if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type || SectionType.Patch == section.Type || SectionType.Bundle == section.Type)
51 { 53 {
52 if (SectionType.Unknown != expectedEntrySectionType && section.Type != expectedEntrySectionType) 54 // TODO: remove this?
53 { 55 //if (SectionType.Unknown != expectedEntrySectionType && section.Type != expectedEntrySectionType)
54 string outputExtension = Output.GetExtension(this.ExpectedOutputType); 56 //{
55 Messaging.Instance.OnMessage(WixWarnings.UnexpectedEntrySection(section.SourceLineNumbers, section.Type.ToString(), expectedEntrySectionType.ToString(), outputExtension)); 57 // string outputExtension = Output.GetExtension(this.ExpectedOutputType);
56 } 58 // Messaging.Instance.OnMessage(WixWarnings.UnexpectedEntrySection(section.SourceLineNumbers, section.Type.ToString(), expectedEntrySectionType.ToString(), outputExtension));
59 //}
57 60
58 if (null == this.EntrySection) 61 if (null == this.EntrySection)
59 { 62 {
@@ -61,42 +64,38 @@ namespace WixToolset.Link
61 } 64 }
62 else 65 else
63 { 66 {
64 Messaging.Instance.OnMessage(WixErrors.MultipleEntrySections(this.EntrySection.SourceLineNumbers, this.EntrySection.Id, section.Id)); 67 Messaging.Instance.OnMessage(WixErrors.MultipleEntrySections(this.EntrySection.Tuples.FirstOrDefault()?.SourceLineNumbers, this.EntrySection.Id, section.Id));
65 Messaging.Instance.OnMessage(WixErrors.MultipleEntrySections2(section.SourceLineNumbers)); 68 Messaging.Instance.OnMessage(WixErrors.MultipleEntrySections2(section.Tuples.FirstOrDefault()?.SourceLineNumbers));
66 } 69 }
67 } 70 }
68 71
69 // Load all the symbols from the section's tables that create symbols. 72 // Load all the symbols from the section's tables that create symbols.
70 foreach (Table table in section.Tables.Where(t => t.Definition.CreateSymbols)) 73 foreach (var row in section.Tuples.Where(t => t.Id != null))
71 { 74 {
72 foreach (Row row in table.Rows) 75 var symbol = new Symbol(section, row);
73 {
74 Symbol symbol = new Symbol(row);
75 76
76 Symbol existingSymbol; 77 if (!symbols.TryGetValue(symbol.Name, out var existingSymbol))
77 if (!symbols.TryGetValue(symbol.Name, out existingSymbol)) 78 {
79 symbols.Add(symbol.Name, symbol);
80 }
81 else // uh-oh, duplicate symbols.
82 {
83 // If the duplicate symbols are both private directories, there is a chance that they
84 // point to identical tuples. Identical directory tuples are redundant and will not cause
85 // conflicts.
86 if (AccessModifier.Private == existingSymbol.Access && AccessModifier.Private == symbol.Access &&
87 TupleDefinitionType.Directory == existingSymbol.Row.Definition.Type && existingSymbol.Row.IsIdentical(symbol.Row))
78 { 88 {
79 symbols.Add(symbol.Name, symbol); 89 // Ensure identical symbol's tuple is marked redundant to ensure (should the tuple be
90 // referenced into the final output) it will not add duplicate primary keys during
91 // the .IDT importing.
92 //symbol.Row.Redundant = true; - TODO: remove this
93 existingSymbol.AddRedundant(symbol);
80 } 94 }
81 else // uh-oh, duplicate symbols. 95 else
82 { 96 {
83 // If the duplicate symbols are both private directories, there is a chance that they 97 existingSymbol.AddPossibleConflict(symbol);
84 // point to identical rows. Identical directory rows are redundant and will not cause 98 possibleConflicts.Add(existingSymbol);
85 // conflicts.
86 if (AccessModifier.Private == existingSymbol.Access && AccessModifier.Private == symbol.Access &&
87 "Directory" == existingSymbol.Row.Table.Name && existingSymbol.Row.IsIdentical(symbol.Row))
88 {
89 // Ensure identical symbol's row is marked redundant to ensure (should the row be
90 // referenced into the final output) it will not add duplicate primary keys during
91 // the .IDT importing.
92 symbol.Row.Redundant = true;
93 existingSymbol.AddRedundant(symbol);
94 }
95 else
96 {
97 existingSymbol.AddPossibleConflict(symbol);
98 possibleConflicts.Add(existingSymbol);
99 }
100 } 99 }
101 } 100 }
102 } 101 }
diff --git a/src/WixToolset.Core/Link/IntermediateTupleExtensions.cs b/src/WixToolset.Core/Link/IntermediateTupleExtensions.cs
new file mode 100644
index 00000000..c4c12e81
--- /dev/null
+++ b/src/WixToolset.Core/Link/IntermediateTupleExtensions.cs
@@ -0,0 +1,26 @@
1// 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.
2
3namespace WixToolset.Core.Link
4{
5 using WixToolset.Data;
6
7 internal static class IntermediateTupleExtensions
8 {
9 public static bool IsIdentical(this IntermediateTuple first, IntermediateTuple second)
10 {
11 var identical = (first.Definition.Type == second.Definition.Type &&
12 first.Definition.Name == second.Definition.Name &&
13 first.Definition.FieldDefinitions.Length == second.Definition.FieldDefinitions.Length);
14
15 for (int i = 0; identical && i < first.Definition.FieldDefinitions.Length; ++i)
16 {
17 var firstField = first[i];
18 var secondField = second[i];
19
20 identical = (firstField.AsString() == secondField.AsString());
21 }
22
23 return identical;
24 }
25 }
26}
diff --git a/src/WixToolset.Core/Link/ReportConflictingSymbolsCommand.cs b/src/WixToolset.Core/Link/ReportConflictingSymbolsCommand.cs
index 39c3a5c2..ac0dd7ec 100644
--- a/src/WixToolset.Core/Link/ReportConflictingSymbolsCommand.cs
+++ b/src/WixToolset.Core/Link/ReportConflictingSymbolsCommand.cs
@@ -6,17 +6,18 @@ namespace WixToolset.Link
6 using System.Linq; 6 using System.Linq;
7 using WixToolset.Data; 7 using WixToolset.Data;
8 8
9 public class ReportConflictingSymbolsCommand : ICommand 9 public class ReportConflictingSymbolsCommand
10 { 10 {
11 private IEnumerable<Symbol> possibleConflicts; 11 public ReportConflictingSymbolsCommand(IEnumerable<Symbol> possibleConflicts, IEnumerable<IntermediateSection> resolvedSections)
12 private IEnumerable<Section> resolvedSections;
13
14 public ReportConflictingSymbolsCommand(IEnumerable<Symbol> possibleConflicts, IEnumerable<Section> resolvedSections)
15 { 12 {
16 this.possibleConflicts = possibleConflicts; 13 this.PossibleConflicts = possibleConflicts;
17 this.resolvedSections = resolvedSections; 14 this.ResolvedSections = resolvedSections;
18 } 15 }
19 16
17 private IEnumerable<Symbol> PossibleConflicts { get; }
18
19 private IEnumerable<IntermediateSection> ResolvedSections { get; }
20
20 public void Execute() 21 public void Execute()
21 { 22 {
22 // Do a quick check if there are any possibly conflicting symbols that don't come from tables that allow 23 // Do a quick check if there are any possibly conflicting symbols that don't come from tables that allow
@@ -25,10 +26,11 @@ namespace WixToolset.Link
25 // symbols are in sections we actually referenced. From the resulting set, show an error for each duplicate 26 // symbols are in sections we actually referenced. From the resulting set, show an error for each duplicate
26 // (aka: conflicting) symbol. This should catch any rows with colliding primary keys (since symbols are based 27 // (aka: conflicting) symbol. This should catch any rows with colliding primary keys (since symbols are based
27 // on the primary keys of rows). 28 // on the primary keys of rows).
28 List<Symbol> illegalDuplicates = possibleConflicts.Where(s => "WixAction" != s.Row.Table.Name && "WixVariable" != s.Row.Table.Name).ToList(); 29 var illegalDuplicates = this.PossibleConflicts.Where(s => s.Row.Definition.Type != TupleDefinitionType.WixAction && s.Row.Definition.Type != TupleDefinitionType.WixVariable).ToList();
29 if (0 < illegalDuplicates.Count) 30 if (0 < illegalDuplicates.Count)
30 { 31 {
31 HashSet<Section> referencedSections = new HashSet<Section>(resolvedSections); 32 var referencedSections = new HashSet<IntermediateSection>(this.ResolvedSections);
33
32 foreach (Symbol referencedDuplicateSymbol in illegalDuplicates.Where(s => referencedSections.Contains(s.Section))) 34 foreach (Symbol referencedDuplicateSymbol in illegalDuplicates.Where(s => referencedSections.Contains(s.Section)))
33 { 35 {
34 List<Symbol> actuallyReferencedDuplicateSymbols = referencedDuplicateSymbol.PossiblyConflictingSymbols.Where(s => referencedSections.Contains(s.Section)).ToList(); 36 List<Symbol> actuallyReferencedDuplicateSymbols = referencedDuplicateSymbol.PossiblyConflictingSymbols.Where(s => referencedSections.Contains(s.Section)).ToList();
diff --git a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs
index 5a985f3f..9c3b2765 100644
--- a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs
+++ b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs
@@ -4,22 +4,21 @@ namespace WixToolset.Link
4{ 4{
5 using System; 5 using System;
6 using System.Collections.Generic; 6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.Linq; 7 using System.Linq;
9 using WixToolset.Data; 8 using WixToolset.Data;
10 using WixToolset.Data.Rows; 9 using WixToolset.Data.Tuples;
11 10
12 /// <summary> 11 /// <summary>
13 /// Resolves all the simple references in a section. 12 /// Resolves all the simple references in a section.
14 /// </summary> 13 /// </summary>
15 internal class ResolveReferencesCommand : ICommand 14 internal class ResolveReferencesCommand : ICommand
16 { 15 {
17 private Section entrySection; 16 private IntermediateSection entrySection;
18 private IDictionary<string, Symbol> symbols; 17 private IDictionary<string, Symbol> symbols;
19 private HashSet<Symbol> referencedSymbols; 18 private HashSet<Symbol> referencedSymbols;
20 private HashSet<Section> resolvedSections; 19 private HashSet<IntermediateSection> resolvedSections;
21 20
22 public ResolveReferencesCommand(Section entrySection, IDictionary<string, Symbol> symbols) 21 public ResolveReferencesCommand(IntermediateSection entrySection, IDictionary<string, Symbol> symbols)
23 { 22 {
24 this.entrySection = entrySection; 23 this.entrySection = entrySection;
25 this.symbols = symbols; 24 this.symbols = symbols;
@@ -29,14 +28,14 @@ namespace WixToolset.Link
29 28
30 public IEnumerable<Symbol> ReferencedSymbols { get { return this.referencedSymbols; } } 29 public IEnumerable<Symbol> ReferencedSymbols { get { return this.referencedSymbols; } }
31 30
32 public IEnumerable<Section> ResolvedSections { get { return this.resolvedSections; } } 31 public IEnumerable<IntermediateSection> ResolvedSections { get { return this.resolvedSections; } }
33 32
34 /// <summary> 33 /// <summary>
35 /// Resolves all the simple references in a section. 34 /// Resolves all the simple references in a section.
36 /// </summary> 35 /// </summary>
37 public void Execute() 36 public void Execute()
38 { 37 {
39 this.resolvedSections = new HashSet<Section>(); 38 this.resolvedSections = new HashSet<IntermediateSection>();
40 this.referencedSymbols = new HashSet<Symbol>(); 39 this.referencedSymbols = new HashSet<Symbol>();
41 40
42 this.RecursivelyResolveReferences(this.entrySection); 41 this.RecursivelyResolveReferences(this.entrySection);
@@ -47,7 +46,7 @@ namespace WixToolset.Link
47 /// </summary> 46 /// </summary>
48 /// <param name="section">Section with references to resolve.</param> 47 /// <param name="section">Section with references to resolve.</param>
49 /// <remarks>Note: recursive function.</remarks> 48 /// <remarks>Note: recursive function.</remarks>
50 private void RecursivelyResolveReferences(Section section) 49 private void RecursivelyResolveReferences(IntermediateSection section)
51 { 50 {
52 // If we already resolved this section, move on to the next. 51 // If we already resolved this section, move on to the next.
53 if (!this.resolvedSections.Add(section)) 52 if (!this.resolvedSections.Add(section))
@@ -59,59 +58,53 @@ namespace WixToolset.Link
59 // symbols provided. Then recursively call this method to process the 58 // symbols provided. Then recursively call this method to process the
60 // located symbol's section. All in all this is a very simple depth-first 59 // located symbol's section. All in all this is a very simple depth-first
61 // search of the references per-section. 60 // search of the references per-section.
62 Table wixSimpleReferenceTable; 61 foreach (var wixSimpleReferenceRow in section.Tuples.OfType<WixSimpleReferenceTuple>())
63 if (section.Tables.TryGetTable("WixSimpleReference", out wixSimpleReferenceTable))
64 { 62 {
65 foreach (WixSimpleReferenceRow wixSimpleReferenceRow in wixSimpleReferenceTable.Rows) 63 // If we're building a Merge Module, ignore all references to the Media table
64 // because Merge Modules don't have Media tables.
65 if (this.BuildingMergeModule && wixSimpleReferenceRow.Definition.Type == TupleDefinitionType.Media)
66 { 66 {
67 Debug.Assert(wixSimpleReferenceRow.Section == section); 67 continue;
68 }
68 69
69 // If we're building a Merge Module, ignore all references to the Media table 70 if (!this.symbols.TryGetValue(wixSimpleReferenceRow.SymbolicName, out var symbol))
70 // because Merge Modules don't have Media tables. 71 {
71 if (this.BuildingMergeModule && "Media" == wixSimpleReferenceRow.TableName) 72 Messaging.Instance.OnMessage(WixErrors.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName));
73 }
74 else // see if the symbol (and any of its duplicates) are appropriately accessible.
75 {
76 IList<Symbol> accessible = DetermineAccessibleSymbols(section, symbol);
77 if (!accessible.Any())
72 { 78 {
73 continue; 79 Messaging.Instance.OnMessage(WixErrors.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName, symbol.Access));
74 } 80 }
75 81 else if (1 == accessible.Count)
76 Symbol symbol;
77 if (!this.symbols.TryGetValue(wixSimpleReferenceRow.SymbolicName, out symbol))
78 { 82 {
79 Messaging.Instance.OnMessage(WixErrors.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName)); 83 var accessibleSymbol = accessible[0];
84 this.referencedSymbols.Add(accessibleSymbol);
85
86 if (null != accessibleSymbol.Section)
87 {
88 RecursivelyResolveReferences(accessibleSymbol.Section);
89 }
80 } 90 }
81 else // see if the symbol (and any of its duplicates) are appropriately accessible. 91 else // display errors for the duplicate symbols.
82 { 92 {
83 IList<Symbol> accessible = DetermineAccessibleSymbols(section, symbol); 93 var accessibleSymbol = accessible[0];
84 if (!accessible.Any()) 94 var referencingSourceLineNumber = wixSimpleReferenceRow.SourceLineNumbers.ToString();
95
96 if (String.IsNullOrEmpty(referencingSourceLineNumber))
85 { 97 {
86 Messaging.Instance.OnMessage(WixErrors.UnresolvedReference(wixSimpleReferenceRow.SourceLineNumbers, wixSimpleReferenceRow.SymbolicName, symbol.Access)); 98 Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol(accessibleSymbol.Row.SourceLineNumbers, accessibleSymbol.Name));
87 } 99 }
88 else if (1 == accessible.Count) 100 else
89 { 101 {
90 Symbol accessibleSymbol = accessible[0]; 102 Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol(accessibleSymbol.Row.SourceLineNumbers, accessibleSymbol.Name, referencingSourceLineNumber));
91 this.referencedSymbols.Add(accessibleSymbol);
92
93 if (null != accessibleSymbol.Section)
94 {
95 RecursivelyResolveReferences(accessibleSymbol.Section);
96 }
97 } 103 }
98 else // display errors for the duplicate symbols. 104
105 foreach (Symbol accessibleDuplicate in accessible.Skip(1))
99 { 106 {
100 Symbol accessibleSymbol = accessible[0]; 107 Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol2(accessibleDuplicate.Row.SourceLineNumbers));
101 string referencingSourceLineNumber = wixSimpleReferenceRow.SourceLineNumbers.ToString();
102 if (String.IsNullOrEmpty(referencingSourceLineNumber))
103 {
104 Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol(accessibleSymbol.Row.SourceLineNumbers, accessibleSymbol.Name));
105 }
106 else
107 {
108 Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol(accessibleSymbol.Row.SourceLineNumbers, accessibleSymbol.Name, referencingSourceLineNumber));
109 }
110
111 foreach (Symbol accessibleDuplicate in accessible.Skip(1))
112 {
113 Messaging.Instance.OnMessage(WixErrors.DuplicateSymbol2(accessibleDuplicate.Row.SourceLineNumbers));
114 }
115 } 108 }
116 } 109 }
117 } 110 }
@@ -124,7 +117,7 @@ namespace WixToolset.Link
124 /// <param name="referencingSection">Section referencing the symbol.</param> 117 /// <param name="referencingSection">Section referencing the symbol.</param>
125 /// <param name="symbol">Symbol being referenced.</param> 118 /// <param name="symbol">Symbol being referenced.</param>
126 /// <returns>List of symbols accessible by referencing section.</returns> 119 /// <returns>List of symbols accessible by referencing section.</returns>
127 private IList<Symbol> DetermineAccessibleSymbols(Section referencingSection, Symbol symbol) 120 private IList<Symbol> DetermineAccessibleSymbols(IntermediateSection referencingSection, Symbol symbol)
128 { 121 {
129 List<Symbol> symbols = new List<Symbol>(); 122 List<Symbol> symbols = new List<Symbol>();
130 123
@@ -158,20 +151,20 @@ namespace WixToolset.Link
158 /// <param name="referencingSection">Section referencing the symbol.</param> 151 /// <param name="referencingSection">Section referencing the symbol.</param>
159 /// <param name="symbol">Symbol being referenced.</param> 152 /// <param name="symbol">Symbol being referenced.</param>
160 /// <returns>True if symbol is accessible.</returns> 153 /// <returns>True if symbol is accessible.</returns>
161 private bool AccessibleSymbol(Section referencingSection, Symbol symbol) 154 private bool AccessibleSymbol(IntermediateSection referencingSection, Symbol symbol)
162 { 155 {
163 switch (symbol.Access) 156 switch (symbol.Access)
164 { 157 {
165 case AccessModifier.Public: 158 case AccessModifier.Public:
166 return true; 159 return true;
167 case AccessModifier.Internal: 160 case AccessModifier.Internal:
168 return symbol.Row.Section.IntermediateId.Equals(referencingSection.IntermediateId) || (null != symbol.Row.Section.LibraryId && symbol.Row.Section.LibraryId.Equals(referencingSection.LibraryId)); 161 return symbol.Section.CompilationId.Equals(referencingSection.CompilationId) || (null != symbol.Section.LibraryId && symbol.Section.LibraryId.Equals(referencingSection.LibraryId));
169 case AccessModifier.Protected: 162 case AccessModifier.Protected:
170 return symbol.Row.Section.IntermediateId.Equals(referencingSection.IntermediateId); 163 return symbol.Section.CompilationId.Equals(referencingSection.CompilationId);
171 case AccessModifier.Private: 164 case AccessModifier.Private:
172 return referencingSection == symbol.Section; 165 return referencingSection == symbol.Section;
173 default: 166 default:
174 throw new InvalidOperationException(); 167 throw new ArgumentOutOfRangeException(nameof(symbol.Access));
175 } 168 }
176 } 169 }
177 } 170 }
diff --git a/src/WixToolset.Core/Link/WixComplexReferenceTupleExtensions.cs b/src/WixToolset.Core/Link/WixComplexReferenceTupleExtensions.cs
new file mode 100644
index 00000000..80cafa50
--- /dev/null
+++ b/src/WixToolset.Core/Link/WixComplexReferenceTupleExtensions.cs
@@ -0,0 +1,73 @@
1// 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.
2
3namespace WixToolset.Core.Link
4{
5 using System;
6 using WixToolset.Data.Tuples;
7
8 internal static class WixComplexReferenceTupleExtensions
9 {
10 /// <summary>
11 /// Creates a shallow copy of the ComplexReference.
12 /// </summary>
13 /// <returns>A shallow copy of the ComplexReference.</returns>
14 public static WixComplexReferenceTuple Clone(this WixComplexReferenceTuple source)
15 {
16 var clone = new WixComplexReferenceTuple(source.SourceLineNumbers, source.Id);
17 clone.ParentType = source.ParentType;
18 clone.Parent = source.Parent;
19 clone.ParentLanguage = source.ParentLanguage;
20 clone.ChildType = source.ChildType;
21 clone.Child = source.Child;
22 clone.IsPrimary = source.IsPrimary;
23
24 return clone;
25 }
26
27 /// <summary>
28 /// Compares two complex references without considering the primary bit.
29 /// </summary>
30 /// <param name="obj">Complex reference to compare to.</param>
31 /// <returns>Zero if the objects are equivalent, negative number if the provided object is less, positive if greater.</returns>
32 public static int CompareToWithoutConsideringPrimary(this WixComplexReferenceTuple tuple, WixComplexReferenceTuple other)
33 {
34 var comparison = tuple.ChildType - other.ChildType;
35 if (0 == comparison)
36 {
37 comparison = String.Compare(tuple.Child, other.Child, StringComparison.Ordinal);
38 if (0 == comparison)
39 {
40 comparison = tuple.ParentType - other.ParentType;
41 if (0 == comparison)
42 {
43 string thisParentLanguage = null == tuple.ParentLanguage ? String.Empty : tuple.ParentLanguage;
44 string otherParentLanguage = null == other.ParentLanguage ? String.Empty : other.ParentLanguage;
45 comparison = String.Compare(thisParentLanguage, otherParentLanguage, StringComparison.Ordinal);
46 if (0 == comparison)
47 {
48 comparison = String.Compare(tuple.Parent, other.Parent, StringComparison.Ordinal);
49 }
50 }
51 }
52 }
53
54 return comparison;
55 }
56
57 /// <summary>
58 /// Changes all of the parent references to point to the passed in parent reference.
59 /// </summary>
60 /// <param name="parent">New parent complex reference.</param>
61 public static void Reparent(this WixComplexReferenceTuple tuple, WixComplexReferenceTuple parent)
62 {
63 tuple.Parent = parent.Parent;
64 tuple.ParentLanguage = parent.ParentLanguage;
65 tuple.ParentType = parent.ParentType;
66
67 if (!tuple.IsPrimary)
68 {
69 tuple.IsPrimary = parent.IsPrimary;
70 }
71 }
72 }
73}
diff --git a/src/WixToolset.Core/Link/WixGroupingOrdering.cs b/src/WixToolset.Core/Link/WixGroupingOrdering.cs
index fc0ce43b..4dd1596c 100644
--- a/src/WixToolset.Core/Link/WixGroupingOrdering.cs
+++ b/src/WixToolset.Core/Link/WixGroupingOrdering.cs
@@ -12,13 +12,13 @@ namespace WixToolset.Link
12 using System.Text; 12 using System.Text;
13 using WixToolset.Extensibility; 13 using WixToolset.Extensibility;
14 using WixToolset.Data; 14 using WixToolset.Data;
15 using WixToolset.Data.Tuples;
15 16
16 /// <summary> 17 /// <summary>
17 /// Grouping and Ordering class of the WiX toolset. 18 /// Grouping and Ordering class of the WiX toolset.
18 /// </summary> 19 /// </summary>
19 internal sealed class WixGroupingOrdering : IMessageHandler 20 internal sealed class WixGroupingOrdering : IMessageHandler
20 { 21 {
21 private Output output;
22 private IMessageHandler messageHandler; 22 private IMessageHandler messageHandler;
23 private List<string> groupTypes; 23 private List<string> groupTypes;
24 private List<string> itemTypes; 24 private List<string> itemTypes;
@@ -34,9 +34,9 @@ namespace WixToolset.Link
34 /// <param name="messageHandler">Handler for any error messages.</param> 34 /// <param name="messageHandler">Handler for any error messages.</param>
35 /// <param name="groupTypes">Group types to include.</param> 35 /// <param name="groupTypes">Group types to include.</param>
36 /// <param name="itemTypes">Item types to include.</param> 36 /// <param name="itemTypes">Item types to include.</param>
37 public WixGroupingOrdering(Output output, IMessageHandler messageHandler) 37 public WixGroupingOrdering(IntermediateSection entrySections, IMessageHandler messageHandler)
38 { 38 {
39 this.output = output; 39 this.EntrySection = entrySections;
40 this.messageHandler = messageHandler; 40 this.messageHandler = messageHandler;
41 41
42 this.rowsUsed = new List<int>(); 42 this.rowsUsed = new List<int>();
@@ -44,6 +44,8 @@ namespace WixToolset.Link
44 this.encounteredError = false; 44 this.encounteredError = false;
45 } 45 }
46 46
47 private IntermediateSection EntrySection { get; }
48
47 /// <summary> 49 /// <summary>
48 /// Switches a WixGroupingOrdering object to operate on a new set of groups/items. 50 /// Switches a WixGroupingOrdering object to operate on a new set of groups/items.
49 /// </summary> 51 /// </summary>
@@ -91,8 +93,7 @@ namespace WixToolset.Link
91 { 93 {
92 Debug.Assert(this.groupTypes.Contains(parentType)); 94 Debug.Assert(this.groupTypes.Contains(parentType));
93 95
94 List<Item> orderedItems; 96 this.CreateOrderedList(parentType, parentId, out var orderedItems);
95 this.CreateOrderedList(parentType, parentId, out orderedItems);
96 if (this.encounteredError) 97 if (this.encounteredError)
97 { 98 {
98 return; 99 return;
@@ -170,15 +171,16 @@ namespace WixToolset.Link
170 /// </summary> 171 /// </summary>
171 public void RemoveUsedGroupRows() 172 public void RemoveUsedGroupRows()
172 { 173 {
173 List<int> sortedIndexes = this.rowsUsed.Distinct().OrderByDescending(i => i).ToList(); 174 var sortedIndexes = this.rowsUsed.Distinct().OrderByDescending(i => i).ToList();
174 175
175 Table wixGroupTable = this.output.Tables["WixGroup"]; 176 //Table wixGroupTable = this.output.Tables["WixGroup"];
176 Debug.Assert(null != wixGroupTable); 177 //Debug.Assert(null != wixGroupTable);
177 Debug.Assert(sortedIndexes[0] < wixGroupTable.Rows.Count); 178 //Debug.Assert(sortedIndexes[0] < wixGroupTable.Rows.Count);
178 179
179 foreach (int rowIndex in sortedIndexes) 180 foreach (int rowIndex in sortedIndexes)
180 { 181 {
181 wixGroupTable.Rows.RemoveAt(rowIndex); 182 //wixGroupTable.Rows.RemoveAt(rowIndex);
183 this.EntrySection.Tuples.RemoveAt(rowIndex);
182 } 184 }
183 } 185 }
184 186
@@ -194,16 +196,15 @@ namespace WixToolset.Link
194 // does WiX (although they do, currently). We probably want to "upgrade" this to a new 196 // does WiX (although they do, currently). We probably want to "upgrade" this to a new
195 // table that includes a sequence number, and then change the code that uses ordered 197 // table that includes a sequence number, and then change the code that uses ordered
196 // groups to read from that table instead. 198 // groups to read from that table instead.
197 Table wixGroupTable = this.output.Tables["WixGroup"];
198 Debug.Assert(null != wixGroupTable);
199
200 foreach (Item item in orderedItems) 199 foreach (Item item in orderedItems)
201 { 200 {
202 Row row = wixGroupTable.CreateRow(item.Row.SourceLineNumbers); 201 var row = new WixGroupTuple(item.Row.SourceLineNumbers);
203 row[0] = parentId; 202 row.ParentId = parentId;
204 row[1] = parentType; 203 row.ParentType = (ComplexReferenceParentType)Enum.Parse(typeof(ComplexReferenceParentType), parentType);
205 row[2] = item.Id; 204 row.ChildId = item.Id;
206 row[3] = item.Type; 205 row.ChildType = (ComplexReferenceChildType)Enum.Parse(typeof(ComplexReferenceChildType), item.Type);
206
207 this.EntrySection.Tuples.Add(row);
207 } 208 }
208 } 209 }
209 210
@@ -254,47 +255,47 @@ namespace WixToolset.Link
254 /// </summary> 255 /// </summary>
255 private void LoadGroups() 256 private void LoadGroups()
256 { 257 {
257 Table wixGroupTable = this.output.Tables["WixGroup"]; 258 //Table wixGroupTable = this.output.Tables["WixGroup"];
258 if (null == wixGroupTable || 0 == wixGroupTable.Rows.Count) 259 //if (null == wixGroupTable || 0 == wixGroupTable.Rows.Count)
259 { 260 //{
260 // TODO: Change message name to make it *not* Bundle specific? 261 // // TODO: Change message name to make it *not* Bundle specific?
261 this.OnMessage(WixErrors.MissingBundleInformation("WixGroup")); 262 // this.OnMessage(WixErrors.MissingBundleInformation("WixGroup"));
262 } 263 //}
263 264
264 // Collect all of the groups 265 // Collect all of the groups
265 for (int rowIndex = 0; rowIndex < wixGroupTable.Rows.Count; ++rowIndex) 266 for (int rowIndex = 0; rowIndex < this.EntrySection.Tuples.Count; ++rowIndex)
266 { 267 {
267 Row row = wixGroupTable.Rows[rowIndex]; 268 if (this.EntrySection.Tuples[rowIndex] is WixGroupTuple row)
268 string rowParentName = (string)row[0];
269 string rowParentType = (string)row[1];
270 string rowChildName = (string)row[2];
271 string rowChildType = (string)row[3];
272
273 // If this row specifies a parent or child type that's not in our
274 // lists, we assume it's not a row that we're concerned about.
275 if (!this.groupTypes.Contains(rowParentType) ||
276 !this.itemTypes.Contains(rowChildType))
277 { 269 {
278 continue; 270 var rowParentName = row.ParentId;
279 } 271 var rowParentType = row.ParentType.ToString();
272 var rowChildName = row.ChildId;
273 var rowChildType = row.ChildType.ToString();
274
275 // If this row specifies a parent or child type that's not in our
276 // lists, we assume it's not a row that we're concerned about.
277 if (!this.groupTypes.Contains(rowParentType) ||
278 !this.itemTypes.Contains(rowChildType))
279 {
280 continue;
281 }
280 282
281 this.rowsUsed.Add(rowIndex); 283 this.rowsUsed.Add(rowIndex);
282 284
283 Item parentItem; 285 if (!this.items.TryGetValue(rowParentType, rowParentName, out var parentItem))
284 if (!this.items.TryGetValue(rowParentType, rowParentName, out parentItem)) 286 {
285 { 287 parentItem = new Item(row, rowParentType, rowParentName);
286 parentItem = new Item(row, rowParentType, rowParentName); 288 this.items.Add(parentItem);
287 this.items.Add(parentItem); 289 }
288 }
289 290
290 Item childItem; 291 if (!this.items.TryGetValue(rowChildType, rowChildName, out var childItem))
291 if (!this.items.TryGetValue(rowChildType, rowChildName, out childItem)) 292 {
292 { 293 childItem = new Item(row, rowChildType, rowChildName);
293 childItem = new Item(row, rowChildType, rowChildName); 294 this.items.Add(childItem);
294 this.items.Add(childItem); 295 }
295 }
296 296
297 parentItem.ChildItems.Add(childItem); 297 parentItem.ChildItems.Add(childItem);
298 }
298 } 299 }
299 } 300 }
300 301
@@ -374,19 +375,19 @@ namespace WixToolset.Link
374 /// </summary> 375 /// </summary>
375 private void LoadOrdering() 376 private void LoadOrdering()
376 { 377 {
377 Table wixOrderingTable = output.Tables["WixOrdering"]; 378 //Table wixOrderingTable = output.Tables["WixOrdering"];
378 if (null == wixOrderingTable || 0 == wixOrderingTable.Rows.Count) 379 //if (null == wixOrderingTable || 0 == wixOrderingTable.Rows.Count)
379 { 380 //{
380 // TODO: Do we need a message here? 381 // // TODO: Do we need a message here?
381 return; 382 // return;
382 } 383 //}
383 384
384 foreach (Row row in wixOrderingTable.Rows) 385 foreach (var row in this.EntrySection.Tuples.OfType<WixOrderingTuple>())
385 { 386 {
386 string rowItemType = (string)row[0]; 387 var rowItemType = row.ItemType;
387 string rowItemName = (string)row[1]; 388 var rowItemName = row.ItemId_;
388 string rowDependsOnType = (string)row[2]; 389 var rowDependsOnType = row.DependsOnType;
389 string rowDependsOnName = (string)row[3]; 390 var rowDependsOnName = row.DependsOnId_;
390 391
391 // If this row specifies some other (unknown) type in either 392 // If this row specifies some other (unknown) type in either
392 // position, we assume it's not a row that we're concerned about. 393 // position, we assume it's not a row that we're concerned about.
@@ -397,15 +398,12 @@ namespace WixToolset.Link
397 continue; 398 continue;
398 } 399 }
399 400
400 Item item = null; 401 if (!this.items.TryGetValue(rowItemType, rowItemName, out var item))
401 Item dependsOn = null;
402
403 if (!this.items.TryGetValue(rowItemType, rowItemName, out item))
404 { 402 {
405 this.OnMessage(WixErrors.IdentifierNotFound(rowItemType, rowItemName)); 403 this.OnMessage(WixErrors.IdentifierNotFound(rowItemType, rowItemName));
406 } 404 }
407 405
408 if (!this.items.TryGetValue(rowDependsOnType, rowDependsOnName, out dependsOn)) 406 if (!this.items.TryGetValue(rowDependsOnType, rowDependsOnName, out var dependsOn))
409 { 407 {
410 this.OnMessage(WixErrors.IdentifierNotFound(rowDependsOnType, rowDependsOnName)); 408 this.OnMessage(WixErrors.IdentifierNotFound(rowDependsOnType, rowDependsOnName));
411 } 409 }
@@ -540,7 +538,7 @@ namespace WixToolset.Link
540 private ItemCollection beforeItems; // for checking for circular references 538 private ItemCollection beforeItems; // for checking for circular references
541 private bool flattenedAfterItems; 539 private bool flattenedAfterItems;
542 540
543 public Item(Row row, string type, string id) 541 public Item(IntermediateTuple row, string type, string id)
544 { 542 {
545 this.Row = row; 543 this.Row = row;
546 this.Type = type; 544 this.Type = type;
@@ -553,7 +551,7 @@ namespace WixToolset.Link
553 flattenedAfterItems = false; 551 flattenedAfterItems = false;
554 } 552 }
555 553
556 public Row Row { get; private set; } 554 public IntermediateTuple Row { get; private set; }
557 public string Type { get; private set; } 555 public string Type { get; private set; }
558 public string Id { get; private set; } 556 public string Id { get; private set; }
559 public string Key { get; private set; } 557 public string Key { get; private set; }
@@ -718,7 +716,7 @@ namespace WixToolset.Link
718 return -1; 716 return -1;
719 } 717 }
720 718
721 return string.CompareOrdinal(x.Id, y.Id); 719 return String.CompareOrdinal(x.Id, y.Id);
722 } 720 }
723 } 721 }
724 } 722 }
diff --git a/src/WixToolset.Core/LinkContext.cs b/src/WixToolset.Core/LinkContext.cs
new file mode 100644
index 00000000..c3631f72
--- /dev/null
+++ b/src/WixToolset.Core/LinkContext.cs
@@ -0,0 +1,28 @@
1// 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.
2
3namespace WixToolset.Core
4{
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Data;
8 using WixToolset.Extensibility;
9 using WixToolset.Extensibility.Services;
10
11 public class LinkContext : ILinkContext
12 {
13 internal LinkContext(IServiceProvider serviceProvider)
14 {
15 this.ServiceProvider = serviceProvider;
16 }
17
18 public IServiceProvider ServiceProvider { get; }
19
20 public Messaging Messaging { get; set; }
21
22 public IEnumerable<ILinkerExtension> Extensions { get; set; }
23
24 public OutputType ExpectedOutputType { get; set; }
25
26 public IEnumerable<Intermediate> Intermediates { get; set; }
27 }
28}
diff --git a/src/WixToolset.Core/Linker.cs b/src/WixToolset.Core/Linker.cs
index c1c9f848..59481387 100644
--- a/src/WixToolset.Core/Linker.cs
+++ b/src/WixToolset.Core/Linker.cs
@@ -1,21 +1,18 @@
1// 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. 1// 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.
2 2
3namespace WixToolset 3namespace WixToolset.Core
4{ 4{
5 using System; 5 using System;
6 using System.Collections; 6 using System.Collections;
7 using System.Collections.Generic; 7 using System.Collections.Generic;
8 using System.Collections.Specialized;
9 using System.Diagnostics; 8 using System.Diagnostics;
10 using System.Diagnostics.CodeAnalysis;
11 using System.Globalization; 9 using System.Globalization;
12 using System.Linq; 10 using System.Linq;
13 using System.Text;
14 using WixToolset.Data; 11 using WixToolset.Data;
15 using WixToolset.Data.Rows;
16 using WixToolset.Extensibility;
17 using WixToolset.Link; 12 using WixToolset.Link;
18 using WixToolset.Core.Native; 13 using WixToolset.Core.Link;
14 using WixToolset.Data.Tuples;
15 using WixToolset.Extensibility.Services;
19 16
20 /// <summary> 17 /// <summary>
21 /// Linker core of the WiX toolset. 18 /// Linker core of the WiX toolset.
@@ -25,13 +22,10 @@ namespace WixToolset
25 private static readonly char[] colonCharacter = ":".ToCharArray(); 22 private static readonly char[] colonCharacter = ":".ToCharArray();
26 private static readonly string emptyGuid = Guid.Empty.ToString("B"); 23 private static readonly string emptyGuid = Guid.Empty.ToString("B");
27 24
28 private List<IExtensionData> extensionData;
29
30 private List<InspectorExtension> inspectorExtensions;
31 private bool sectionIdOnRows; 25 private bool sectionIdOnRows;
32 private WixActionRowCollection standardActions; 26 //private WixActionRowCollection standardActions;
33 private Output activeOutput; 27 //private Output activeOutput;
34 private TableDefinitionCollection tableDefinitions; 28 //private TableDefinitionCollection tableDefinitions;
35 29
36 /// <summary> 30 /// <summary>
37 /// Creates a linker. 31 /// Creates a linker.
@@ -40,18 +34,14 @@ namespace WixToolset
40 { 34 {
41 this.sectionIdOnRows = true; // TODO: what is the correct value for this? 35 this.sectionIdOnRows = true; // TODO: what is the correct value for this?
42 36
43 this.standardActions = WindowsInstallerStandard.GetStandardActions(); 37 //this.standardActions = WindowsInstallerStandard.GetStandardActions();
44 this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions()); 38 //this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions());
45 39
46 this.extensionData = new List<IExtensionData>(); 40 //this.extensionData = new List<IExtensionData>();
47 this.inspectorExtensions = new List<InspectorExtension>(); 41 //this.inspectorExtensions = new List<InspectorExtension>();
48 } 42 }
49 43
50 /// <summary> 44 private ILinkContext Context { get; set; }
51 /// Gets or sets the localizer.
52 /// </summary>
53 /// <value>The localizer.</value>
54 public Localizer Localizer { get; set; }
55 45
56 /// <summary> 46 /// <summary>
57 /// Gets or sets the path to output unreferenced symbols to. If null or empty, there is no output. 47 /// Gets or sets the path to output unreferenced symbols to. If null or empty, there is no output.
@@ -66,45 +56,36 @@ namespace WixToolset
66 public bool ShowPedanticMessages { get; set; } 56 public bool ShowPedanticMessages { get; set; }
67 57
68 /// <summary> 58 /// <summary>
69 /// Gets the table definitions used by the linker.
70 /// </summary>
71 /// <value>Table definitions used by the linker.</value>
72 public TableDefinitionCollection TableDefinitions
73 {
74 get { return this.tableDefinitions; }
75 }
76
77 /// <summary>
78 /// Gets or sets the Wix variable resolver. 59 /// Gets or sets the Wix variable resolver.
79 /// </summary> 60 /// </summary>
80 /// <value>The Wix variable resolver.</value> 61 /// <value>The Wix variable resolver.</value>
81 internal IBindVariableResolver WixVariableResolver { get; set; } 62 //internal IBindVariableResolver WixVariableResolver { get; set; }
82 63
83 /// <summary> 64 /// <summary>
84 /// Adds an extension. 65 /// Adds an extension.
85 /// </summary> 66 /// </summary>
86 /// <param name="extension">The extension to add.</param> 67 /// <param name="extension">The extension to add.</param>
87 public void AddExtensionData(IExtensionData extension) 68 //public void AddExtensionData(IExtensionData extension)
88 { 69 //{
89 if (null != extension.TableDefinitions) 70 // if (null != extension.TableDefinitions)
90 { 71 // {
91 foreach (TableDefinition tableDefinition in extension.TableDefinitions) 72 // foreach (TableDefinition tableDefinition in extension.TableDefinitions)
92 { 73 // {
93 if (!this.tableDefinitions.Contains(tableDefinition.Name)) 74 // if (!this.tableDefinitions.Contains(tableDefinition.Name))
94 { 75 // {
95 this.tableDefinitions.Add(tableDefinition); 76 // this.tableDefinitions.Add(tableDefinition);
96 } 77 // }
97 else 78 // else
98 { 79 // {
99 throw new WixException(WixErrors.DuplicateExtensionTable(extension.GetType().ToString(), tableDefinition.Name)); 80 // throw new WixException(WixErrors.DuplicateExtensionTable(extension.GetType().ToString(), tableDefinition.Name));
100 } 81 // }
101 } 82 // }
102 } 83 // }
103 84
104 // keep track of extension data so the libraries can be loaded from these later once all the table definitions 85 // // keep track of extension data so the libraries can be loaded from these later once all the table definitions
105 // are loaded; this will allow extensions to have cross table definition dependencies 86 // // are loaded; this will allow extensions to have cross table definition dependencies
106 this.extensionData.Add(extension); 87 // this.extensionData.Add(extension);
107 } 88 //}
108 89
109 /// <summary> 90 /// <summary>
110 /// Links a collection of sections into an output. 91 /// Links a collection of sections into an output.
@@ -112,31 +93,39 @@ namespace WixToolset
112 /// <param name="inputs">The collection of sections to link together.</param> 93 /// <param name="inputs">The collection of sections to link together.</param>
113 /// <param name="expectedOutputType">Expected output type, based on output file extension provided to the linker.</param> 94 /// <param name="expectedOutputType">Expected output type, based on output file extension provided to the linker.</param>
114 /// <returns>Output object from the linking.</returns> 95 /// <returns>Output object from the linking.</returns>
115 public Output Link(IEnumerable<Section> inputs, OutputType expectedOutputType) 96 public Intermediate Link(ILinkContext context)
116 { 97 {
117 Output output = null; 98 this.Context = context ?? throw new ArgumentNullException(nameof(context));
118 List<Section> sections = new List<Section>(inputs);
119 99
120 try 100 //IEnumerable<Section> inputs, OutputType expectedOutputType
121 { 101
102 var sections = this.Context.Intermediates.SelectMany(i => i.Sections).ToList();
103
104#if MOVE_TO_BACKEND
122 bool containsModuleSubstitution = false; 105 bool containsModuleSubstitution = false;
123 bool containsModuleConfiguration = false; 106 bool containsModuleConfiguration = false;
107#endif
124 108
125 this.activeOutput = null; 109 //this.activeOutput = null;
126 110
127 List<Row> actionRows = new List<Row>(); 111#if MOVE_TO_BACKEND
128 List<Row> suppressActionRows = new List<Row>(); 112 var actionRows = new List<IntermediateTuple>();
113 var suppressActionRows = new List<IntermediateTuple>();
114#endif
129 115
130 TableDefinitionCollection customTableDefinitions = new TableDefinitionCollection(); 116 //TableDefinitionCollection customTableDefinitions = new TableDefinitionCollection();
131 List<Row> customRows = new List<Row>(); 117 //IntermediateTuple customRows = new List<IntermediateTuple>();
132 118
119#if MOVE_TO_BACKEND
133 StringCollection generatedShortFileNameIdentifiers = new StringCollection(); 120 StringCollection generatedShortFileNameIdentifiers = new StringCollection();
134 Hashtable generatedShortFileNames = new Hashtable(); 121 Hashtable generatedShortFileNames = new Hashtable();
122#endif
135 123
136 Hashtable multipleFeatureComponents = new Hashtable(); 124 Hashtable multipleFeatureComponents = new Hashtable();
137 125
138 Hashtable wixVariables = new Hashtable(); 126 var wixVariables = new Dictionary<string, WixVariableTuple>();
139 127
128#if MOVE_TO_BACKEND
140 // verify that modularization types match for foreign key relationships 129 // verify that modularization types match for foreign key relationships
141 foreach (TableDefinition tableDefinition in this.tableDefinitions) 130 foreach (TableDefinition tableDefinition in this.tableDefinitions)
142 { 131 {
@@ -164,7 +153,9 @@ namespace WixToolset
164 } 153 }
165 } 154 }
166 } 155 }
156#endif
167 157
158#if TODO
168 // Add sections from the extensions with data. 159 // Add sections from the extensions with data.
169 foreach (IExtensionData data in this.extensionData) 160 foreach (IExtensionData data in this.extensionData)
170 { 161 {
@@ -175,123 +166,118 @@ namespace WixToolset
175 sections.AddRange(library.Sections); 166 sections.AddRange(library.Sections);
176 } 167 }
177 } 168 }
169#endif
178 170
179 // First find the entry section and while processing all sections load all the symbols from all of the sections. 171 // First find the entry section and while processing all sections load all the symbols from all of the sections.
180 // sections.FindEntrySectionAndLoadSymbols(false, this, expectedOutputType, out entrySection, out allSymbols); 172 // sections.FindEntrySectionAndLoadSymbols(false, this, expectedOutputType, out entrySection, out allSymbols);
181 FindEntrySectionAndLoadSymbolsCommand find = new FindEntrySectionAndLoadSymbolsCommand(sections); 173 var find = new FindEntrySectionAndLoadSymbolsCommand(sections);
182 find.ExpectedOutputType = expectedOutputType; 174 find.ExpectedOutputType = this.Context.ExpectedOutputType;
175 find.Execute();
183 176
184 find.Execute(); 177 // Must have found the entry section by now.
178 if (null == find.EntrySection)
179 {
180 throw new WixException(WixErrors.MissingEntrySection(this.Context.ExpectedOutputType.ToString()));
181 }
185 182
186 // Must have found the entry section by now. 183 // Now that we know where we're starting from, create the section to hold the linked content.
187 if (null == find.EntrySection) 184 var resolvedSection = new IntermediateSection(find.EntrySection.Id, find.EntrySection.Type, find.EntrySection.Codepage);
188 { 185 var allSymbols = find.Symbols;
189 throw new WixException(WixErrors.MissingEntrySection(expectedOutputType.ToString()));
190 }
191 186
192 IDictionary<string, Symbol> allSymbols = find.Symbols; 187 // Add the missing standard action symbols.
188 this.LoadStandardActionSymbols(resolvedSection, allSymbols);
193 189
194 // Add the missing standard action symbols. 190 // Resolve the symbol references to find the set of sections we care about for linking.
195 this.LoadStandardActionSymbols(allSymbols); 191 // Of course, we start with the entry section (that's how it got its name after all).
192 var resolve = new ResolveReferencesCommand(find.EntrySection, allSymbols);
193 resolve.BuildingMergeModule = (SectionType.Module == find.EntrySection.Type);
196 194
197 // now that we know where we're starting from, create the output object 195 resolve.Execute();
198 output = new Output(null);
199 output.EntrySection = find.EntrySection; // Note: this entry section will get added to the Output.Sections collection later
200 if (null != this.Localizer && -1 != this.Localizer.Codepage)
201 {
202 output.Codepage = this.Localizer.Codepage;
203 }
204 this.activeOutput = output;
205 196
206 // Resolve the symbol references to find the set of sections we care about for linking. 197 if (Messaging.Instance.EncounteredError)
207 // Of course, we start with the entry section (that's how it got its name after all). 198 {
208 ResolveReferencesCommand resolve = new ResolveReferencesCommand(output.EntrySection, allSymbols); 199 return null;
209 resolve.BuildingMergeModule = (OutputType.Module == output.Type); 200 }
210 201
211 resolve.Execute(); 202 // Reset the sections to only those that were resolved then flatten the complex
203 // references that particpate in groups.
204 sections = resolve.ResolvedSections.ToList();
212 205
213 if (Messaging.Instance.EncounteredError) 206 this.FlattenSectionsComplexReferences(sections);
214 {
215 return null;
216 }
217 207
218 // Add the resolved sections to the output then flatten the complex 208 if (Messaging.Instance.EncounteredError)
219 // references that particpate in groups. 209 {
220 foreach (Section section in resolve.ResolvedSections) 210 return null;
221 { 211 }
222 output.Sections.Add(section);
223 }
224 212
225 this.FlattenSectionsComplexReferences(output.Sections); 213 // The hard part in linking is processing the complex references.
214 var referencedComponents = new HashSet<string>();
215 var componentsToFeatures = new ConnectToFeatureCollection();
216 var featuresToFeatures = new ConnectToFeatureCollection();
217 var modulesToFeatures = new ConnectToFeatureCollection();
218 this.ProcessComplexReferences(resolvedSection, sections, referencedComponents, componentsToFeatures, featuresToFeatures, modulesToFeatures);
226 219
227 if (Messaging.Instance.EncounteredError) 220 if (Messaging.Instance.EncounteredError)
221 {
222 return null;
223 }
224
225 // Display an error message for Components that were not referenced by a Feature.
226 foreach (var symbol in resolve.ReferencedSymbols.Where(s => s.Row.Definition.Type == TupleDefinitionType.Component))
227 {
228 if (!referencedComponents.Contains(symbol.Name))
228 { 229 {
229 return null; 230 this.OnMessage(WixErrors.OrphanedComponent(symbol.Row.SourceLineNumbers, symbol.Row.Id.Id));
230 } 231 }
232 }
231 233
232 // The hard part in linking is processing the complex references. 234 // Report duplicates that would ultimately end up being primary key collisions.
233 HashSet<string> referencedComponents = new HashSet<string>(); 235 ReportConflictingSymbolsCommand reportDupes = new ReportConflictingSymbolsCommand(find.PossiblyConflictingSymbols, resolve.ResolvedSections);
234 ConnectToFeatureCollection componentsToFeatures = new ConnectToFeatureCollection(); 236 reportDupes.Execute();
235 ConnectToFeatureCollection featuresToFeatures = new ConnectToFeatureCollection();
236 ConnectToFeatureCollection modulesToFeatures = new ConnectToFeatureCollection();
237 this.ProcessComplexReferences(output, output.Sections, referencedComponents, componentsToFeatures, featuresToFeatures, modulesToFeatures);
238 237
239 if (Messaging.Instance.EncounteredError) 238 if (Messaging.Instance.EncounteredError)
240 { 239 {
241 return null; 240 return null;
242 } 241 }
243 242
244 // Display an error message for Components that were not referenced by a Feature. 243 // resolve the feature to feature connects
245 foreach (Symbol symbol in resolve.ReferencedSymbols.Where(s => "Component".Equals(s.Row.TableDefinition.Name, StringComparison.Ordinal))) 244 this.ResolveFeatureToFeatureConnects(featuresToFeatures, allSymbols);
246 {
247 if (!referencedComponents.Contains(symbol.Name))
248 {
249 this.OnMessage(WixErrors.OrphanedComponent(symbol.Row.SourceLineNumbers, (string)symbol.Row[0]));
250 }
251 }
252 245
253 // Report duplicates that would ultimately end up being primary key collisions. 246 // start generating OutputTables and OutputRows for all the sections in the output
254 ReportConflictingSymbolsCommand reportDupes = new ReportConflictingSymbolsCommand(find.PossiblyConflictingSymbols, resolve.ResolvedSections); 247 var ensureTableRows = new List<IntermediateTuple>();
255 reportDupes.Execute();
256 248
257 if (Messaging.Instance.EncounteredError) 249 int sectionCount = 0;
250 foreach (var section in sections)
251 {
252 sectionCount++;
253
254 string sectionId = section.Id;
255 if (null == sectionId && this.sectionIdOnRows)
258 { 256 {
259 return null; 257 sectionId = "wix.section." + sectionCount.ToString(CultureInfo.InvariantCulture);
260 } 258 }
261 259
262 // resolve the feature to feature connects 260 foreach (var tuple in section.Tuples)
263 this.ResolveFeatureToFeatureConnects(featuresToFeatures, allSymbols);
264
265 // start generating OutputTables and OutputRows for all the sections in the output
266 List<Row> ensureTableRows = new List<Row>();
267 int sectionCount = 0;
268 foreach (Section section in output.Sections)
269 { 261 {
270 sectionCount++; 262 var copyTuple = true; // by default, copy tuples.
271 string sectionId = section.Id;
272 if (null == sectionId && this.sectionIdOnRows)
273 {
274 sectionId = "wix.section." + sectionCount.ToString(CultureInfo.InvariantCulture);
275 }
276 263
277 foreach (Table table in section.Tables) 264 // handle special tables
265 switch (tuple.Definition.Type)
278 { 266 {
279 bool copyRows = true; // by default, copy rows. 267#if MOVE_TO_BACKEND
280
281 // handle special tables
282 switch (table.Name)
283 {
284 case "AppSearch": 268 case "AppSearch":
285 this.activeOutput.EnsureTable(this.tableDefinitions["Signature"]); 269 this.activeOutput.EnsureTable(this.tableDefinitions["Signature"]);
286 break; 270 break;
271#endif
287 272
288 case "Class": 273 case TupleDefinitionType.Class:
289 if (OutputType.Product == output.Type) 274 if (SectionType.Product == resolvedSection.Type)
290 { 275 {
291 this.ResolveFeatures(table.Rows, 2, 11, componentsToFeatures, multipleFeatureComponents); 276 this.ResolveFeatures(tuple, 2, 11, componentsToFeatures, multipleFeatureComponents);
292 } 277 }
293 break; 278 break;
294 279
280#if MOVE_TO_BACKEND
295 case "CustomAction": 281 case "CustomAction":
296 if (OutputType.Module == this.activeOutput.Type) 282 if (OutputType.Module == this.activeOutput.Type)
297 { 283 {
@@ -342,29 +328,32 @@ namespace WixToolset
342 } 328 }
343 } 329 }
344 break; 330 break;
331#endif
332 case TupleDefinitionType.Extension:
333 if (SectionType.Product == resolvedSection.Type)
334 {
335 this.ResolveFeatures(tuple, 1, 4, componentsToFeatures, multipleFeatureComponents);
336 }
337 break;
345 338
346 case "Extension": 339#if MOVE_TO_BACKEND
347 if (OutputType.Product == output.Type) 340 case TupleDefinitionType.ModuleSubstitution:
348 {
349 this.ResolveFeatures(table.Rows, 1, 4, componentsToFeatures, multipleFeatureComponents);
350 }
351 break;
352
353 case "ModuleSubstitution":
354 containsModuleSubstitution = true; 341 containsModuleSubstitution = true;
355 break; 342 break;
356 343
357 case "ModuleConfiguration": 344 case TupleDefinitionType.ModuleConfiguration:
358 containsModuleConfiguration = true; 345 containsModuleConfiguration = true;
359 break; 346 break;
347#endif
360 348
361 case "MsiAssembly": 349 case TupleDefinitionType.MsiAssembly:
362 if (OutputType.Product == output.Type) 350 if (SectionType.Product == resolvedSection.Type)
363 { 351 {
364 this.ResolveFeatures(table.Rows, 0, 1, componentsToFeatures, multipleFeatureComponents); 352 this.ResolveFeatures(tuple, 0, 1, componentsToFeatures, multipleFeatureComponents);
365 } 353 }
366 break; 354 break;
367 355
356#if MOVE_TO_BACKEND
368 case "ProgId": 357 case "ProgId":
369 // the Extension table is required with a ProgId table 358 // the Extension table is required with a ProgId table
370 this.activeOutput.EnsureTable(this.tableDefinitions["Extension"]); 359 this.activeOutput.EnsureTable(this.tableDefinitions["Extension"]);
@@ -382,42 +371,46 @@ namespace WixToolset
382 } 371 }
383 } 372 }
384 break; 373 break;
374#endif
385 375
386 case "PublishComponent": 376 case TupleDefinitionType.PublishComponent:
387 if (OutputType.Product == output.Type) 377 if (SectionType.Product == resolvedSection.Type)
388 { 378 {
389 this.ResolveFeatures(table.Rows, 2, 4, componentsToFeatures, multipleFeatureComponents); 379 this.ResolveFeatures(tuple, 2, 4, componentsToFeatures, multipleFeatureComponents);
390 } 380 }
391 break; 381 break;
392
393 case "Shortcut":
394 if (OutputType.Product == output.Type)
395 {
396 this.ResolveFeatures(table.Rows, 3, 4, componentsToFeatures, multipleFeatureComponents);
397 }
398 break;
399 382
400 case "TypeLib": 383 case TupleDefinitionType.Shortcut:
401 if (OutputType.Product == output.Type) 384 if (SectionType.Product == resolvedSection.Type)
402 { 385 {
403 this.ResolveFeatures(table.Rows, 2, 6, componentsToFeatures, multipleFeatureComponents); 386 this.ResolveFeatures(tuple, 3, 4, componentsToFeatures, multipleFeatureComponents);
404 } 387 }
405 break; 388 break;
406 389
407 case "WixAction": 390 case TupleDefinitionType.TypeLib:
408 if (this.sectionIdOnRows) 391 if (SectionType.Product == resolvedSection.Type)
409 { 392 {
410 foreach (Row row in table.Rows) 393 this.ResolveFeatures(tuple, 2, 6, componentsToFeatures, multipleFeatureComponents);
411 { 394 }
412 row.SectionId = sectionId; 395 break;
413 } 396
414 } 397#if MOVE_TO_BACKEND
415 actionRows.AddRange(table.Rows); 398 case TupleDefinitionType.WixAction:
399 //if (this.sectionIdOnRows)
400 //{
401 // foreach (Row row in table.Rows)
402 // {
403 // row.SectionId = sectionId;
404 // }
405 //}
406 actionRows.Add(tuple);
416 break; 407 break;
408#endif
417 409
410#if SOLVE_CUSTOM_TABLE
418 case "WixCustomTable": 411 case "WixCustomTable":
419 this.LinkCustomTable(table, customTableDefinitions); 412 this.LinkCustomTable(table, customTableDefinitions);
420 copyRows = false; // we've created table definitions from these rows, no need to process them any longer 413 copyTuple = false; // we've created table definitions from these rows, no need to process them any longer
421 break; 414 break;
422 415
423 case "WixCustomRow": 416 case "WixCustomRow":
@@ -426,19 +419,22 @@ namespace WixToolset
426 row.SectionId = (this.sectionIdOnRows ? sectionId : null); 419 row.SectionId = (this.sectionIdOnRows ? sectionId : null);
427 customRows.Add(row); 420 customRows.Add(row);
428 } 421 }
429 copyRows = false; 422 copyTuple = false;
430 break; 423 break;
424#endif
425
426 case TupleDefinitionType.WixEnsureTable:
427 ensureTableRows.Add(tuple);
428 break;
431 429
432 case "WixEnsureTable":
433 ensureTableRows.AddRange(table.Rows);
434 break;
435 430
431#if MOVE_TO_BACKEND
436 case "WixFile": 432 case "WixFile":
437 foreach (Row row in table.Rows) 433 foreach (Row row in table.Rows)
438 { 434 {
439 // DiskId is not valid when creating a module, so set it to 435 // DiskId is not valid when creating a module, so set it to
440 // 0 for all files to ensure proper sorting in the binder 436 // 0 for all files to ensure proper sorting in the binder
441 if (OutputType.Module == this.activeOutput.Type) 437 if (SectionType.Module == entrySection.Type)
442 { 438 {
443 row[5] = 0; 439 row[5] = 0;
444 } 440 }
@@ -450,61 +446,76 @@ namespace WixToolset
450 } 446 }
451 } 447 }
452 break; 448 break;
449#endif
453 450
454 case "WixMerge": 451 case TupleDefinitionType.WixMerge:
455 if (OutputType.Product == output.Type) 452 if (SectionType.Product == resolvedSection.Type)
456 { 453 {
457 this.ResolveFeatures(table.Rows, 0, 7, modulesToFeatures, null); 454 this.ResolveFeatures(tuple, 0, 7, modulesToFeatures, null);
458 } 455 }
459 break; 456 break;
460 457
461 case "WixSuppressAction": 458#if MOVE_TO_BACKEND
462 suppressActionRows.AddRange(table.Rows); 459 case TupleDefinitionType.WixSuppressAction:
460 suppressActionRows.Add(tuple);
463 break; 461 break;
462#endif
464 463
465 case "WixVariable": 464 case TupleDefinitionType.WixComplexReference:
466 // check for colliding values and collect the wix variable rows 465 copyTuple = false;
467 foreach (WixVariableRow row in table.Rows) 466 break;
468 { 467
469 WixVariableRow collidingRow = (WixVariableRow)wixVariables[row.Id]; 468 case TupleDefinitionType.WixSimpleReference:
469 copyTuple = false;
470 break;
470 471
471 if (null == collidingRow || (collidingRow.Overridable && !row.Overridable)) 472 case TupleDefinitionType.WixVariable:
473 // check for colliding values and collect the wix variable rows
474 {
475 var row = (WixVariableTuple)tuple;
476
477 if (wixVariables.TryGetValue(row.WixVariable, out var collidingRow))
478 {
479 if (collidingRow.Overridable && !row.Overridable)
472 { 480 {
473 wixVariables[row.Id] = row; 481 wixVariables[row.WixVariable] = row;
474 } 482 }
475 else if (!row.Overridable || (collidingRow.Overridable && row.Overridable)) 483 else if (!row.Overridable || (collidingRow.Overridable && row.Overridable))
476 { 484 {
477 this.OnMessage(WixErrors.WixVariableCollision(row.SourceLineNumbers, row.Id)); 485 this.OnMessage(WixErrors.WixVariableCollision(row.SourceLineNumbers, row.WixVariable));
478 } 486 }
479 } 487 }
480 copyRows = false; 488 else
481 break; 489 {
482 } 490 wixVariables.Add(row.WixVariable, row);
491 }
492 }
483 493
484 if (copyRows) 494 copyTuple = false;
485 { 495 break;
486 Table outputTable = this.activeOutput.EnsureTable(this.tableDefinitions[table.Name]); 496 }
487 this.CopyTableRowsToOutputTable(table, outputTable, sectionId); 497
488 } 498 if (copyTuple)
499 {
500 resolvedSection.Tuples.Add(tuple);
489 } 501 }
490 } 502 }
503 }
491 504
492 // copy the module to feature connections into the output 505 // copy the module to feature connections into the output
493 if (0 < modulesToFeatures.Count) 506 foreach (ConnectToFeature connectToFeature in modulesToFeatures)
507 {
508 foreach (var feature in connectToFeature.ConnectFeatures)
494 { 509 {
495 Table wixFeatureModulesTable = this.activeOutput.EnsureTable(this.tableDefinitions["WixFeatureModules"]); 510 var row = new WixFeatureModulesTuple();
511 row.Feature_ = feature;
512 row.WixMerge_ = connectToFeature.ChildId;
496 513
497 foreach (ConnectToFeature connectToFeature in modulesToFeatures) 514 resolvedSection.Tuples.Add(row);
498 {
499 foreach (string feature in connectToFeature.ConnectFeatures)
500 {
501 Row row = wixFeatureModulesTable.CreateRow(null);
502 row[0] = feature;
503 row[1] = connectToFeature.ChildId;
504 }
505 }
506 } 515 }
516 }
507 517
518#if MOVE_TO_BACKEND
508 // ensure the creation of tables that need to exist 519 // ensure the creation of tables that need to exist
509 if (0 < ensureTableRows.Count) 520 if (0 < ensureTableRows.Count)
510 { 521 {
@@ -525,17 +536,14 @@ namespace WixToolset
525 this.activeOutput.EnsureTable(tableDef); 536 this.activeOutput.EnsureTable(tableDef);
526 } 537 }
527 } 538 }
539#endif
528 540
529 // copy all the suppress action rows to the output to suppress actions from merge modules 541#if MOVE_TO_BACKEND
530 if (0 < suppressActionRows.Count)
531 {
532 Table suppressActionTable = this.activeOutput.EnsureTable(this.tableDefinitions["WixSuppressAction"]);
533 suppressActionRows.ForEach(r => suppressActionTable.Rows.Add(r));
534 }
535
536 // sequence all the actions 542 // sequence all the actions
537 this.SequenceActions(actionRows, suppressActionRows); 543 this.SequenceActions(actionRows, suppressActionRows);
544#endif
538 545
546#if MOVE_TO_BACKEND
539 // check for missing table and add them or display an error as appropriate 547 // check for missing table and add them or display an error as appropriate
540 switch (this.activeOutput.Type) 548 switch (this.activeOutput.Type)
541 { 549 {
@@ -576,7 +584,9 @@ namespace WixToolset
576 } 584 }
577 585
578 this.CheckForIllegalTables(this.activeOutput); 586 this.CheckForIllegalTables(this.activeOutput);
587#endif
579 588
589#if SOLVE_CUSTOM_TABLE
580 // add the custom row data 590 // add the custom row data
581 foreach (Row row in customRows) 591 foreach (Row row in customRows)
582 { 592 {
@@ -649,35 +659,28 @@ namespace WixToolset
649 } 659 }
650 } 660 }
651 } 661 }
662#endif
652 663
653 //correct the section Id in FeatureComponents table 664 //correct the section Id in FeatureComponents table
654 if (this.sectionIdOnRows) 665 if (this.sectionIdOnRows)
655 { 666 {
656 Hashtable componentSectionIds = new Hashtable(); 667 //var componentSectionIds = new Dictionary<string, string>();
657 Table componentTable = output.Tables["Component"]; 668
658 669 //foreach (var componentTuple in entrySection.Tuples.OfType<ComponentTuple>())
659 if (null != componentTable) 670 //{
660 { 671 // componentSectionIds.Add(componentTuple.Id.Id, componentTuple.SectionId);
661 foreach (Row componentRow in componentTable.Rows) 672 //}
662 { 673
663 componentSectionIds.Add(componentRow.Fields[0].Data.ToString(), componentRow.SectionId); 674 //foreach (var featureComponentTuple in entrySection.Tuples.OfType<FeatureComponentsTuple>())
664 } 675 //{
665 } 676 // if (componentSectionIds.TryGetValue(featureComponentTuple.Component_, out var componentSectionId))
666 677 // {
667 Table featureComponentsTable = output.Tables["FeatureComponents"]; 678 // featureComponentTuple.SectionId = componentSectionId;
668 679 // }
669 if (null != featureComponentsTable) 680 //}
670 { 681 }
671 foreach (Row featureComponentsRow in featureComponentsTable.Rows)
672 {
673 if (componentSectionIds.Contains(featureComponentsRow.Fields[1].Data.ToString()))
674 {
675 featureComponentsRow.SectionId = (string)componentSectionIds[featureComponentsRow.Fields[1].Data.ToString()];
676 }
677 }
678 }
679 }
680 682
683#if MOVE_TO_BACKEND
681 // add the ModuleSubstitution table to the ModuleIgnoreTable 684 // add the ModuleSubstitution table to the ModuleIgnoreTable
682 if (containsModuleSubstitution) 685 if (containsModuleSubstitution)
683 { 686 {
@@ -695,7 +698,9 @@ namespace WixToolset
695 Row moduleIgnoreTableRow = moduleIgnoreTableTable.CreateRow(null); 698 Row moduleIgnoreTableRow = moduleIgnoreTableTable.CreateRow(null);
696 moduleIgnoreTableRow[0] = "ModuleConfiguration"; 699 moduleIgnoreTableRow[0] = "ModuleConfiguration";
697 } 700 }
701#endif
698 702
703#if MOVE_TO_BACKEND
699 // index all the file rows 704 // index all the file rows
700 Table fileTable = this.activeOutput.Tables["File"]; 705 Table fileTable = this.activeOutput.Tables["File"];
701 RowDictionary<FileRow> indexedFileRows = (null == fileTable) ? new RowDictionary<FileRow>() : new RowDictionary<FileRow>(fileTable); 706 RowDictionary<FileRow> indexedFileRows = (null == fileTable) ? new RowDictionary<FileRow>() : new RowDictionary<FileRow>(fileTable);
@@ -740,47 +745,32 @@ namespace WixToolset
740 } 745 }
741 } 746 }
742 } 747 }
748#endif
743 749
744 // copy the wix variable rows to the output after all overriding has been accounted for. 750 // copy the wix variable rows to the output after all overriding has been accounted for.
745 if (0 < wixVariables.Count) 751 foreach (var row in wixVariables.Values)
746 { 752 {
747 Table wixVariableTable = output.EnsureTable(this.tableDefinitions["WixVariable"]); 753 resolvedSection.Tuples.Add(row);
754 }
748 755
749 foreach (WixVariableRow row in wixVariables.Values) 756 // Bundles have groups of data that must be flattened in a way different from other types.
750 { 757 this.FlattenBundleTables(resolvedSection);
751 wixVariableTable.Rows.Add(row);
752 }
753 }
754 758
755 // Bundles have groups of data that must be flattened in a way different from other types. 759 if (Messaging.Instance.EncounteredError)
756 this.FlattenBundleTables(output); 760 {
761 return null;
762 }
757 763
758 if (Messaging.Instance.EncounteredError) 764 var output = new Intermediate(resolvedSection.Id, new[] { resolvedSection }, null, null);
759 {
760 return null;
761 }
762 765
766#if MOVE_TO_BACKEND
763 this.CheckOutputConsistency(output); 767 this.CheckOutputConsistency(output);
764 768#endif
765 // inspect the output
766 InspectorCore inspectorCore = new InspectorCore();
767 foreach (InspectorExtension inspectorExtension in this.inspectorExtensions)
768 {
769 inspectorExtension.Core = inspectorCore;
770 inspectorExtension.InspectOutput(output);
771
772 // reset
773 inspectorExtension.Core = null;
774 }
775 }
776 finally
777 {
778 this.activeOutput = null;
779 }
780 769
781 return Messaging.Instance.EncounteredError ? null : output; 770 return Messaging.Instance.EncounteredError ? null : output;
782 } 771 }
783 772
773#if SOLVE_CUSTOM_TABLE
784 /// <summary> 774 /// <summary>
785 /// Links the definition of a custom table. 775 /// Links the definition of a custom table.
786 /// </summary> 776 /// </summary>
@@ -995,7 +985,9 @@ namespace WixToolset
995 customTableDefinitions.Add(customTable); 985 customTableDefinitions.Add(customTable);
996 } 986 }
997 } 987 }
988#endif
998 989
990#if MOVE_TO_BACKEND
999 /// <summary> 991 /// <summary>
1000 /// Checks for any tables in the output which are not allowed in the output type. 992 /// Checks for any tables in the output which are not allowed in the output type.
1001 /// </summary> 993 /// </summary>
@@ -1088,7 +1080,9 @@ namespace WixToolset
1088 } 1080 }
1089 } 1081 }
1090 } 1082 }
1083#endif
1091 1084
1085#if MOVE_TO_BACKEND
1092 /// <summary> 1086 /// <summary>
1093 /// Performs various consistency checks on the output. 1087 /// Performs various consistency checks on the output.
1094 /// </summary> 1088 /// </summary>
@@ -1145,30 +1139,30 @@ namespace WixToolset
1145 } 1139 }
1146 } 1140 }
1147 } 1141 }
1148 1142#endif
1149 /// <summary> 1143 /// <summary>
1150 /// Sends a message to the message delegate if there is one. 1144 /// Sends a message to the message delegate if there is one.
1151 /// </summary> 1145 /// </summary>
1152 /// <param name="mea">Message event arguments.</param> 1146 /// <param name="mea">Message event arguments.</param>
1153 public void OnMessage(MessageEventArgs e) 1147 public void OnMessage(MessageEventArgs e)
1154 { 1148 {
1155 Messaging.Instance.OnMessage(e); 1149 this.Context.Messaging.OnMessage(e);
1156 } 1150 }
1157 1151
1158 /// <summary> 1152 /// <summary>
1159 /// Load the standard action symbols. 1153 /// Load the standard action symbols.
1160 /// </summary> 1154 /// </summary>
1161 /// <param name="allSymbols">Collection of symbols.</param> 1155 /// <param name="symbols">Collection of symbols.</param>
1162 private void LoadStandardActionSymbols(IDictionary<string, Symbol> allSymbols) 1156 private void LoadStandardActionSymbols(IntermediateSection section, IDictionary<string, Symbol> symbols)
1163 { 1157 {
1164 foreach (WixActionRow actionRow in this.standardActions) 1158 foreach (var actionRow in WindowsInstallerStandard.StandardActions())
1165 { 1159 {
1166 Symbol actionSymbol = new Symbol(actionRow); 1160 var symbol = new Symbol(section, actionRow);
1167 1161
1168 // If the action's symbol has not already been defined (i.e. overriden by the user), add it now. 1162 // If the action's symbol has not already been defined (i.e. overriden by the user), add it now.
1169 if (!allSymbols.ContainsKey(actionSymbol.Name)) 1163 if (!symbols.ContainsKey(symbol.Name))
1170 { 1164 {
1171 allSymbols.Add(actionSymbol.Name, actionSymbol); 1165 symbols.Add(symbol.Name, symbol);
1172 } 1166 }
1173 } 1167 }
1174 } 1168 }
@@ -1176,186 +1170,180 @@ namespace WixToolset
1176 /// <summary> 1170 /// <summary>
1177 /// Process the complex references. 1171 /// Process the complex references.
1178 /// </summary> 1172 /// </summary>
1179 /// <param name="output">Active output to add sections to.</param> 1173 /// <param name="resolvedSection">Active section to add tuples to.</param>
1180 /// <param name="sections">Sections that are referenced during the link process.</param> 1174 /// <param name="sections">Sections that are referenced during the link process.</param>
1181 /// <param name="referencedComponents">Collection of all components referenced by complex reference.</param> 1175 /// <param name="referencedComponents">Collection of all components referenced by complex reference.</param>
1182 /// <param name="componentsToFeatures">Component to feature complex references.</param> 1176 /// <param name="componentsToFeatures">Component to feature complex references.</param>
1183 /// <param name="featuresToFeatures">Feature to feature complex references.</param> 1177 /// <param name="featuresToFeatures">Feature to feature complex references.</param>
1184 /// <param name="modulesToFeatures">Module to feature complex references.</param> 1178 /// <param name="modulesToFeatures">Module to feature complex references.</param>
1185 private void ProcessComplexReferences(Output output, IEnumerable<Section> sections, ISet<string> referencedComponents, ConnectToFeatureCollection componentsToFeatures, ConnectToFeatureCollection featuresToFeatures, ConnectToFeatureCollection modulesToFeatures) 1179 private void ProcessComplexReferences(IntermediateSection resolvedSection, IEnumerable<IntermediateSection> sections, ISet<string> referencedComponents, ConnectToFeatureCollection componentsToFeatures, ConnectToFeatureCollection featuresToFeatures, ConnectToFeatureCollection modulesToFeatures)
1186 { 1180 {
1187 Hashtable componentsToModules = new Hashtable(); 1181 Hashtable componentsToModules = new Hashtable();
1188 1182
1189 foreach (Section section in sections) 1183 foreach (var section in sections)
1190 { 1184 {
1191 Table wixComplexReferenceTable = section.Tables["WixComplexReference"]; 1185 var featureComponents = new List<FeatureComponentsTuple>();
1192 1186
1193 if (null != wixComplexReferenceTable) 1187 foreach (var wixComplexReferenceRow in section.Tuples.OfType<WixComplexReferenceTuple>())
1194 { 1188 {
1195 foreach (WixComplexReferenceRow wixComplexReferenceRow in wixComplexReferenceTable.Rows) 1189 ConnectToFeature connection;
1190 switch (wixComplexReferenceRow.ParentType)
1196 { 1191 {
1197 ConnectToFeature connection; 1192 case ComplexReferenceParentType.Feature:
1198 switch (wixComplexReferenceRow.ParentType) 1193 switch (wixComplexReferenceRow.ChildType)
1199 { 1194 {
1200 case ComplexReferenceParentType.Feature: 1195 case ComplexReferenceChildType.Component:
1201 switch (wixComplexReferenceRow.ChildType) 1196 connection = componentsToFeatures[wixComplexReferenceRow.Child];
1202 { 1197 if (null == connection)
1203 case ComplexReferenceChildType.Component: 1198 {
1204 connection = componentsToFeatures[wixComplexReferenceRow.ChildId]; 1199 componentsToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary));
1205 if (null == connection) 1200 }
1206 { 1201 else if (wixComplexReferenceRow.IsPrimary)
1207 componentsToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentId, wixComplexReferenceRow.IsPrimary)); 1202 {
1208 } 1203 if (connection.IsExplicitPrimaryFeature)
1209 else if (wixComplexReferenceRow.IsPrimary)
1210 { 1204 {
1211 if (connection.IsExplicitPrimaryFeature) 1205 this.OnMessage(WixErrors.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), connection.PrimaryFeature ?? resolvedSection.Id));
1212 { 1206 continue;
1213 this.OnMessage(WixErrors.MultiplePrimaryReferences(section.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.ParentId, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : this.activeOutput.EntrySection.Id)));
1214 continue;
1215 }
1216 else
1217 {
1218 connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects
1219 connection.PrimaryFeature = wixComplexReferenceRow.ParentId; // set the new primary feature
1220 connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again
1221 }
1222 } 1207 }
1223 else 1208 else
1224 { 1209 {
1225 connection.ConnectFeatures.Add(wixComplexReferenceRow.ParentId); 1210 connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects
1211 connection.PrimaryFeature = wixComplexReferenceRow.Parent; // set the new primary feature
1212 connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again
1226 } 1213 }
1214 }
1215 else
1216 {
1217 connection.ConnectFeatures.Add(wixComplexReferenceRow.Parent);
1218 }
1227 1219
1228 // add a row to the FeatureComponents table 1220 // add a row to the FeatureComponents table
1229 Table featureComponentsTable = output.EnsureTable(this.tableDefinitions["FeatureComponents"]); 1221 var featureComponent = new FeatureComponentsTuple();
1230 Row row = featureComponentsTable.CreateRow(null); 1222 featureComponent.Feature_ = wixComplexReferenceRow.Parent;
1231 if (this.sectionIdOnRows) 1223 featureComponent.Component_ = wixComplexReferenceRow.Child;
1232 {
1233 row.SectionId = section.Id;
1234 }
1235 row[0] = wixComplexReferenceRow.ParentId;
1236 row[1] = wixComplexReferenceRow.ChildId;
1237 1224
1238 // index the component for finding orphaned records 1225 featureComponents.Add(featureComponent);
1239 string symbolName = String.Concat("Component:", wixComplexReferenceRow.ChildId);
1240 referencedComponents.Add(symbolName);
1241 1226
1242 break; 1227 // index the component for finding orphaned records
1228 var symbolName = String.Concat("Component:", wixComplexReferenceRow.Child);
1229 referencedComponents.Add(symbolName);
1243 1230
1244 case ComplexReferenceChildType.Feature: 1231 break;
1245 connection = featuresToFeatures[wixComplexReferenceRow.ChildId];
1246 if (null != connection)
1247 {
1248 this.OnMessage(WixErrors.MultiplePrimaryReferences(section.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.ParentId, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : this.activeOutput.EntrySection.Id)));
1249 continue;
1250 }
1251 1232
1252 featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentId, wixComplexReferenceRow.IsPrimary)); 1233 case ComplexReferenceChildType.Feature:
1253 break; 1234 connection = featuresToFeatures[wixComplexReferenceRow.Child];
1235 if (null != connection)
1236 {
1237 this.OnMessage(WixErrors.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
1238 continue;
1239 }
1254 1240
1255 case ComplexReferenceChildType.Module: 1241 featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary));
1256 connection = modulesToFeatures[wixComplexReferenceRow.ChildId]; 1242 break;
1257 if (null == connection) 1243
1258 { 1244 case ComplexReferenceChildType.Module:
1259 modulesToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentId, wixComplexReferenceRow.IsPrimary)); 1245 connection = modulesToFeatures[wixComplexReferenceRow.Child];
1260 } 1246 if (null == connection)
1261 else if (wixComplexReferenceRow.IsPrimary) 1247 {
1248 modulesToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary));
1249 }
1250 else if (wixComplexReferenceRow.IsPrimary)
1251 {
1252 if (connection.IsExplicitPrimaryFeature)
1262 { 1253 {
1263 if (connection.IsExplicitPrimaryFeature) 1254 this.OnMessage(WixErrors.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
1264 { 1255 continue;
1265 this.OnMessage(WixErrors.MultiplePrimaryReferences(section.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.ParentId, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : this.activeOutput.EntrySection.Id)));
1266 continue;
1267 }
1268 else
1269 {
1270 connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects
1271 connection.PrimaryFeature = wixComplexReferenceRow.ParentId; // set the new primary feature
1272 connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again
1273 }
1274 } 1256 }
1275 else 1257 else
1276 { 1258 {
1277 connection.ConnectFeatures.Add(wixComplexReferenceRow.ParentId); 1259 connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects
1260 connection.PrimaryFeature = wixComplexReferenceRow.Parent; // set the new primary feature
1261 connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again
1278 } 1262 }
1279 break; 1263 }
1264 else
1265 {
1266 connection.ConnectFeatures.Add(wixComplexReferenceRow.Parent);
1267 }
1268 break;
1280 1269
1281 default: 1270 default:
1282 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); 1271 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
1283 } 1272 }
1284 break; 1273 break;
1285 1274
1286 case ComplexReferenceParentType.Module: 1275 case ComplexReferenceParentType.Module:
1287 switch (wixComplexReferenceRow.ChildType) 1276 switch (wixComplexReferenceRow.ChildType)
1288 { 1277 {
1289 case ComplexReferenceChildType.Component: 1278 case ComplexReferenceChildType.Component:
1290 if (componentsToModules.ContainsKey(wixComplexReferenceRow.ChildId)) 1279 if (componentsToModules.ContainsKey(wixComplexReferenceRow.Child))
1291 { 1280 {
1292 this.OnMessage(WixErrors.ComponentReferencedTwice(section.SourceLineNumbers, wixComplexReferenceRow.ChildId)); 1281 this.OnMessage(WixErrors.ComponentReferencedTwice(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.Child));
1293 continue; 1282 continue;
1294 } 1283 }
1295 else 1284 else
1296 { 1285 {
1297 componentsToModules.Add(wixComplexReferenceRow.ChildId, wixComplexReferenceRow); // should always be new 1286 componentsToModules.Add(wixComplexReferenceRow.Child, wixComplexReferenceRow); // should always be new
1298 1287
1299 // add a row to the ModuleComponents table 1288 // add a row to the ModuleComponents table
1300 Table moduleComponentsTable = output.EnsureTable(this.tableDefinitions["ModuleComponents"]); 1289 var moduleComponent = new ModuleComponentsTuple();
1301 Row row = moduleComponentsTable.CreateRow(null); 1290 moduleComponent.Component = wixComplexReferenceRow.Child;
1302 if (this.sectionIdOnRows) 1291 moduleComponent.ModuleID = wixComplexReferenceRow.Parent;
1303 { 1292 moduleComponent.Language = Convert.ToInt32(wixComplexReferenceRow.ParentLanguage);
1304 row.SectionId = section.Id; 1293 }
1305 }
1306 row[0] = wixComplexReferenceRow.ChildId;
1307 row[1] = wixComplexReferenceRow.ParentId;
1308 row[2] = wixComplexReferenceRow.ParentLanguage;
1309 }
1310 1294
1311 // index the component for finding orphaned records 1295 // index the component for finding orphaned records
1312 string componentSymbolName = String.Concat("Component:", wixComplexReferenceRow.ChildId); 1296 string componentSymbolName = String.Concat("Component:", wixComplexReferenceRow.Child);
1313 referencedComponents.Add(componentSymbolName); 1297 referencedComponents.Add(componentSymbolName);
1314 1298
1315 break; 1299 break;
1316 1300
1317 default: 1301 default:
1318 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); 1302 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
1319 } 1303 }
1320 break; 1304 break;
1321 1305
1322 case ComplexReferenceParentType.Patch: 1306 case ComplexReferenceParentType.Patch:
1323 switch (wixComplexReferenceRow.ChildType) 1307 switch (wixComplexReferenceRow.ChildType)
1324 { 1308 {
1325 case ComplexReferenceChildType.PatchFamily: 1309 case ComplexReferenceChildType.PatchFamily:
1326 case ComplexReferenceChildType.PatchFamilyGroup: 1310 case ComplexReferenceChildType.PatchFamilyGroup:
1327 break; 1311 break;
1328 1312
1329 default: 1313 default:
1330 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); 1314 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
1331 } 1315 }
1332 break; 1316 break;
1333 1317
1334 case ComplexReferenceParentType.Product: 1318 case ComplexReferenceParentType.Product:
1335 switch (wixComplexReferenceRow.ChildType) 1319 switch (wixComplexReferenceRow.ChildType)
1336 { 1320 {
1337 case ComplexReferenceChildType.Feature: 1321 case ComplexReferenceChildType.Feature:
1338 connection = featuresToFeatures[wixComplexReferenceRow.ChildId]; 1322 connection = featuresToFeatures[wixComplexReferenceRow.Child];
1339 if (null != connection) 1323 if (null != connection)
1340 { 1324 {
1341 this.OnMessage(WixErrors.MultiplePrimaryReferences(section.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.ParentId, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : this.activeOutput.EntrySection.Id))); 1325 this.OnMessage(WixErrors.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
1342 continue; 1326 continue;
1343 } 1327 }
1344 1328
1345 featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.ChildId, null, wixComplexReferenceRow.IsPrimary)); 1329 featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, null, wixComplexReferenceRow.IsPrimary));
1346 break; 1330 break;
1347 1331
1348 default: 1332 default:
1349 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); 1333 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
1350 } 1334 }
1351 break; 1335 break;
1352 1336
1353 default: 1337 default:
1354 // Note: Groups have been processed before getting here so they are not handled by any case above. 1338 // Note: Groups have been processed before getting here so they are not handled by any case above.
1355 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceParentType), wixComplexReferenceRow.ParentType))); 1339 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceParentType), wixComplexReferenceRow.ParentType)));
1356 }
1357 } 1340 }
1358 } 1341 }
1342
1343 foreach (var featureComponent in featureComponents)
1344 {
1345 section.Tuples.Add(featureComponent);
1346 }
1359 } 1347 }
1360 } 1348 }
1361 1349
@@ -1363,11 +1351,11 @@ namespace WixToolset
1363 /// Flattens all complex references in all sections in the collection. 1351 /// Flattens all complex references in all sections in the collection.
1364 /// </summary> 1352 /// </summary>
1365 /// <param name="sections">Sections that are referenced during the link process.</param> 1353 /// <param name="sections">Sections that are referenced during the link process.</param>
1366 private void FlattenSectionsComplexReferences(IEnumerable<Section> sections) 1354 private void FlattenSectionsComplexReferences(IEnumerable<IntermediateSection> sections)
1367 { 1355 {
1368 Hashtable parentGroups = new Hashtable(); 1356 var parentGroups = new Dictionary<string, List<WixComplexReferenceTuple>>();
1369 Hashtable parentGroupsSections = new Hashtable(); 1357 var parentGroupsSections = new Dictionary<string, IntermediateSection>();
1370 Hashtable parentGroupsNeedingProcessing = new Hashtable(); 1358 var parentGroupsNeedingProcessing = new Dictionary<string, IntermediateSection>();
1371 1359
1372 // DisplaySectionComplexReferences("--- section's complex references before flattening ---", sections); 1360 // DisplaySectionComplexReferences("--- section's complex references before flattening ---", sections);
1373 1361
@@ -1376,69 +1364,60 @@ namespace WixToolset
1376 // parents" of Features, Modules, and, of course, Groups. These references 1364 // parents" of Features, Modules, and, of course, Groups. These references
1377 // that participate in a "grouping parent" will be removed from their section 1365 // that participate in a "grouping parent" will be removed from their section
1378 // now and after processing added back in Step 3 below. 1366 // now and after processing added back in Step 3 below.
1379 foreach (Section section in sections) 1367 foreach (var section in sections)
1380 { 1368 {
1381 Table wixComplexReferenceTable = section.Tables["WixComplexReference"]; 1369 // Count down because we'll sometimes remove items from the list.
1382 1370 for (int i = section.Tuples.Count - 1; i >= 0; --i)
1383 if (null != wixComplexReferenceTable)
1384 { 1371 {
1385 // Count down because we'll sometimes remove items from the list. 1372 // Only process the "grouping parents" such as FeatureGroup, ComponentGroup, Feature,
1386 for (int i = wixComplexReferenceTable.Rows.Count - 1; i >= 0; --i) 1373 // and Module. Non-grouping complex references are simple and
1374 // resolved during normal complex reference resolutions.
1375 if (section.Tuples[i] is WixComplexReferenceTuple wixComplexReferenceRow &&
1376 (ComplexReferenceParentType.FeatureGroup == wixComplexReferenceRow.ParentType ||
1377 ComplexReferenceParentType.ComponentGroup == wixComplexReferenceRow.ParentType ||
1378 ComplexReferenceParentType.Feature == wixComplexReferenceRow.ParentType ||
1379 ComplexReferenceParentType.Module == wixComplexReferenceRow.ParentType ||
1380 ComplexReferenceParentType.PatchFamilyGroup == wixComplexReferenceRow.ParentType ||
1381 ComplexReferenceParentType.Product == wixComplexReferenceRow.ParentType))
1387 { 1382 {
1388 WixComplexReferenceRow wixComplexReferenceRow = (WixComplexReferenceRow)wixComplexReferenceTable.Rows[i]; 1383 var parentTypeAndId = CombineTypeAndId(wixComplexReferenceRow.ParentType, wixComplexReferenceRow.Parent);
1389 1384
1390 // Only process the "grouping parents" such as FeatureGroup, ComponentGroup, Feature, 1385 // Group all complex references with a common parent
1391 // and Module. Non-grouping complex references are simple and 1386 // together so we can find them quickly while processing in
1392 // resolved during normal complex reference resolutions. 1387 // Step 2.
1393 if (ComplexReferenceParentType.FeatureGroup == wixComplexReferenceRow.ParentType || 1388 if (!parentGroups.TryGetValue(parentTypeAndId, out var childrenComplexRefs))
1394 ComplexReferenceParentType.ComponentGroup == wixComplexReferenceRow.ParentType ||
1395 ComplexReferenceParentType.Feature == wixComplexReferenceRow.ParentType ||
1396 ComplexReferenceParentType.Module == wixComplexReferenceRow.ParentType ||
1397 ComplexReferenceParentType.PatchFamilyGroup == wixComplexReferenceRow.ParentType ||
1398 ComplexReferenceParentType.Product == wixComplexReferenceRow.ParentType)
1399 { 1389 {
1400 string parentTypeAndId = CombineTypeAndId(wixComplexReferenceRow.ParentType, wixComplexReferenceRow.ParentId); 1390 childrenComplexRefs = new List<WixComplexReferenceTuple>();
1391 parentGroups.Add(parentTypeAndId, childrenComplexRefs);
1392 }
1401 1393
1402 // Group all complex references with a common parent 1394 childrenComplexRefs.Add(wixComplexReferenceRow);
1403 // together so we can find them quickly while processing in 1395 section.Tuples.RemoveAt(i);
1404 // Step 2.
1405 ArrayList childrenComplexRefs = parentGroups[parentTypeAndId] as ArrayList;
1406 if (null == childrenComplexRefs)
1407 {
1408 childrenComplexRefs = new ArrayList();
1409 parentGroups.Add(parentTypeAndId, childrenComplexRefs);
1410 }
1411 1396
1412 childrenComplexRefs.Add(wixComplexReferenceRow); 1397 // Remember the mapping from set of complex references with a common
1413 wixComplexReferenceTable.Rows.RemoveAt(i); 1398 // parent to their section. We'll need this to add them back to the
1399 // correct section in Step 3.
1400 if (!parentGroupsSections.TryGetValue(parentTypeAndId, out var parentSection))
1401 {
1402 parentGroupsSections.Add(parentTypeAndId, section);
1403 }
1414 1404
1415 // Remember the mapping from set of complex references with a common 1405 // If the child of the complex reference is another group, then in Step 2
1416 // parent to their section. We'll need this to add them back to the 1406 // we're going to have to process this complex reference again to copy
1417 // correct section in Step 3. 1407 // the child group's references into the parent group.
1418 Section parentSection = parentGroupsSections[parentTypeAndId] as Section; 1408 if ((ComplexReferenceChildType.ComponentGroup == wixComplexReferenceRow.ChildType) ||
1419 if (null == parentSection) 1409 (ComplexReferenceChildType.FeatureGroup == wixComplexReferenceRow.ChildType) ||
1420 { 1410 (ComplexReferenceChildType.PatchFamilyGroup == wixComplexReferenceRow.ChildType))
1421 parentGroupsSections.Add(parentTypeAndId, section); 1411 {
1422 } 1412 if (!parentGroupsNeedingProcessing.ContainsKey(parentTypeAndId))
1423 // Debug.Assert(section == (Section)parentGroupsSections[parentTypeAndId]);
1424
1425 // If the child of the complex reference is another group, then in Step 2
1426 // we're going to have to process this complex reference again to copy
1427 // the child group's references into the parent group.
1428 if ((ComplexReferenceChildType.ComponentGroup == wixComplexReferenceRow.ChildType) ||
1429 (ComplexReferenceChildType.FeatureGroup == wixComplexReferenceRow.ChildType) ||
1430 (ComplexReferenceChildType.PatchFamilyGroup == wixComplexReferenceRow.ChildType))
1431 { 1413 {
1432 if (!parentGroupsNeedingProcessing.ContainsKey(parentTypeAndId)) 1414 parentGroupsNeedingProcessing.Add(parentTypeAndId, section);
1433 {
1434 parentGroupsNeedingProcessing.Add(parentTypeAndId, section);
1435 }
1436 // Debug.Assert(section == (Section)parentGroupsNeedingProcessing[parentTypeAndId]);
1437 } 1415 }
1438 } 1416 }
1439 } 1417 }
1440 } 1418 }
1441 } 1419 }
1420
1442 Debug.Assert(parentGroups.Count == parentGroupsSections.Count); 1421 Debug.Assert(parentGroups.Count == parentGroupsSections.Count);
1443 Debug.Assert(parentGroupsNeedingProcessing.Count <= parentGroups.Count); 1422 Debug.Assert(parentGroupsNeedingProcessing.Count <= parentGroups.Count);
1444 1423
@@ -1447,14 +1426,13 @@ namespace WixToolset
1447 // Step 2: Loop through the parent groups that have nested groups removing 1426 // Step 2: Loop through the parent groups that have nested groups removing
1448 // them from the hash table as they are processed. At the end of this the 1427 // them from the hash table as they are processed. At the end of this the
1449 // complex references should all be flattened. 1428 // complex references should all be flattened.
1450 string[] keys = new string[parentGroupsNeedingProcessing.Keys.Count]; 1429 var keys = parentGroupsNeedingProcessing.Keys.ToList();
1451 parentGroupsNeedingProcessing.Keys.CopyTo(keys, 0);
1452 1430
1453 foreach (string key in keys) 1431 foreach (string key in keys)
1454 { 1432 {
1455 if (parentGroupsNeedingProcessing.Contains(key)) 1433 if (parentGroupsNeedingProcessing.ContainsKey(key))
1456 { 1434 {
1457 Stack loopDetector = new Stack(); 1435 var loopDetector = new Stack<string>();
1458 this.FlattenGroup(key, loopDetector, parentGroups, parentGroupsNeedingProcessing); 1436 this.FlattenGroup(key, loopDetector, parentGroups, parentGroupsNeedingProcessing);
1459 } 1437 }
1460 else 1438 else
@@ -1468,18 +1446,17 @@ namespace WixToolset
1468 // in Step 1 and flattened in Step 2 are added to their appropriate 1446 // in Step 1 and flattened in Step 2 are added to their appropriate
1469 // section. This is where we will toss out the final no-longer-needed 1447 // section. This is where we will toss out the final no-longer-needed
1470 // groups. 1448 // groups.
1471 foreach (string parentGroup in parentGroups.Keys) 1449 foreach (var parentGroup in parentGroups.Keys)
1472 { 1450 {
1473 Section section = (Section)parentGroupsSections[parentGroup]; 1451 var section = parentGroupsSections[parentGroup];
1474 Table wixComplexReferenceTable = section.Tables["WixComplexReference"];
1475 1452
1476 foreach (WixComplexReferenceRow wixComplexReferenceRow in (ArrayList)parentGroups[parentGroup]) 1453 foreach (var wixComplexReferenceRow in parentGroups[parentGroup])
1477 { 1454 {
1478 if ((ComplexReferenceParentType.FeatureGroup != wixComplexReferenceRow.ParentType) && 1455 if ((ComplexReferenceParentType.FeatureGroup != wixComplexReferenceRow.ParentType) &&
1479 (ComplexReferenceParentType.ComponentGroup != wixComplexReferenceRow.ParentType) && 1456 (ComplexReferenceParentType.ComponentGroup != wixComplexReferenceRow.ParentType) &&
1480 (ComplexReferenceParentType.PatchFamilyGroup != wixComplexReferenceRow.ParentType)) 1457 (ComplexReferenceParentType.PatchFamilyGroup != wixComplexReferenceRow.ParentType))
1481 { 1458 {
1482 wixComplexReferenceTable.Rows.Add(wixComplexReferenceRow); 1459 section.Tuples.Add(wixComplexReferenceRow);
1483 } 1460 }
1484 } 1461 }
1485 } 1462 }
@@ -1504,46 +1481,39 @@ namespace WixToolset
1504 /// <param name="loopDetector">Stack of groups processed thus far. Used to detect loops.</param> 1481 /// <param name="loopDetector">Stack of groups processed thus far. Used to detect loops.</param>
1505 /// <param name="parentGroups">Hash table of complex references grouped by parent id.</param> 1482 /// <param name="parentGroups">Hash table of complex references grouped by parent id.</param>
1506 /// <param name="parentGroupsNeedingProcessing">Hash table of parent groups that still have nested groups that need to be flattened.</param> 1483 /// <param name="parentGroupsNeedingProcessing">Hash table of parent groups that still have nested groups that need to be flattened.</param>
1507 private void FlattenGroup(string parentTypeAndId, Stack loopDetector, Hashtable parentGroups, Hashtable parentGroupsNeedingProcessing) 1484 private void FlattenGroup(string parentTypeAndId, Stack<string> loopDetector, Dictionary<string, List<WixComplexReferenceTuple>> parentGroups, Dictionary<string, IntermediateSection> parentGroupsNeedingProcessing)
1508 { 1485 {
1509 Debug.Assert(parentGroupsNeedingProcessing.Contains(parentTypeAndId)); 1486 Debug.Assert(parentGroupsNeedingProcessing.ContainsKey(parentTypeAndId));
1510 loopDetector.Push(parentTypeAndId); // push this complex reference parent identfier into the stack for loop verifying 1487 loopDetector.Push(parentTypeAndId); // push this complex reference parent identfier into the stack for loop verifying
1511 1488
1512 ArrayList allNewChildComplexReferences = new ArrayList(); 1489 var allNewChildComplexReferences = new List<WixComplexReferenceTuple>();
1513 ArrayList referencesToParent = (ArrayList)parentGroups[parentTypeAndId]; 1490
1514 foreach (WixComplexReferenceRow wixComplexReferenceRow in referencesToParent) 1491 var referencesToParent = parentGroups[parentTypeAndId];
1492 foreach (var wixComplexReferenceRow in referencesToParent)
1515 { 1493 {
1516 Debug.Assert(ComplexReferenceParentType.ComponentGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.FeatureGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Feature == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Module == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Product == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.PatchFamilyGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Patch == wixComplexReferenceRow.ParentType); 1494 Debug.Assert(ComplexReferenceParentType.ComponentGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.FeatureGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Feature == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Module == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Product == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.PatchFamilyGroup == wixComplexReferenceRow.ParentType || ComplexReferenceParentType.Patch == wixComplexReferenceRow.ParentType);
1517 Debug.Assert(parentTypeAndId == CombineTypeAndId(wixComplexReferenceRow.ParentType, wixComplexReferenceRow.ParentId)); 1495 Debug.Assert(parentTypeAndId == CombineTypeAndId(wixComplexReferenceRow.ParentType, wixComplexReferenceRow.Parent));
1518 1496
1519 // We are only interested processing when the child is a group. 1497 // We are only interested processing when the child is a group.
1520 if ((ComplexReferenceChildType.ComponentGroup == wixComplexReferenceRow.ChildType) || 1498 if ((ComplexReferenceChildType.ComponentGroup == wixComplexReferenceRow.ChildType) ||
1521 (ComplexReferenceChildType.FeatureGroup == wixComplexReferenceRow.ChildType) || 1499 (ComplexReferenceChildType.FeatureGroup == wixComplexReferenceRow.ChildType) ||
1522 (ComplexReferenceChildType.PatchFamilyGroup == wixComplexReferenceRow.ChildType)) 1500 (ComplexReferenceChildType.PatchFamilyGroup == wixComplexReferenceRow.ChildType))
1523 { 1501 {
1524 string childTypeAndId = CombineTypeAndId(wixComplexReferenceRow.ChildType, wixComplexReferenceRow.ChildId); 1502 string childTypeAndId = CombineTypeAndId(wixComplexReferenceRow.ChildType, wixComplexReferenceRow.Child);
1525 if (loopDetector.Contains(childTypeAndId)) 1503 if (loopDetector.Contains(childTypeAndId))
1526 { 1504 {
1527 // Create a comma delimited list of the references that participate in the 1505 // Create a comma delimited list of the references that participate in the
1528 // loop for the error message. Start at the bottom of the stack and work the 1506 // loop for the error message. Start at the bottom of the stack and work the
1529 // way up to present the loop as a directed graph. 1507 // way up to present the loop as a directed graph.
1530 object[] stack = loopDetector.ToArray(); 1508 var loop = String.Join(" -> ", loopDetector);
1531 StringBuilder loop = new StringBuilder();
1532 for (int i = stack.Length - 1; i >= 0; --i)
1533 {
1534 loop.Append((string)stack[i]);
1535 if (0 < i)
1536 {
1537 loop.Append(" -> ");
1538 }
1539 }
1540 1509
1541 this.OnMessage(WixErrors.ReferenceLoopDetected(wixComplexReferenceRow.Table.Section == null ? null : wixComplexReferenceRow.Table.Section.SourceLineNumbers, loop.ToString())); 1510 this.OnMessage(WixErrors.ReferenceLoopDetected(wixComplexReferenceRow?.SourceLineNumbers, loop));
1542 1511
1543 // Cleanup the parentGroupsNeedingProcessing and the loopDetector just like the 1512 // Cleanup the parentGroupsNeedingProcessing and the loopDetector just like the
1544 // exit of this method does at the end because we are exiting early. 1513 // exit of this method does at the end because we are exiting early.
1545 loopDetector.Pop(); 1514 loopDetector.Pop();
1546 parentGroupsNeedingProcessing.Remove(parentTypeAndId); 1515 parentGroupsNeedingProcessing.Remove(parentTypeAndId);
1516
1547 return; // bail 1517 return; // bail
1548 } 1518 }
1549 1519
@@ -1560,10 +1530,9 @@ namespace WixToolset
1560 // complex reference (because we're moving references up the tree), and finally 1530 // complex reference (because we're moving references up the tree), and finally
1561 // add the cloned child's complex reference to the list of complex references 1531 // add the cloned child's complex reference to the list of complex references
1562 // that we'll eventually add to the parent group. 1532 // that we'll eventually add to the parent group.
1563 ArrayList referencesToChild = (ArrayList)parentGroups[childTypeAndId]; 1533 if (parentGroups.TryGetValue(childTypeAndId, out var referencesToChild))
1564 if (null != referencesToChild)
1565 { 1534 {
1566 foreach (WixComplexReferenceRow crefChild in referencesToChild) 1535 foreach (var crefChild in referencesToChild)
1567 { 1536 {
1568 // Only merge up the non-group items since groups are purged 1537 // Only merge up the non-group items since groups are purged
1569 // after this part of the processing anyway (cloning them would 1538 // after this part of the processing anyway (cloning them would
@@ -1572,8 +1541,8 @@ namespace WixToolset
1572 (ComplexReferenceChildType.ComponentGroup != crefChild.ChildType) || 1541 (ComplexReferenceChildType.ComponentGroup != crefChild.ChildType) ||
1573 (ComplexReferenceChildType.PatchFamilyGroup != crefChild.ChildType)) 1542 (ComplexReferenceChildType.PatchFamilyGroup != crefChild.ChildType))
1574 { 1543 {
1575 WixComplexReferenceRow crefChildClone = crefChild.Clone(); 1544 var crefChildClone = crefChild.Clone();
1576 Debug.Assert(crefChildClone.ParentId == wixComplexReferenceRow.ChildId); 1545 Debug.Assert(crefChildClone.Parent == wixComplexReferenceRow.Child);
1577 1546
1578 crefChildClone.Reparent(wixComplexReferenceRow); 1547 crefChildClone.Reparent(wixComplexReferenceRow);
1579 allNewChildComplexReferences.Add(crefChildClone); 1548 allNewChildComplexReferences.Add(crefChildClone);
@@ -1587,10 +1556,11 @@ namespace WixToolset
1587 // group. Clean out any left over groups and quietly remove any 1556 // group. Clean out any left over groups and quietly remove any
1588 // duplicate complex references that occurred during the merge. 1557 // duplicate complex references that occurred during the merge.
1589 referencesToParent.AddRange(allNewChildComplexReferences); 1558 referencesToParent.AddRange(allNewChildComplexReferences);
1590 referencesToParent.Sort(); 1559 referencesToParent.Sort(ComplexReferenceComparision);
1591 for (int i = referencesToParent.Count - 1; i >= 0; --i) 1560 for (int i = referencesToParent.Count - 1; i >= 0; --i)
1592 { 1561 {
1593 WixComplexReferenceRow wixComplexReferenceRow = (WixComplexReferenceRow)referencesToParent[i]; 1562 var wixComplexReferenceRow = referencesToParent[i];
1563
1594 if ((ComplexReferenceChildType.FeatureGroup == wixComplexReferenceRow.ChildType) || 1564 if ((ComplexReferenceChildType.FeatureGroup == wixComplexReferenceRow.ChildType) ||
1595 (ComplexReferenceChildType.ComponentGroup == wixComplexReferenceRow.ChildType) || 1565 (ComplexReferenceChildType.ComponentGroup == wixComplexReferenceRow.ChildType) ||
1596 (ComplexReferenceChildType.PatchFamilyGroup == wixComplexReferenceRow.ChildType)) 1566 (ComplexReferenceChildType.PatchFamilyGroup == wixComplexReferenceRow.ChildType))
@@ -1602,7 +1572,7 @@ namespace WixToolset
1602 // Since the list is already sorted, we can find duplicates by simply 1572 // Since the list is already sorted, we can find duplicates by simply
1603 // looking at the next sibling in the list and tossing out one if they 1573 // looking at the next sibling in the list and tossing out one if they
1604 // match. 1574 // match.
1605 WixComplexReferenceRow crefCompare = (WixComplexReferenceRow)referencesToParent[i - 1]; 1575 var crefCompare = referencesToParent[i - 1];
1606 if (0 == wixComplexReferenceRow.CompareToWithoutConsideringPrimary(crefCompare)) 1576 if (0 == wixComplexReferenceRow.CompareToWithoutConsideringPrimary(crefCompare))
1607 { 1577 {
1608 referencesToParent.RemoveAt(i); 1578 referencesToParent.RemoveAt(i);
@@ -1610,6 +1580,29 @@ namespace WixToolset
1610 } 1580 }
1611 } 1581 }
1612 1582
1583 int ComplexReferenceComparision(WixComplexReferenceTuple x, WixComplexReferenceTuple y)
1584 {
1585 var comparison = x.ChildType - y.ChildType;
1586 if (0 == comparison)
1587 {
1588 comparison = String.Compare(x.Child, y.Child, StringComparison.Ordinal);
1589 if (0 == comparison)
1590 {
1591 comparison = x.ParentType - y.ParentType;
1592 if (0 == comparison)
1593 {
1594 comparison = String.Compare(x.ParentLanguage ?? String.Empty, y.ParentLanguage ?? String.Empty, StringComparison.Ordinal);
1595 if (0 == comparison)
1596 {
1597 comparison = String.Compare(x.Parent, y.Parent, StringComparison.Ordinal);
1598 }
1599 }
1600 }
1601 }
1602
1603 return comparison;
1604 }
1605
1613 loopDetector.Pop(); // pop this complex reference off the stack since we're done verify the loop here 1606 loopDetector.Pop(); // pop this complex reference off the stack since we're done verify the loop here
1614 parentGroupsNeedingProcessing.Remove(parentTypeAndId); // remove the newly processed complex reference 1607 parentGroupsNeedingProcessing.Remove(parentTypeAndId); // remove the newly processed complex reference
1615 } 1608 }
@@ -1639,9 +1632,9 @@ namespace WixToolset
1639 /// Flattens the tables used in a Bundle. 1632 /// Flattens the tables used in a Bundle.
1640 /// </summary> 1633 /// </summary>
1641 /// <param name="output">Output containing the tables to process.</param> 1634 /// <param name="output">Output containing the tables to process.</param>
1642 private void FlattenBundleTables(Output output) 1635 private void FlattenBundleTables(IntermediateSection entrySection)
1643 { 1636 {
1644 if (OutputType.Bundle != output.Type) 1637 if (SectionType.Bundle != entrySection.Type)
1645 { 1638 {
1646 return; 1639 return;
1647 } 1640 }
@@ -1651,7 +1644,7 @@ namespace WixToolset
1651 // will hold Payloads under UX, ChainPackages (references?) under Chain, 1644 // will hold Payloads under UX, ChainPackages (references?) under Chain,
1652 // and ChainPackages/Payloads under the attached and any detatched 1645 // and ChainPackages/Payloads under the attached and any detatched
1653 // Containers. 1646 // Containers.
1654 WixGroupingOrdering groups = new WixGroupingOrdering(output, this); 1647 var groups = new WixGroupingOrdering(entrySection, this);
1655 1648
1656 // Create UX payloads and Package payloads 1649 // Create UX payloads and Package payloads
1657 groups.UseTypes(new string[] { "Container", "Layout", "PackageGroup", "PayloadGroup", "Package" }, new string[] { "PackageGroup", "Package", "PayloadGroup", "Payload" }); 1650 groups.UseTypes(new string[] { "Container", "Layout", "PackageGroup", "PayloadGroup", "Package" }, new string[] { "PackageGroup", "Package", "PayloadGroup", "Payload" });
@@ -1675,21 +1668,21 @@ namespace WixToolset
1675 { 1668 {
1676 foreach (ConnectToFeature connection in featuresToFeatures) 1669 foreach (ConnectToFeature connection in featuresToFeatures)
1677 { 1670 {
1678 WixSimpleReferenceRow wixSimpleReferenceRow = new WixSimpleReferenceRow(null, this.tableDefinitions["WixSimpleReference"]); 1671 var wixSimpleReferenceRow = new WixSimpleReferenceTuple();
1679 wixSimpleReferenceRow.TableName = "Feature"; 1672 wixSimpleReferenceRow.Table = "Feature";
1680 wixSimpleReferenceRow.PrimaryKeys = connection.ChildId; 1673 wixSimpleReferenceRow.PrimaryKeys = connection.ChildId;
1681 1674
1682 Symbol symbol; 1675 if (!allSymbols.TryGetValue(wixSimpleReferenceRow.SymbolicName, out var symbol))
1683 if (!allSymbols.TryGetValue(wixSimpleReferenceRow.SymbolicName, out symbol))
1684 { 1676 {
1685 continue; 1677 continue;
1686 } 1678 }
1687 1679
1688 Row row = symbol.Row; 1680 var row = symbol.Row;
1689 row[1] = connection.PrimaryFeature; 1681 row.Set(1, connection.PrimaryFeature);
1690 } 1682 }
1691 } 1683 }
1692 1684
1685#if DEAD_CODE
1693 /// <summary> 1686 /// <summary>
1694 /// Copies a table's rows to an output table. 1687 /// Copies a table's rows to an output table.
1695 /// </summary> 1688 /// </summary>
@@ -1731,16 +1724,18 @@ namespace WixToolset
1731 outputTable.Rows.Add(row); 1724 outputTable.Rows.Add(row);
1732 } 1725 }
1733 } 1726 }
1727#endif
1734 1728
1729#if MOVE_TO_BACKEND
1735 /// <summary> 1730 /// <summary>
1736 /// Set sequence numbers for all the actions and create rows in the output object. 1731 /// Set sequence numbers for all the actions and create rows in the output object.
1737 /// </summary> 1732 /// </summary>
1738 /// <param name="actionRows">Collection of actions to schedule.</param> 1733 /// <param name="actionRows">Collection of actions to schedule.</param>
1739 /// <param name="suppressActionRows">Collection of actions to suppress.</param> 1734 /// <param name="suppressActionRows">Collection of actions to suppress.</param>
1740 private void SequenceActions(List<Row> actionRows, List<Row> suppressActionRows) 1735 private void SequenceActions(List<IntermediateTuple> actionRows, List<IntermediateTuple> suppressActionRows)
1741 { 1736 {
1742 WixActionRowCollection overridableActionRows = new WixActionRowCollection(); 1737 var overridableActionRows = new WixActionRowCollection();
1743 WixActionRowCollection requiredActionRows = new WixActionRowCollection(); 1738 var requiredActionRows = new WixActionRowCollection();
1744 ArrayList scheduledActionRows = new ArrayList(); 1739 ArrayList scheduledActionRows = new ArrayList();
1745 1740
1746 // gather the required actions for the output type 1741 // gather the required actions for the output type
@@ -2362,6 +2357,7 @@ namespace WixToolset
2362 WixActionRowCollection relatedRows = (after ? parentActionRow.NextActionRows : parentActionRow.PreviousActionRows); 2357 WixActionRowCollection relatedRows = (after ? parentActionRow.NextActionRows : parentActionRow.PreviousActionRows);
2363 relatedRows.Add(actionRow); 2358 relatedRows.Add(actionRow);
2364 } 2359 }
2360#endif
2365 2361
2366 /// <summary> 2362 /// <summary>
2367 /// Resolve features for columns that have null guid placeholders. 2363 /// Resolve features for columns that have null guid placeholders.
@@ -2371,59 +2367,55 @@ namespace WixToolset
2371 /// <param name="featureColumn">Number of the column containing the feature.</param> 2367 /// <param name="featureColumn">Number of the column containing the feature.</param>
2372 /// <param name="connectToFeatures">Connect to feature complex references.</param> 2368 /// <param name="connectToFeatures">Connect to feature complex references.</param>
2373 /// <param name="multipleFeatureComponents">Hashtable of known components under multiple features.</param> 2369 /// <param name="multipleFeatureComponents">Hashtable of known components under multiple features.</param>
2374 private void ResolveFeatures(IEnumerable<Row> rows, int connectionColumn, int featureColumn, ConnectToFeatureCollection connectToFeatures, Hashtable multipleFeatureComponents) 2370 private void ResolveFeatures(IntermediateTuple row, int connectionColumn, int featureColumn, ConnectToFeatureCollection connectToFeatures, Hashtable multipleFeatureComponents)
2375 { 2371 {
2376 foreach (Row row in rows) 2372 var connectionId = row.AsString(connectionColumn);
2373 var featureId = row.AsString(featureColumn);
2374
2375 if (emptyGuid == featureId)
2377 { 2376 {
2378 string connectionId = (string)row[connectionColumn]; 2377 ConnectToFeature connection = connectToFeatures[connectionId];
2379 string featureId = (string)row[featureColumn];
2380 2378
2381 if (emptyGuid == featureId) 2379 if (null == connection)
2382 { 2380 {
2383 ConnectToFeature connection = connectToFeatures[connectionId]; 2381 // display an error for the component or merge module as approrpriate
2384 2382 if (null != multipleFeatureComponents)
2385 if (null == connection)
2386 { 2383 {
2387 // display an error for the component or merge module as approrpriate 2384 this.OnMessage(WixErrors.ComponentExpectedFeature(row.SourceLineNumbers, connectionId, row.Definition.Name, row.Id.Id));
2388 if (null != multipleFeatureComponents)
2389 {
2390 this.OnMessage(WixErrors.ComponentExpectedFeature(row.SourceLineNumbers, connectionId, row.Table.Name, row.GetPrimaryKey('/')));
2391 }
2392 else
2393 {
2394 this.OnMessage(WixErrors.MergeModuleExpectedFeature(row.SourceLineNumbers, connectionId));
2395 }
2396 } 2385 }
2397 else 2386 else
2398 { 2387 {
2399 // check for unique, implicit, primary feature parents with multiple possible parent features 2388 this.OnMessage(WixErrors.MergeModuleExpectedFeature(row.SourceLineNumbers, connectionId));
2400 if (this.ShowPedanticMessages && 2389 }
2401 !connection.IsExplicitPrimaryFeature && 2390 }
2402 0 < connection.ConnectFeatures.Count) 2391 else
2392 {
2393 // check for unique, implicit, primary feature parents with multiple possible parent features
2394 if (this.ShowPedanticMessages &&
2395 !connection.IsExplicitPrimaryFeature &&
2396 0 < connection.ConnectFeatures.Count)
2397 {
2398 // display a warning for the component or merge module as approrpriate
2399 if (null != multipleFeatureComponents)
2403 { 2400 {
2404 // display a warning for the component or merge module as approrpriate 2401 if (!multipleFeatureComponents.Contains(connectionId))
2405 if (null != multipleFeatureComponents)
2406 { 2402 {
2407 if (!multipleFeatureComponents.Contains(connectionId)) 2403 this.OnMessage(WixWarnings.ImplicitComponentPrimaryFeature(connectionId));
2408 {
2409 this.OnMessage(WixWarnings.ImplicitComponentPrimaryFeature(connectionId));
2410 2404
2411 // remember this component so only one warning is generated for it 2405 // remember this component so only one warning is generated for it
2412 multipleFeatureComponents[connectionId] = null; 2406 multipleFeatureComponents[connectionId] = null;
2413 }
2414 }
2415 else
2416 {
2417 this.OnMessage(WixWarnings.ImplicitMergeModulePrimaryFeature(connectionId));
2418 } 2407 }
2419 } 2408 }
2420 2409 else
2421 // set the feature 2410 {
2422 row[featureColumn] = connection.PrimaryFeature; 2411 this.OnMessage(WixWarnings.ImplicitMergeModulePrimaryFeature(connectionId));
2412 }
2423 } 2413 }
2414
2415 // set the feature
2416 row.Set(featureColumn, connection.PrimaryFeature);
2424 } 2417 }
2425 } 2418 }
2426 } 2419 }
2427
2428 } 2420 }
2429} 2421}
diff --git a/src/WixToolset.Core/Localizer.cs b/src/WixToolset.Core/Localizer.cs
index 72d0955b..a19c32fb 100644
--- a/src/WixToolset.Core/Localizer.cs
+++ b/src/WixToolset.Core/Localizer.cs
@@ -18,7 +18,7 @@ namespace WixToolset
18 public static readonly XNamespace WxlNamespace = "http://wixtoolset.org/schemas/v4/wxl"; 18 public static readonly XNamespace WxlNamespace = "http://wixtoolset.org/schemas/v4/wxl";
19 private static string XmlElementName = "WixLocalization"; 19 private static string XmlElementName = "WixLocalization";
20 20
21 private Dictionary<string, WixVariableRow> variables; 21 private Dictionary<string, BindVariable> variables;
22 private Dictionary<string, LocalizedControl> localizedControls; 22 private Dictionary<string, LocalizedControl> localizedControls;
23 23
24 /// <summary> 24 /// <summary>
@@ -27,7 +27,7 @@ namespace WixToolset
27 public Localizer(IEnumerable<Localization> localizations) 27 public Localizer(IEnumerable<Localization> localizations)
28 { 28 {
29 this.Codepage = -1; 29 this.Codepage = -1;
30 this.variables = new Dictionary<string, WixVariableRow>(); 30 this.variables = new Dictionary<string, BindVariable>();
31 this.localizedControls = new Dictionary<string, LocalizedControl>(); 31 this.localizedControls = new Dictionary<string, LocalizedControl>();
32 32
33 foreach (var localization in localizations) 33 foreach (var localization in localizations)
@@ -37,9 +37,9 @@ namespace WixToolset
37 this.Codepage = localization.Codepage; 37 this.Codepage = localization.Codepage;
38 } 38 }
39 39
40 foreach (WixVariableRow wixVariableRow in localization.Variables) 40 foreach (var variable in localization.Variables)
41 { 41 {
42 Localizer.AddWixVariable(this.variables, wixVariableRow); 42 Localizer.AddWixVariable(this.variables, variable);
43 } 43 }
44 44
45 foreach (KeyValuePair<string, LocalizedControl> localizedControl in localization.LocalizedControls) 45 foreach (KeyValuePair<string, LocalizedControl> localizedControl in localization.LocalizedControls)
@@ -86,7 +86,7 @@ namespace WixToolset
86 /// <param name="tableDefinitions">Collection containing TableDefinitions to use when loading the localization file.</param> 86 /// <param name="tableDefinitions">Collection containing TableDefinitions to use when loading the localization file.</param>
87 /// <param name="suppressSchema">Suppress xml schema validation while loading.</param> 87 /// <param name="suppressSchema">Suppress xml schema validation while loading.</param>
88 /// <returns>Returns the loaded localization file.</returns> 88 /// <returns>Returns the loaded localization file.</returns>
89 public static Localization ParseLocalizationFile(string path, TableDefinitionCollection tableDefinitions) 89 public static Localization ParseLocalizationFile(string path)
90 { 90 {
91 XElement root = XDocument.Load(path).Root; 91 XElement root = XDocument.Load(path).Root;
92 Localization localization = null; 92 Localization localization = null;
@@ -96,7 +96,7 @@ namespace WixToolset
96 { 96 {
97 if (Localizer.WxlNamespace == root.Name.Namespace) 97 if (Localizer.WxlNamespace == root.Name.Namespace)
98 { 98 {
99 localization = ParseWixLocalizationElement(root, tableDefinitions); 99 localization = ParseWixLocalizationElement(root);
100 } 100 }
101 else // invalid or missing namespace 101 else // invalid or missing namespace
102 { 102 {
@@ -123,7 +123,7 @@ namespace WixToolset
123 /// </summary> 123 /// </summary>
124 /// <param name="variables">Dictionary of variable rows.</param> 124 /// <param name="variables">Dictionary of variable rows.</param>
125 /// <param name="wixVariableRow">Row to add to the variables dictionary.</param> 125 /// <param name="wixVariableRow">Row to add to the variables dictionary.</param>
126 private static void AddWixVariable(IDictionary<string, WixVariableRow> variables, WixVariableRow wixVariableRow) 126 private static void AddWixVariable(IDictionary<string, BindVariable> variables, BindVariable wixVariableRow)
127 { 127 {
128 if (!variables.TryGetValue(wixVariableRow.Id, out var existingWixVariableRow) || (existingWixVariableRow.Overridable && !wixVariableRow.Overridable)) 128 if (!variables.TryGetValue(wixVariableRow.Id, out var existingWixVariableRow) || (existingWixVariableRow.Overridable && !wixVariableRow.Overridable))
129 { 129 {
@@ -139,7 +139,7 @@ namespace WixToolset
139 /// Parses the WixLocalization element. 139 /// Parses the WixLocalization element.
140 /// </summary> 140 /// </summary>
141 /// <param name="node">Element to parse.</param> 141 /// <param name="node">Element to parse.</param>
142 private static Localization ParseWixLocalizationElement(XElement node, TableDefinitionCollection tableDefinitions) 142 private static Localization ParseWixLocalizationElement(XElement node)
143 { 143 {
144 int codepage = -1; 144 int codepage = -1;
145 string culture = null; 145 string culture = null;
@@ -171,7 +171,7 @@ namespace WixToolset
171 } 171 }
172 } 172 }
173 173
174 Dictionary<string, WixVariableRow> variables = new Dictionary<string,WixVariableRow>(); 174 Dictionary<string, BindVariable> variables = new Dictionary<string, BindVariable>();
175 Dictionary<string, LocalizedControl> localizedControls = new Dictionary<string, LocalizedControl>(); 175 Dictionary<string, LocalizedControl> localizedControls = new Dictionary<string, LocalizedControl>();
176 176
177 foreach (XElement child in node.Elements()) 177 foreach (XElement child in node.Elements())
@@ -181,7 +181,7 @@ namespace WixToolset
181 switch (child.Name.LocalName) 181 switch (child.Name.LocalName)
182 { 182 {
183 case "String": 183 case "String":
184 Localizer.ParseString(child, variables, tableDefinitions); 184 Localizer.ParseString(child, variables);
185 break; 185 break;
186 186
187 case "UI": 187 case "UI":
@@ -206,7 +206,7 @@ namespace WixToolset
206 /// Parse a localization string into a WixVariableRow. 206 /// Parse a localization string into a WixVariableRow.
207 /// </summary> 207 /// </summary>
208 /// <param name="node">Element to parse.</param> 208 /// <param name="node">Element to parse.</param>
209 private static void ParseString(XElement node, IDictionary<string, WixVariableRow> variables, TableDefinitionCollection tableDefinitions) 209 private static void ParseString(XElement node, IDictionary<string, BindVariable> variables)
210 { 210 {
211 string id = null; 211 string id = null;
212 bool overridable = false; 212 bool overridable = false;
@@ -251,12 +251,15 @@ namespace WixToolset
251 251
252 if (!Messaging.Instance.EncounteredError) 252 if (!Messaging.Instance.EncounteredError)
253 { 253 {
254 WixVariableRow wixVariableRow = new WixVariableRow(sourceLineNumbers, tableDefinitions["WixVariable"]); 254 var variable = new BindVariable
255 wixVariableRow.Id = id; 255 {
256 wixVariableRow.Overridable = overridable; 256 SourceLineNumbers = sourceLineNumbers,
257 wixVariableRow.Value = value; 257 Id = id,
258 Overridable = overridable,
259 Value = value,
260 };
258 261
259 Localizer.AddWixVariable(variables, wixVariableRow); 262 Localizer.AddWixVariable(variables, variable);
260 } 263 }
261 } 264 }
262 265
diff --git a/src/WixToolset.Core/Preprocessor.cs b/src/WixToolset.Core/Preprocessor.cs
index a9fbcbb7..85b3dab8 100644
--- a/src/WixToolset.Core/Preprocessor.cs
+++ b/src/WixToolset.Core/Preprocessor.cs
@@ -38,7 +38,6 @@ namespace WixToolset
38 38
39 private List<IPreprocessorExtension> extensions; 39 private List<IPreprocessorExtension> extensions;
40 private Dictionary<string, IPreprocessorExtension> extensionsByPrefix; 40 private Dictionary<string, IPreprocessorExtension> extensionsByPrefix;
41 private List<InspectorExtension> inspectorExtensions;
42 41
43 private SourceLineNumber currentLineNumber; 42 private SourceLineNumber currentLineNumber;
44 private Stack<SourceLineNumber> sourceStack; 43 private Stack<SourceLineNumber> sourceStack;
@@ -60,7 +59,6 @@ namespace WixToolset
60 59
61 this.extensions = new List<IPreprocessorExtension>(); 60 this.extensions = new List<IPreprocessorExtension>();
62 this.extensionsByPrefix = new Dictionary<string, IPreprocessorExtension>(); 61 this.extensionsByPrefix = new Dictionary<string, IPreprocessorExtension>();
63 this.inspectorExtensions = new List<InspectorExtension>();
64 62
65 this.sourceStack = new Stack<SourceLineNumber>(); 63 this.sourceStack = new Stack<SourceLineNumber>();
66 64
@@ -201,27 +199,9 @@ namespace WixToolset
201 public XDocument Process(string sourceFile, IDictionary<string, string> variables) 199 public XDocument Process(string sourceFile, IDictionary<string, string> variables)
202 { 200 {
203 using (Stream sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read)) 201 using (Stream sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read))
202 using (XmlReader reader = XmlReader.Create(sourceFile, DocumentXmlReaderSettings))
204 { 203 {
205 InspectorCore inspectorCore = new InspectorCore(); 204 return Process(reader, variables, sourceFile);
206 foreach (InspectorExtension inspectorExtension in this.inspectorExtensions)
207 {
208 inspectorExtension.Core = inspectorCore;
209 inspectorExtension.InspectSource(sourceStream);
210
211 // reset
212 inspectorExtension.Core = null;
213 sourceStream.Position = 0;
214 }
215
216 if (inspectorCore.EncounteredError)
217 {
218 return null;
219 }
220
221 using (XmlReader reader = XmlReader.Create(sourceFile, DocumentXmlReaderSettings))
222 {
223 return Process(reader, variables, sourceFile);
224 }
225 } 205 }
226 } 206 }
227 207
diff --git a/src/WixToolset.Core/TupleDefinitionCreator.cs b/src/WixToolset.Core/TupleDefinitionCreator.cs
new file mode 100644
index 00000000..8c9b9d29
--- /dev/null
+++ b/src/WixToolset.Core/TupleDefinitionCreator.cs
@@ -0,0 +1,52 @@
1// 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.
2
3namespace WixToolset.Core
4{
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Data;
8 using WixToolset.Extensibility;
9 using WixToolset.Extensibility.Services;
10
11 internal class TupleDefinitionCreator : ITupleDefinitionCreator
12 {
13 public TupleDefinitionCreator(IServiceProvider serviceProvider)
14 {
15 this.ServiceProvider = serviceProvider;
16 }
17
18 private IServiceProvider ServiceProvider { get; }
19
20 private IEnumerable<IExtensionData> ExtensionData { get; set; }
21
22 public bool TryGetTupleDefinitionByName(string name, out IntermediateTupleDefinition tupleDefinition)
23 {
24 tupleDefinition = TupleDefinitions.ByName(name);
25
26 if (tupleDefinition == null)
27 {
28 if (this.ExtensionData == null)
29 {
30 this.LoadExtensionData();
31 }
32
33 foreach (var data in this.ExtensionData)
34 {
35 if (data.TryGetTupleDefinitionByName(name, out tupleDefinition))
36 {
37 break;
38 }
39 }
40 }
41
42 return tupleDefinition != null;
43 }
44
45 private void LoadExtensionData()
46 {
47 var extensionManager = (IExtensionManager)this.ServiceProvider.GetService(typeof(IExtensionManager));
48
49 this.ExtensionData = extensionManager.Create<IExtensionData>();
50 }
51 }
52}
diff --git a/src/WixToolset.Core/WindowsInstallerStandard.cs b/src/WixToolset.Core/WindowsInstallerStandard.cs
new file mode 100644
index 00000000..90a53e6a
--- /dev/null
+++ b/src/WixToolset.Core/WindowsInstallerStandard.cs
@@ -0,0 +1,260 @@
1// 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.
2
3namespace WixToolset.Core
4{
5 using System.Collections.Generic;
6 using WixToolset.Data;
7 using WixToolset.Data.Tuples;
8
9 internal class WindowsInstallerStandard
10 {
11 private static readonly HashSet<string> standardActionNames = new HashSet<string>
12 {
13 "AllocateRegistrySpace",
14 "AppSearch",
15 "BindImage",
16 "CCPSearch",
17 "CostFinalize",
18 "CostInitialize",
19 "CreateFolders",
20 "CreateShortcuts",
21 "DeleteServices",
22 "DisableRollback",
23 "DuplicateFiles",
24 "ExecuteAction",
25 "FileCost",
26 "FindRelatedProducts",
27 "ForceReboot",
28 "InstallAdminPackage",
29 "InstallExecute",
30 "InstallExecuteAgain",
31 "InstallFiles",
32 "InstallFinalize",
33 "InstallInitialize",
34 "InstallODBC",
35 "InstallServices",
36 "InstallSFPCatalogFile",
37 "InstallValidate",
38 "IsolateComponents",
39 "LaunchConditions",
40 "MigrateFeatureStates",
41 "MoveFiles",
42 "MsiConfigureServices",
43 "MsiPublishAssemblies",
44 "MsiUnpublishAssemblies",
45 "PatchFiles",
46 "ProcessComponents",
47 "PublishComponents",
48 "PublishFeatures",
49 "PublishProduct",
50 "RegisterClassInfo",
51 "RegisterComPlus",
52 "RegisterExtensionInfo",
53 "RegisterFonts",
54 "RegisterMIMEInfo",
55 "RegisterProduct",
56 "RegisterProgIdInfo",
57 "RegisterTypeLibraries",
58 "RegisterUser",
59 "RemoveDuplicateFiles",
60 "RemoveEnvironmentStrings",
61 "RemoveExistingProducts",
62 "RemoveFiles",
63 "RemoveFolders",
64 "RemoveIniValues",
65 "RemoveODBC",
66 "RemoveRegistryValues",
67 "RemoveShortcuts",
68 "ResolveSource",
69 "RMCCPSearch",
70 "ScheduleReboot",
71 "SelfRegModules",
72 "SelfUnregModules",
73 "SetODBCFolders",
74 "StartServices",
75 "StopServices",
76 "UnpublishComponents",
77 "UnpublishFeatures",
78 "UnregisterClassInfo",
79 "UnregisterComPlus",
80 "UnregisterExtensionInfo",
81 "UnregisterFonts",
82 "UnregisterMIMEInfo",
83 "UnregisterProgIdInfo",
84 "UnregisterTypeLibraries",
85 "ValidateProductID",
86 "WriteEnvironmentStrings",
87 "WriteIniValues",
88 "WriteRegistryValues",
89 };
90
91 private static readonly WixActionTuple[] standardActions = new[]
92 {
93 new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallInitialize", AccessModifier.Public)) { Action="InstallInitialize", Sequence=1500, SequenceTable=SequenceTable.AdminExecuteSequence },
94 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/InstallInitialize", AccessModifier.Public)) { Action="InstallInitialize", Sequence=1500, SequenceTable=SequenceTable.AdvtExecuteSequence },
95 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallInitialize", AccessModifier.Public)) { Action="InstallInitialize", Sequence=1500, SequenceTable=SequenceTable.InstallExecuteSequence },
96
97 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallExecute", AccessModifier.Public)) { Action="InstallExecute", Sequence=6500, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
98
99 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallExecuteAgain", AccessModifier.Public)) { Action="InstallExecuteAgain", Sequence=6550, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
100
101 new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallFinalize", AccessModifier.Public)) { Action="InstallFinalize", Sequence=6600, SequenceTable=SequenceTable.AdminExecuteSequence },
102 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/InstallFinalize", AccessModifier.Public)) { Action="InstallFinalize", Sequence=6600, SequenceTable=SequenceTable.AdvtExecuteSequence },
103 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallFinalize", AccessModifier.Public)) { Action="InstallFinalize", Sequence=6600, SequenceTable=SequenceTable.InstallExecuteSequence },
104
105 new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallFiles", AccessModifier.Public)) { Action="InstallFiles", Sequence=4000, SequenceTable=SequenceTable.AdminExecuteSequence },
106 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallFiles", AccessModifier.Public)) { Action="InstallFiles", Sequence=4000, SequenceTable=SequenceTable.InstallExecuteSequence },
107
108 new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallAdminPackage", AccessModifier.Public)) { Action="InstallAdminPackage", Sequence=3900, SequenceTable=SequenceTable.AdminExecuteSequence },
109
110 new WixActionTuple(null, new Identifier("AdminExecuteSequence/FileCost", AccessModifier.Public)) { Action="FileCost", Sequence=900, SequenceTable=SequenceTable.AdminExecuteSequence },
111 new WixActionTuple(null, new Identifier("InstallExecuteSequence/FileCost", AccessModifier.Public)) { Action="FileCost", Sequence=900, SequenceTable=SequenceTable.InstallExecuteSequence },
112 new WixActionTuple(null, new Identifier("InstallUISequence/FileCost", AccessModifier.Public)) { Action="FileCost", Sequence=900, SequenceTable=SequenceTable.InstallUISequence },
113
114 new WixActionTuple(null, new Identifier("AdminExecuteSequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.AdminExecuteSequence },
115 new WixActionTuple(null, new Identifier("AdminUISequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.AdminUISequence },
116 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.AdvtExecuteSequence },
117 new WixActionTuple(null, new Identifier("InstallExecuteSequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.InstallExecuteSequence },
118 new WixActionTuple(null, new Identifier("InstallUISequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.InstallUISequence },
119
120 new WixActionTuple(null, new Identifier("AdminExecuteSequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.AdminExecuteSequence },
121 new WixActionTuple(null, new Identifier("AdminUISequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.AdminUISequence },
122 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.AdvtExecuteSequence },
123 new WixActionTuple(null, new Identifier("InstallExecuteSequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.InstallExecuteSequence },
124 new WixActionTuple(null, new Identifier("InstallUISequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.InstallUISequence },
125
126 new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallValidate", AccessModifier.Public)) { Action="InstallValidate", Sequence=1400, SequenceTable=SequenceTable.AdminExecuteSequence },
127 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/InstallValidate", AccessModifier.Public)) { Action="InstallValidate", Sequence=1400, SequenceTable=SequenceTable.AdvtExecuteSequence },
128 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallValidate", AccessModifier.Public)) { Action="InstallValidate", Sequence=1400, SequenceTable=SequenceTable.InstallExecuteSequence },
129
130 new WixActionTuple(null, new Identifier("AdminUISequence/ExecuteAction", AccessModifier.Public)) { Action="ExecuteAction", Sequence=1300, SequenceTable=SequenceTable.AdminUISequence },
131 new WixActionTuple(null, new Identifier("InstallUISequence/ExecuteAction", AccessModifier.Public)) { Action="ExecuteAction", Sequence=1300, SequenceTable=SequenceTable.InstallUISequence },
132
133 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/CreateShortcuts", AccessModifier.Public)) { Action="CreateShortcuts", Sequence=4500, SequenceTable=SequenceTable.AdvtExecuteSequence },
134 new WixActionTuple(null, new Identifier("InstallExecuteSequence/CreateShortcuts", AccessModifier.Public)) { Action="CreateShortcuts", Sequence=4500, SequenceTable=SequenceTable.InstallExecuteSequence },
135
136 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/MsiPublishAssemblies", AccessModifier.Public)) { Action="MsiPublishAssemblies", Sequence=6250, SequenceTable=SequenceTable.AdvtExecuteSequence },
137 new WixActionTuple(null, new Identifier("InstallExecuteSequence/MsiPublishAssemblies", AccessModifier.Public)) { Action="MsiPublishAssemblies", Sequence=6250, SequenceTable=SequenceTable.InstallExecuteSequence },
138
139 //<action name="PublishComponents" sequence="6200" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
140 //<action name="PublishFeatures" sequence="6300" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
141 //<action name="PublishProduct" sequence="6400" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
142 //<action name="RegisterClassInfo" sequence="4600" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
143 //<action name="RegisterExtensionInfo" sequence="4700" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
144 //<action name="RegisterMIMEInfo" sequence="4900" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
145 //<action name="RegisterProgIdInfo" sequence="4800" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
146 //<action name="AllocateRegistrySpace" condition="NOT Installed" sequence="1550" InstallExecuteSequence="yes" />
147 //<action name="AppSearch" sequence="50" InstallExecuteSequence="yes" InstallUISequence="yes" />
148 //<action name="BindImage" sequence="4300" InstallExecuteSequence="yes" />
149 //<action name="CreateFolders" sequence="3700" InstallExecuteSequence="yes" />
150 //<action name="DuplicateFiles" sequence="4210" InstallExecuteSequence="yes" />
151 //<action name="FindRelatedProducts" sequence="25" InstallExecuteSequence="yes" InstallUISequence="yes" />
152 //<action name="InstallODBC" sequence="5400" InstallExecuteSequence="yes" />
153 //<action name="InstallServices" condition="VersionNT" sequence="5800" InstallExecuteSequence="yes" />
154 //<action name="MsiConfigureServices" condition="VersionNT>=600" sequence="5850" InstallExecuteSequence="yes" />
155 //<action name="IsolateComponents" sequence="950" InstallExecuteSequence="yes" InstallUISequence="yes" />
156 //<action name="LaunchConditions" sequence="100" AdminExecuteSequence="yes" AdminUISequence="yes" InstallExecuteSequence="yes" InstallUISequence="yes" />
157 //<action name="MigrateFeatureStates" sequence="1200" InstallExecuteSequence="yes" InstallUISequence="yes" />
158 //<action name="MoveFiles" sequence="3800" InstallExecuteSequence="yes" />
159 //<action name="PatchFiles" sequence="4090" AdminExecuteSequence="yes" InstallExecuteSequence="yes" />
160 //<action name="ProcessComponents" sequence="1600" InstallExecuteSequence="yes" />
161 //<action name="RegisterComPlus" sequence="5700" InstallExecuteSequence="yes" />
162 //<action name="RegisterFonts" sequence="5300" InstallExecuteSequence="yes" />
163 //<action name="RegisterProduct" sequence="6100" InstallExecuteSequence="yes" />
164 //<action name="RegisterTypeLibraries" sequence="5500" InstallExecuteSequence="yes" />
165 //<action name="RegisterUser" sequence="6000" InstallExecuteSequence="yes" />
166 //<action name="RemoveDuplicateFiles" sequence="3400" InstallExecuteSequence="yes" />
167 //<action name="RemoveEnvironmentStrings" sequence="3300" InstallExecuteSequence="yes" />
168 //<action name="RemoveFiles" sequence="3500" InstallExecuteSequence="yes" />
169 //<action name="RemoveFolders" sequence="3600" InstallExecuteSequence="yes" />
170 //<action name="RemoveIniValues" sequence="3100" InstallExecuteSequence="yes" />
171 //<action name="RemoveODBC" sequence="2400" InstallExecuteSequence="yes" />
172 //<action name="RemoveRegistryValues" sequence="2600" InstallExecuteSequence="yes" />
173 //<action name="RemoveShortcuts" sequence="3200" InstallExecuteSequence="yes" />
174 //<action name="SelfRegModules" sequence="5600" InstallExecuteSequence="yes" />
175 //<action name="SelfUnregModules" sequence="2200" InstallExecuteSequence="yes" />
176 //<action name="SetODBCFolders" sequence="1100" InstallExecuteSequence="yes" />
177
178
179 new WixActionTuple(null, new Identifier("InstallExecuteSequence/CCPSearch", AccessModifier.Public)) { Action="CCPSearch", Sequence=500, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
180 new WixActionTuple(null, new Identifier("InstallUISequence/CCPSearch", AccessModifier.Public)) { Action="CCPSearch", Sequence=500, SequenceTable=SequenceTable.InstallUISequence, Condition="NOT Installed" },
181
182 new WixActionTuple(null, new Identifier("InstallExecuteSequence/DeleteServices", AccessModifier.Public)) { Action="DeleteServices", Sequence=2000, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="VersionNT" },
183
184 new WixActionTuple(null, new Identifier("InstallExecuteSequence/RMCCPSearch", AccessModifier.Public)) { Action="RMCCPSearch", Sequence=600, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
185 new WixActionTuple(null, new Identifier("InstallUISequence/RMCCPSearch", AccessModifier.Public)) { Action="RMCCPSearch", Sequence=600, SequenceTable=SequenceTable.InstallUISequence, Condition="NOT Installed" },
186
187 new WixActionTuple(null, new Identifier("InstallExecuteSequence/StartServices", AccessModifier.Public)) { Action="StartServices", Sequence=5900, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="VersionNT" },
188 new WixActionTuple(null, new Identifier("InstallExecuteSequence/StopServices", AccessModifier.Public)) { Action="StopServices", Sequence=1900, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="VersionNT" },
189
190 new WixActionTuple(null, new Identifier("InstallExecuteSequence/MsiUnpublishAssemblies", AccessModifier.Public)) { Action="MsiUnpublishAssemblies", Sequence=1750, SequenceTable=SequenceTable.InstallExecuteSequence },
191 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnpublishComponents", AccessModifier.Public)) { Action="UnpublishComponents", Sequence=1700, SequenceTable=SequenceTable.InstallExecuteSequence },
192 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnpublishFeatures", AccessModifier.Public)) { Action="UnpublishFeatures", Sequence=1800, SequenceTable=SequenceTable.InstallExecuteSequence },
193 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterClassInfo", AccessModifier.Public)) { Action="UnregisterClassInfo", Sequence=2700, SequenceTable=SequenceTable.InstallExecuteSequence },
194 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterComPlus", AccessModifier.Public)) { Action="UnregisterComPlus", Sequence=2100, SequenceTable=SequenceTable.InstallExecuteSequence },
195 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterExtensionInfo", AccessModifier.Public)) { Action="UnregisterExtensionInfo", Sequence=2800, SequenceTable=SequenceTable.InstallExecuteSequence },
196 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterFonts", AccessModifier.Public)) { Action="UnregisterFonts", Sequence=2500, SequenceTable=SequenceTable.InstallExecuteSequence },
197 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterMIMEInfo", AccessModifier.Public)) { Action="UnregisterMIMEInfo", Sequence=3000, SequenceTable=SequenceTable.InstallExecuteSequence },
198 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterProgIdInfo", AccessModifier.Public)) { Action="UnregisterProgIdInfo", Sequence=2900, SequenceTable=SequenceTable.InstallExecuteSequence },
199 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterTypeLibraries", AccessModifier.Public)) { Action="UnregisterTypeLibraries", Sequence=2300, SequenceTable=SequenceTable.InstallExecuteSequence },
200 new WixActionTuple(null, new Identifier("InstallExecuteSequence/ValidateProductID", AccessModifier.Public)) { Action="ValidateProductID", Sequence=700, SequenceTable=SequenceTable.InstallExecuteSequence },
201 new WixActionTuple(null, new Identifier("InstallExecuteSequence/WriteEnvironmentStrings", AccessModifier.Public)) { Action="WriteEnvironmentStrings", Sequence=5200, SequenceTable=SequenceTable.InstallExecuteSequence },
202 new WixActionTuple(null, new Identifier("InstallExecuteSequence/WriteIniValues", AccessModifier.Public)) { Action="WriteIniValues", Sequence=5100, SequenceTable=SequenceTable.InstallExecuteSequence },
203 new WixActionTuple(null, new Identifier("InstallExecuteSequence/WriteRegistryValues", AccessModifier.Public)) { Action="WriteRegistryValues", Sequence=5000, SequenceTable=SequenceTable.InstallExecuteSequence },
204 };
205
206 private static readonly HashSet<string> standardDirectories = new HashSet<string>
207 {
208 "TARGETDIR",
209 "AdminToolsFolder",
210 "AppDataFolder",
211 "CommonAppDataFolder",
212 "CommonFilesFolder",
213 "DesktopFolder",
214 "FavoritesFolder",
215 "FontsFolder",
216 "LocalAppDataFolder",
217 "MyPicturesFolder",
218 "PersonalFolder",
219 "ProgramFilesFolder",
220 "ProgramMenuFolder",
221 "SendToFolder",
222 "StartMenuFolder",
223 "StartupFolder",
224 "System16Folder",
225 "SystemFolder",
226 "TempFolder",
227 "TemplateFolder",
228 "WindowsFolder",
229 "CommonFiles64Folder",
230 "ProgramFiles64Folder",
231 "System64Folder",
232 "NetHoodFolder",
233 "PrintHoodFolder",
234 "RecentFolder",
235 "WindowsVolume",
236 };
237
238 /// <summary>
239 /// Find out if an action is a standard action.
240 /// </summary>
241 /// <param name="actionName">Name of the action.</param>
242 /// <returns>true if the action is standard, false otherwise.</returns>
243 public static bool IsStandardAction(string actionName)
244 {
245 return standardActionNames.Contains(actionName);
246 }
247
248 public static WixActionTuple[] StandardActions() => standardActions;
249
250 /// <summary>
251 /// Find out if a directory is a standard directory.
252 /// </summary>
253 /// <param name="directoryName">Name of the directory.</param>
254 /// <returns>true if the directory is standard, false otherwise.</returns>
255 public static bool IsStandardDirectory(string directoryName)
256 {
257 return standardDirectories.Contains(directoryName);
258 }
259 }
260}
diff --git a/src/WixToolset.Core/WixToolsetServiceProvider.cs b/src/WixToolset.Core/WixToolsetServiceProvider.cs
index c073c32b..dd49e7ed 100644
--- a/src/WixToolset.Core/WixToolsetServiceProvider.cs
+++ b/src/WixToolset.Core/WixToolsetServiceProvider.cs
@@ -3,18 +3,30 @@
3namespace WixToolset.Core 3namespace WixToolset.Core
4{ 4{
5 using System; 5 using System;
6 using WixToolset.Data;
6 using WixToolset.Extensibility; 7 using WixToolset.Extensibility;
7 using WixToolset.Extensibility.Services; 8 using WixToolset.Extensibility.Services;
8 9
9 public class WixToolsetServiceProvider : IServiceProvider 10 public class WixToolsetServiceProvider : IServiceProvider
10 { 11 {
11 private ExtensionManager extensionManager; 12 private ExtensionManager extensionManager;
13 private TupleDefinitionCreator tupleDefinitionCreator;
12 14
13 public object GetService(Type serviceType) 15 public object GetService(Type serviceType)
14 { 16 {
15 if (serviceType == null) throw new ArgumentNullException(nameof(serviceType)); 17 if (serviceType == null) throw new ArgumentNullException(nameof(serviceType));
16 18
17 // Transients. 19 // Transients.
20 if (serviceType == typeof(ICompileContext))
21 {
22 return new CompileContext(this);
23 }
24
25 if (serviceType == typeof(ILinkContext))
26 {
27 return new LinkContext(this);
28 }
29
18 if (serviceType == typeof(IBindContext)) 30 if (serviceType == typeof(IBindContext))
19 { 31 {
20 return new BindContext(this); 32 return new BindContext(this);
@@ -38,7 +50,12 @@ namespace WixToolset.Core
38 // Singletons. 50 // Singletons.
39 if (serviceType == typeof(IExtensionManager)) 51 if (serviceType == typeof(IExtensionManager))
40 { 52 {
41 return extensionManager = extensionManager ?? new ExtensionManager(); 53 return this.extensionManager = this.extensionManager ?? new ExtensionManager();
54 }
55
56 if (serviceType == typeof(ITupleDefinitionCreator))
57 {
58 return this.tupleDefinitionCreator = this.tupleDefinitionCreator ?? new TupleDefinitionCreator(this);
42 } 59 }
43 60
44 throw new ArgumentException($"Unknown service type: {serviceType.Name}", nameof(serviceType)); 61 throw new ArgumentException($"Unknown service type: {serviceType.Name}", nameof(serviceType));
diff --git a/src/WixToolset.Core/WixVariableResolver.cs b/src/WixToolset.Core/WixVariableResolver.cs
index 357ff700..c4572d33 100644
--- a/src/WixToolset.Core/WixVariableResolver.cs
+++ b/src/WixToolset.Core/WixVariableResolver.cs
@@ -9,7 +9,7 @@ namespace WixToolset.Core
9 using System.Text; 9 using System.Text;
10 using System.Text.RegularExpressions; 10 using System.Text.RegularExpressions;
11 using WixToolset.Data; 11 using WixToolset.Data;
12 using WixToolset.Data.Rows; 12 using WixToolset.Data.Tuples;
13 using WixToolset.Extensibility; 13 using WixToolset.Extensibility;
14 14
15 /// <summary> 15 /// <summary>
@@ -60,17 +60,17 @@ namespace WixToolset.Core
60 /// Add a variable. 60 /// Add a variable.
61 /// </summary> 61 /// </summary>
62 /// <param name="wixVariableRow">The WixVariableRow to add.</param> 62 /// <param name="wixVariableRow">The WixVariableRow to add.</param>
63 public void AddVariable(WixVariableRow wixVariableRow) 63 public void AddVariable(WixVariableTuple wixVariableRow)
64 { 64 {
65 try 65 try
66 { 66 {
67 this.wixVariables.Add(wixVariableRow.Id, wixVariableRow.Value); 67 this.wixVariables.Add(wixVariableRow.WixVariable, wixVariableRow.Value);
68 } 68 }
69 catch (ArgumentException) 69 catch (ArgumentException)
70 { 70 {
71 if (!wixVariableRow.Overridable) // collision 71 if (!wixVariableRow.Overridable) // collision
72 { 72 {
73 Messaging.Instance.OnMessage(WixErrors.WixVariableCollision(wixVariableRow.SourceLineNumbers, wixVariableRow.Id)); 73 Messaging.Instance.OnMessage(WixErrors.WixVariableCollision(wixVariableRow.SourceLineNumbers, wixVariableRow.WixVariable));
74 } 74 }
75 } 75 }
76 } 76 }
diff --git a/src/WixToolset.Data.WindowsInstaller/ColumnDefinition.cs b/src/WixToolset.Data.WindowsInstaller/ColumnDefinition.cs
new file mode 100644
index 00000000..7e5a07c5
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/ColumnDefinition.cs
@@ -0,0 +1,1032 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Globalization;
7 using System.Xml;
8
9 /// <summary>
10 /// Defines MSI column types.
11 /// </summary>
12 public enum ColumnType
13 {
14 /// <summary>Unknown column type, default and invalid.</summary>
15 Unknown,
16
17 /// <summary>Column is a string.</summary>
18 String,
19
20 /// <summary>Column is a localizable string.</summary>
21 Localized,
22
23 /// <summary>Column is a number.</summary>
24 Number,
25
26 /// <summary>Column is a binary stream.</summary>
27 Object,
28
29 /// <summary>Column is a string that is preserved in transforms (like Object).</summary>
30 Preserved,
31 }
32
33 /// <summary>
34 /// Specifies if the column should be modularized.
35 /// </summary>
36 public enum ColumnModularizeType
37 {
38 /// <summary>Column should not be modularized.</summary>
39 None,
40
41 /// <summary>Column should be modularized.</summary>
42 Column,
43
44 /// <summary>When the column is an primary or foreign key to the Icon table it should be modularized special.</summary>
45 Icon,
46
47 /// <summary>When the column is a companion file it should be modularized.</summary>
48 CompanionFile,
49
50 /// <summary>Column is a condition and should be modularized.</summary>
51 Condition,
52
53 /// <summary>Special modularization type for the ControlEvent table's Argument column.</summary>
54 ControlEventArgument,
55
56 /// <summary>Special modularization type for the Control table's Text column.</summary>
57 ControlText,
58
59 /// <summary>Any Properties in the column should be modularized.</summary>
60 Property,
61
62 /// <summary>Semi-colon list of keys, all of which need to be modularized.</summary>
63 SemicolonDelimited,
64 }
65
66 /// <summary>
67 /// Column validation category type
68 /// </summary>
69 public enum ColumnCategory
70 {
71 /// <summary>Unknown category, default and invalid.</summary>
72 Unknown,
73
74 /// <summary>Text category.</summary>
75 Text,
76
77 /// <summary>UpperCase category.</summary>
78 UpperCase,
79
80 /// <summary>LowerCase category.</summary>
81 LowerCase,
82
83 /// <summary>Integer category.</summary>
84 Integer,
85
86 /// <summary>DoubleInteger category.</summary>
87 DoubleInteger,
88
89 /// <summary>TimeDate category.</summary>
90 TimeDate,
91
92 /// <summary>Identifier category.</summary>
93 Identifier,
94
95 /// <summary>Property category.</summary>
96 Property,
97
98 /// <summary>Filename category.</summary>
99 Filename,
100
101 /// <summary>WildCardFilename category.</summary>
102 WildCardFilename,
103
104 /// <summary>Path category.</summary>
105 Path,
106
107 /// <summary>Paths category.</summary>
108 Paths,
109
110 /// <summary>AnyPath category.</summary>
111 AnyPath,
112
113 /// <summary>DefaultDir category.</summary>
114 DefaultDir,
115
116 /// <summary>RegPath category.</summary>
117 RegPath,
118
119 /// <summary>Formatted category.</summary>
120 Formatted,
121
122 /// <summary>Template category.</summary>
123 Template,
124
125 /// <summary>Condition category.</summary>
126 Condition,
127
128 /// <summary>Guid category.</summary>
129 Guid,
130
131 /// <summary>Version category.</summary>
132 Version,
133
134 /// <summary>Language category.</summary>
135 Language,
136
137 /// <summary>Binary category.</summary>
138 Binary,
139
140 /// <summary>CustomSource category.</summary>
141 CustomSource,
142
143 /// <summary>Cabinet category.</summary>
144 Cabinet,
145
146 /// <summary>Shortcut category.</summary>
147 Shortcut,
148
149 /// <summary>Formatted SDDL category.</summary>
150 FormattedSDDLText,
151 }
152
153 /// <summary>
154 /// Definition of a table's column.
155 /// </summary>
156 public sealed class ColumnDefinition : IComparable<ColumnDefinition>
157 {
158 private string name;
159 private ColumnType type;
160 private int length;
161 private bool primaryKey;
162 private bool nullable;
163 private ColumnModularizeType modularize;
164 private bool localizable;
165 private bool added;
166
167 private bool minValueSet;
168 private long minValue;
169 private bool maxValueSet;
170 private long maxValue;
171 private string keyTable;
172 private bool keyColumnSet;
173 private int keyColumn;
174 private ColumnCategory category;
175 private string possibilities;
176 private string description;
177 private bool escapeIdtCharacters;
178 private bool useCData;
179
180 /// <summary>
181 /// Creates a new column definition.
182 /// </summary>
183 /// <param name="name">Name of column.</param>
184 /// <param name="type">Type of column</param>
185 /// <param name="length">Length of column.</param>
186 /// <param name="primaryKey">If column is primary key.</param>
187 /// <param name="nullable">If column is nullable.</param>
188 /// <param name="modularizeType">Type of modularization for column</param>
189 /// <param name="localizable">If the column is localizable.</param>
190 /// <param name="minValueSet">If the minimum of the value was set.</param>
191 /// <param name="minValue">Minimum value for the column.</param>
192 /// <param name="maxValueSet">If the maximum value was set.</param>
193 /// <param name="maxValue">Maximum value for the colum.</param>
194 /// <param name="keyTable">Optional name of table for foreign key.</param>
195 /// <param name="keyColumnSet">If the key column was set.</param>
196 /// <param name="keyColumn">Optional name of column for foreign key.</param>
197 /// <param name="category">Validation category for column.</param>
198 /// <param name="possibilities">Set of possible values for column.</param>
199 /// <param name="description">Description of column in vaidation table.</param>
200 /// <param name="escapeIdtCharacters">If characters should be escaped in IDT.</param>
201 /// <param name="useCData">If whitespace should be preserved in a CDATA node.</param>
202 public ColumnDefinition(string name, ColumnType type, int length, bool primaryKey, bool nullable, ColumnModularizeType modularizeType, bool localizable, bool minValueSet, long minValue, bool maxValueSet, long maxValue, string keyTable, bool keyColumnSet, int keyColumn, ColumnCategory category, string possibilities, string description, bool escapeIdtCharacters, bool useCData)
203 {
204 this.name = name;
205 this.type = type;
206 this.length = length;
207 this.primaryKey = primaryKey;
208 this.nullable = nullable;
209 this.modularize = modularizeType;
210 this.localizable = localizable;
211 this.minValueSet = minValueSet;
212 this.minValue = minValue;
213 this.maxValueSet = maxValueSet;
214 this.maxValue = maxValue;
215 this.keyTable = keyTable;
216 this.keyColumnSet = keyColumnSet;
217 this.keyColumn = keyColumn;
218 this.category = category;
219 this.possibilities = possibilities;
220 this.description = description;
221 this.escapeIdtCharacters = escapeIdtCharacters;
222 this.useCData = useCData;
223 }
224
225 /// <summary>
226 /// Gets whether this column was added via a transform.
227 /// </summary>
228 /// <value>Whether this column was added via a transform.</value>
229 public bool Added
230 {
231 get { return this.added; }
232 set { this.added = value; }
233 }
234
235 /// <summary>
236 /// Gets the name of the column.
237 /// </summary>
238 /// <value>Name of column.</value>
239 public string Name
240 {
241 get { return this.name; }
242 }
243
244 /// <summary>
245 /// Gets the type of the column.
246 /// </summary>
247 /// <value>Type of column.</value>
248 public ColumnType Type
249 {
250 get { return this.type; }
251 }
252
253 /// <summary>
254 /// Gets the length of the column.
255 /// </summary>
256 /// <value>Length of column.</value>
257 public int Length
258 {
259 get { return this.length; }
260 }
261
262 /// <summary>
263 /// Gets if the column is a primary key.
264 /// </summary>
265 /// <value>true if column is primary key.</value>
266 public bool PrimaryKey
267 {
268 get { return this.primaryKey; }
269 }
270
271 /// <summary>
272 /// Gets if the column is nullable.
273 /// </summary>
274 /// <value>true if column is nullable.</value>
275 public bool Nullable
276 {
277 get { return this.nullable; }
278 }
279
280 /// <summary>
281 /// Gets the type of modularization for this column.
282 /// </summary>
283 /// <value>Column's modularization type.</value>
284 public ColumnModularizeType ModularizeType
285 {
286 get { return this.modularize; }
287 }
288
289 /// <summary>
290 /// Gets if the column is localizable. Can be because the type is localizable, or because the column
291 /// was explicitly set to be so.
292 /// </summary>
293 /// <value>true if column is localizable.</value>
294 public bool IsLocalizable
295 {
296 get { return this.localizable || ColumnType.Localized == this.Type; }
297 }
298
299 /// <summary>
300 /// Gets if the minimum value of the column is set.
301 /// </summary>
302 /// <value>true if minimum value is set.</value>
303 public bool IsMinValueSet
304 {
305 get { return this.minValueSet; }
306 }
307
308 /// <summary>
309 /// Gets the minimum value for the column, only valid if IsMinValueSet returns true.
310 /// </summary>
311 /// <value>Minimum value for the column.</value>
312 public long MinValue
313 {
314 get { return this.minValue; }
315 }
316
317 /// <summary>
318 /// Gets if the maximum value of the column is set.
319 /// </summary>
320 /// <value>true if maximum value is set.</value>
321 public bool IsMaxValueSet
322 {
323 get { return this.maxValueSet; }
324 }
325
326 /// <summary>
327 /// Gets the maximum value for the column, only valid if IsMinValueSet returns true.
328 /// </summary>
329 /// <value>Maximum value for the column.</value>
330 public long MaxValue
331 {
332 get { return this.maxValue; }
333 }
334
335 /// <summary>
336 /// Gets the table that has the foreign key for this column
337 /// </summary>
338 /// <value>Foreign key table name.</value>
339 public string KeyTable
340 {
341 get { return this.keyTable; }
342 }
343
344 /// <summary>
345 /// Gets if the key column is set.
346 /// </summary>
347 /// <value>True if the key column is set.</value>
348 public bool IsKeyColumnSet
349 {
350 get { return this.keyColumnSet; }
351 }
352
353 /// <summary>
354 /// Gets the foreign key column that this column refers to.
355 /// </summary>
356 /// <value>Foreign key column.</value>
357 public int KeyColumn
358 {
359 get { return this.keyColumn; }
360 }
361
362 /// <summary>
363 /// Gets the validation category for this column.
364 /// </summary>
365 /// <value>Validation category.</value>
366 public ColumnCategory Category
367 {
368 get { return this.category; }
369 }
370
371 /// <summary>
372 /// Gets the set of possibilities for this column.
373 /// </summary>
374 /// <value>Set of possibilities for this column.</value>
375 public string Possibilities
376 {
377 get { return this.possibilities; }
378 }
379
380 /// <summary>
381 /// Gets the description for this column.
382 /// </summary>
383 /// <value>Description of column.</value>
384 public string Description
385 {
386 get { return this.description; }
387 }
388
389 /// <summary>
390 /// Gets if characters should be escaped to fit into IDT.
391 /// </summary>
392 /// <value>true if data should be escaped when adding to IDT.</value>
393 public bool EscapeIdtCharacters
394 {
395 get { return this.escapeIdtCharacters; }
396 }
397
398 /// <summary>
399 /// Gets if whitespace should be preserved in a CDATA node.
400 /// </summary>
401 /// <value>true if whitespace should be preserved in a CDATA node.</value>
402 public bool UseCData
403 {
404 get { return this.useCData; }
405 }
406
407 /// <summary>
408 /// Gets the type of the column in IDT format.
409 /// </summary>
410 /// <value>IDT format for column type.</value>
411 public string IdtType
412 {
413 get
414 {
415 char typeCharacter;
416 switch (this.type)
417 {
418 case ColumnType.Number:
419 typeCharacter = this.nullable ? 'I' : 'i';
420 break;
421 case ColumnType.Preserved:
422 case ColumnType.String:
423 typeCharacter = this.nullable ? 'S' : 's';
424 break;
425 case ColumnType.Localized:
426 typeCharacter = this.nullable ? 'L' : 'l';
427 break;
428 case ColumnType.Object:
429 typeCharacter = this.nullable ? 'V' : 'v';
430 break;
431 default:
432 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixDataStrings.EXP_UnknownColumnType, this.type));
433 }
434
435 return String.Concat(typeCharacter, this.length);
436 }
437 }
438
439 /// <summary>
440 /// Parses a column definition in a table definition.
441 /// </summary>
442 /// <param name="reader">Reader to get data from.</param>
443 /// <returns>The ColumnDefintion represented by the Xml.</returns>
444 internal static ColumnDefinition Read(XmlReader reader)
445 {
446 if (!reader.LocalName.Equals("columnDefinition"))
447 {
448 throw new XmlException();
449 }
450
451 bool added = false;
452 ColumnCategory category = ColumnCategory.Unknown;
453 string description = null;
454 bool empty = reader.IsEmptyElement;
455 bool escapeIdtCharacters = false;
456 int keyColumn = -1;
457 bool keyColumnSet = false;
458 string keyTable = null;
459 int length = -1;
460 bool localizable = false;
461 long maxValue = 0;
462 bool maxValueSet = false;
463 long minValue = 0;
464 bool minValueSet = false;
465 ColumnModularizeType modularize = ColumnModularizeType.None;
466 string name = null;
467 bool nullable = false;
468 string possibilities = null;
469 bool primaryKey = false;
470 ColumnType type = ColumnType.Unknown;
471 bool useCData = false;
472
473 // parse the attributes
474 while (reader.MoveToNextAttribute())
475 {
476 switch (reader.LocalName)
477 {
478 case "added":
479 added = reader.Value.Equals("yes");
480 break;
481 case "category":
482 switch (reader.Value)
483 {
484 case "anyPath":
485 category = ColumnCategory.AnyPath;
486 break;
487 case "binary":
488 category = ColumnCategory.Binary;
489 break;
490 case "cabinet":
491 category = ColumnCategory.Cabinet;
492 break;
493 case "condition":
494 category = ColumnCategory.Condition;
495 break;
496 case "customSource":
497 category = ColumnCategory.CustomSource;
498 break;
499 case "defaultDir":
500 category = ColumnCategory.DefaultDir;
501 break;
502 case "doubleInteger":
503 category = ColumnCategory.DoubleInteger;
504 break;
505 case "filename":
506 category = ColumnCategory.Filename;
507 break;
508 case "formatted":
509 category = ColumnCategory.Formatted;
510 break;
511 case "formattedSddl":
512 category = ColumnCategory.FormattedSDDLText;
513 break;
514 case "guid":
515 category = ColumnCategory.Guid;
516 break;
517 case "identifier":
518 category = ColumnCategory.Identifier;
519 break;
520 case "integer":
521 category = ColumnCategory.Integer;
522 break;
523 case "language":
524 category = ColumnCategory.Language;
525 break;
526 case "lowerCase":
527 category = ColumnCategory.LowerCase;
528 break;
529 case "path":
530 category = ColumnCategory.Path;
531 break;
532 case "paths":
533 category = ColumnCategory.Paths;
534 break;
535 case "property":
536 category = ColumnCategory.Property;
537 break;
538 case "regPath":
539 category = ColumnCategory.RegPath;
540 break;
541 case "shortcut":
542 category = ColumnCategory.Shortcut;
543 break;
544 case "template":
545 category = ColumnCategory.Template;
546 break;
547 case "text":
548 category = ColumnCategory.Text;
549 break;
550 case "timeDate":
551 category = ColumnCategory.TimeDate;
552 break;
553 case "upperCase":
554 category = ColumnCategory.UpperCase;
555 break;
556 case "version":
557 category = ColumnCategory.Version;
558 break;
559 case "wildCardFilename":
560 category = ColumnCategory.WildCardFilename;
561 break;
562 default:
563 throw new InvalidOperationException();
564 }
565 break;
566 case "description":
567 description = reader.Value;
568 break;
569 case "escapeIdtCharacters":
570 escapeIdtCharacters = reader.Value.Equals("yes");
571 break;
572 case "keyColumn":
573 keyColumnSet = true;
574 keyColumn = Convert.ToInt32(reader.Value, 10);
575 break;
576 case "keyTable":
577 keyTable = reader.Value;
578 break;
579 case "length":
580 length = Convert.ToInt32(reader.Value, 10);
581 break;
582 case "localizable":
583 localizable = reader.Value.Equals("yes");
584 break;
585 case "maxValue":
586 maxValueSet = true;
587 maxValue = Convert.ToInt32(reader.Value, 10);
588 break;
589 case "minValue":
590 minValueSet = true;
591 minValue = Convert.ToInt32(reader.Value, 10);
592 break;
593 case "modularize":
594 switch (reader.Value)
595 {
596 case "column":
597 modularize = ColumnModularizeType.Column;
598 break;
599 case "companionFile":
600 modularize = ColumnModularizeType.CompanionFile;
601 break;
602 case "condition":
603 modularize = ColumnModularizeType.Condition;
604 break;
605 case "controlEventArgument":
606 modularize = ColumnModularizeType.ControlEventArgument;
607 break;
608 case "controlText":
609 modularize = ColumnModularizeType.ControlText;
610 break;
611 case "icon":
612 modularize = ColumnModularizeType.Icon;
613 break;
614 case "none":
615 modularize = ColumnModularizeType.None;
616 break;
617 case "property":
618 modularize = ColumnModularizeType.Property;
619 break;
620 case "semicolonDelimited":
621 modularize = ColumnModularizeType.SemicolonDelimited;
622 break;
623 default:
624 throw new XmlException();
625 }
626 break;
627 case "name":
628 switch (reader.Value)
629 {
630 case "CREATE":
631 case "DELETE":
632 case "DROP":
633 case "INSERT":
634 throw new XmlException();
635 default:
636 name = reader.Value;
637 break;
638 }
639 break;
640 case "nullable":
641 nullable = reader.Value.Equals("yes");
642 break;
643 case "primaryKey":
644 primaryKey = reader.Value.Equals("yes");
645 break;
646 case "set":
647 possibilities = reader.Value;
648 break;
649 case "type":
650 switch (reader.Value)
651 {
652 case "localized":
653 type = ColumnType.Localized;
654 break;
655 case "number":
656 type = ColumnType.Number;
657 break;
658 case "object":
659 type = ColumnType.Object;
660 break;
661 case "string":
662 type = ColumnType.String;
663 break;
664 case "preserved":
665 type = ColumnType.Preserved;
666 break;
667 default:
668 throw new XmlException();
669 }
670 break;
671 case "useCData":
672 useCData = reader.Value.Equals("yes");
673 break;
674 }
675 }
676
677 // parse the child elements (there should be none)
678 if (!empty)
679 {
680 bool done = false;
681
682 while (!done && reader.Read())
683 {
684 switch (reader.NodeType)
685 {
686 case XmlNodeType.Element:
687 throw new XmlException();
688 case XmlNodeType.EndElement:
689 done = true;
690 break;
691 }
692 }
693
694 if (!done)
695 {
696 throw new XmlException();
697 }
698 }
699
700 ColumnDefinition columnDefinition = new ColumnDefinition(name, type, length, primaryKey, nullable, modularize, localizable, minValueSet, minValue, maxValueSet, maxValue, keyTable, keyColumnSet, keyColumn, category, possibilities, description, escapeIdtCharacters, useCData);
701 columnDefinition.Added = added;
702
703 return columnDefinition;
704 }
705
706 /// <summary>
707 /// Persists a ColumnDefinition in an XML format.
708 /// </summary>
709 /// <param name="writer">XmlWriter where the Output should persist itself as XML.</param>
710 internal void Write(XmlWriter writer)
711 {
712 writer.WriteStartElement("columnDefinition", TableDefinitionCollection.XmlNamespaceUri);
713
714 writer.WriteAttributeString("name", this.name);
715
716 switch (this.type)
717 {
718 case ColumnType.Localized:
719 writer.WriteAttributeString("type", "localized");
720 break;
721 case ColumnType.Number:
722 writer.WriteAttributeString("type", "number");
723 break;
724 case ColumnType.Object:
725 writer.WriteAttributeString("type", "object");
726 break;
727 case ColumnType.String:
728 writer.WriteAttributeString("type", "string");
729 break;
730 case ColumnType.Preserved:
731 writer.WriteAttributeString("type", "preserved");
732 break;
733 }
734
735 writer.WriteAttributeString("length", this.length.ToString(CultureInfo.InvariantCulture.NumberFormat));
736
737 if (this.primaryKey)
738 {
739 writer.WriteAttributeString("primaryKey", "yes");
740 }
741
742 if (this.nullable)
743 {
744 writer.WriteAttributeString("nullable", "yes");
745 }
746
747 if (this.localizable)
748 {
749 writer.WriteAttributeString("localizable", "yes");
750 }
751
752 if (this.added)
753 {
754 writer.WriteAttributeString("added", "yes");
755 }
756
757 switch (this.modularize)
758 {
759 case ColumnModularizeType.Column:
760 writer.WriteAttributeString("modularize", "column");
761 break;
762 case ColumnModularizeType.CompanionFile:
763 writer.WriteAttributeString("modularize", "companionFile");
764 break;
765 case ColumnModularizeType.Condition:
766 writer.WriteAttributeString("modularize", "condition");
767 break;
768 case ColumnModularizeType.ControlEventArgument:
769 writer.WriteAttributeString("modularize", "controlEventArgument");
770 break;
771 case ColumnModularizeType.ControlText:
772 writer.WriteAttributeString("modularize", "controlText");
773 break;
774 case ColumnModularizeType.Icon:
775 writer.WriteAttributeString("modularize", "icon");
776 break;
777 case ColumnModularizeType.None:
778 // this is the default value
779 break;
780 case ColumnModularizeType.Property:
781 writer.WriteAttributeString("modularize", "property");
782 break;
783 case ColumnModularizeType.SemicolonDelimited:
784 writer.WriteAttributeString("modularize", "semicolonDelimited");
785 break;
786 }
787
788 if (this.minValueSet)
789 {
790 writer.WriteAttributeString("minValue", this.minValue.ToString(CultureInfo.InvariantCulture.NumberFormat));
791 }
792
793 if (this.maxValueSet)
794 {
795 writer.WriteAttributeString("maxValue", this.maxValue.ToString(CultureInfo.InvariantCulture.NumberFormat));
796 }
797
798 if (!String.IsNullOrEmpty(this.keyTable))
799 {
800 writer.WriteAttributeString("keyTable", this.keyTable);
801 }
802
803 if (this.keyColumnSet)
804 {
805 writer.WriteAttributeString("keyColumn", this.keyColumn.ToString(CultureInfo.InvariantCulture.NumberFormat));
806 }
807
808 switch (this.category)
809 {
810 case ColumnCategory.AnyPath:
811 writer.WriteAttributeString("category", "anyPath");
812 break;
813 case ColumnCategory.Binary:
814 writer.WriteAttributeString("category", "binary");
815 break;
816 case ColumnCategory.Cabinet:
817 writer.WriteAttributeString("category", "cabinet");
818 break;
819 case ColumnCategory.Condition:
820 writer.WriteAttributeString("category", "condition");
821 break;
822 case ColumnCategory.CustomSource:
823 writer.WriteAttributeString("category", "customSource");
824 break;
825 case ColumnCategory.DefaultDir:
826 writer.WriteAttributeString("category", "defaultDir");
827 break;
828 case ColumnCategory.DoubleInteger:
829 writer.WriteAttributeString("category", "doubleInteger");
830 break;
831 case ColumnCategory.Filename:
832 writer.WriteAttributeString("category", "filename");
833 break;
834 case ColumnCategory.Formatted:
835 writer.WriteAttributeString("category", "formatted");
836 break;
837 case ColumnCategory.FormattedSDDLText:
838 writer.WriteAttributeString("category", "formattedSddl");
839 break;
840 case ColumnCategory.Guid:
841 writer.WriteAttributeString("category", "guid");
842 break;
843 case ColumnCategory.Identifier:
844 writer.WriteAttributeString("category", "identifier");
845 break;
846 case ColumnCategory.Integer:
847 writer.WriteAttributeString("category", "integer");
848 break;
849 case ColumnCategory.Language:
850 writer.WriteAttributeString("category", "language");
851 break;
852 case ColumnCategory.LowerCase:
853 writer.WriteAttributeString("category", "lowerCase");
854 break;
855 case ColumnCategory.Path:
856 writer.WriteAttributeString("category", "path");
857 break;
858 case ColumnCategory.Paths:
859 writer.WriteAttributeString("category", "paths");
860 break;
861 case ColumnCategory.Property:
862 writer.WriteAttributeString("category", "property");
863 break;
864 case ColumnCategory.RegPath:
865 writer.WriteAttributeString("category", "regPath");
866 break;
867 case ColumnCategory.Shortcut:
868 writer.WriteAttributeString("category", "shortcut");
869 break;
870 case ColumnCategory.Template:
871 writer.WriteAttributeString("category", "template");
872 break;
873 case ColumnCategory.Text:
874 writer.WriteAttributeString("category", "text");
875 break;
876 case ColumnCategory.TimeDate:
877 writer.WriteAttributeString("category", "timeDate");
878 break;
879 case ColumnCategory.UpperCase:
880 writer.WriteAttributeString("category", "upperCase");
881 break;
882 case ColumnCategory.Version:
883 writer.WriteAttributeString("category", "version");
884 break;
885 case ColumnCategory.WildCardFilename:
886 writer.WriteAttributeString("category", "wildCardFilename");
887 break;
888 }
889
890 if (!String.IsNullOrEmpty(this.possibilities))
891 {
892 writer.WriteAttributeString("set", this.possibilities);
893 }
894
895 if (!String.IsNullOrEmpty(this.description))
896 {
897 writer.WriteAttributeString("description", this.description);
898 }
899
900 if (this.escapeIdtCharacters)
901 {
902 writer.WriteAttributeString("escapeIdtCharacters", "yes");
903 }
904
905 if (this.useCData)
906 {
907 writer.WriteAttributeString("useCData", "yes");
908 }
909
910 writer.WriteEndElement();
911 }
912
913 /// <summary>
914 /// Validate a value for this column.
915 /// </summary>
916 /// <param name="value">The value to validate.</param>
917 /// <returns>Validated value.</returns>
918 internal object ValidateValue(object value)
919 {
920 if (null == value)
921 {
922 if (!this.nullable)
923 {
924 throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot set column '{0}' with a null value because this is a required field.", this.name));
925 }
926 }
927 else // check numerical values against their specified minimum and maximum values.
928 {
929 if (ColumnType.Number == this.type && !this.IsLocalizable)
930 {
931 // For now all enums in the tables can be represented by integers. This if statement would need to
932 // be enhanced if that ever changes.
933 if (value is int || value.GetType().IsEnum)
934 {
935 int intValue = (int)value;
936
937 // validate the value against the minimum allowed value
938 if (this.minValueSet && this.minValue > intValue)
939 {
940 throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot set column '{0}' with value {1} because it is less than the minimum allowed value for this column, {2}.", this.name, intValue, this.minValue));
941 }
942
943 // validate the value against the maximum allowed value
944 if (this.maxValueSet && this.maxValue < intValue)
945 {
946 throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot set column '{0}' with value {1} because it is greater than the maximum allowed value for this column, {2}.", this.name, intValue, this.maxValue));
947 }
948
949 return intValue;
950 }
951 else if (value is long)
952 {
953 long longValue = (long)value;
954
955 // validate the value against the minimum allowed value
956 if (this.minValueSet && this.minValue > longValue)
957 {
958 throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot set column '{0}' with value {1} because it is less than the minimum allowed value for this column, {2}.", this.name, longValue, this.minValue));
959 }
960
961 // validate the value against the maximum allowed value
962 if (this.maxValueSet && this.maxValue < longValue)
963 {
964 throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot set column '{0}' with value {1} because it is greater than the maximum allowed value for this column, {2}.", this.name, longValue, this.maxValue));
965 }
966
967 return longValue;
968 }
969 else
970 {
971 throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot set number column '{0}' with a value of type '{1}'.", this.name, value.GetType().ToString()));
972 }
973 }
974 else
975 {
976 if (!(value is string))
977 {
978 throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot set string column '{0}' with a value of type '{1}'.", this.name, value.GetType().ToString()));
979 }
980 }
981 }
982
983 return value;
984 }
985
986 /// <summary>
987 /// Compare this column definition to another column definition.
988 /// </summary>
989 /// <remarks>
990 /// Only Windows Installer traits are compared, allowing for updates to WiX-specific table definitions.
991 /// </remarks>
992 /// <param name="other">The <see cref="ColumnDefinition"/> to compare with this one.</param>
993 /// <returns>0 if the columns' core propeties are the same; otherwise, non-0.</returns>
994 public int CompareTo(ColumnDefinition other)
995 {
996 // by definition, this object is greater than null
997 if (null == other)
998 {
999 return 1;
1000 }
1001
1002 // compare column names
1003 int ret = String.Compare(this.Name, other.Name, StringComparison.Ordinal);
1004
1005 // compare column types
1006 if (0 == ret)
1007 {
1008 ret = this.Type == other.Type ? 0 : -1;
1009
1010 // compare column lengths
1011 if (0 == ret)
1012 {
1013 ret = this.Length == other.Length ? 0 : -1;
1014
1015 // compare whether both are primary keys
1016 if (0 == ret)
1017 {
1018 ret = this.PrimaryKey == other.PrimaryKey ? 0 : -1;
1019
1020 // compare nullability
1021 if (0 == ret)
1022 {
1023 ret = this.Nullable == other.Nullable ? 0 : -1;
1024 }
1025 }
1026 }
1027 }
1028
1029 return ret;
1030 }
1031 }
1032}
diff --git a/src/WixToolset.Data.WindowsInstaller/Common.cs b/src/WixToolset.Data.WindowsInstaller/Common.cs
new file mode 100644
index 00000000..a1e1e607
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Common.cs
@@ -0,0 +1,25 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Text.RegularExpressions;
7
8 internal static class Common
9 {
10 private static readonly Regex LegalIdentifierCharacters = new Regex(@"^[_A-Za-z][0-9A-Za-z_\.]*$", RegexOptions.Compiled);
11
12 public static bool IsIdentifier(string value)
13 {
14 if (!String.IsNullOrEmpty(value))
15 {
16 if (LegalIdentifierCharacters.IsMatch(value))
17 {
18 return true;
19 }
20 }
21
22 return false;
23 }
24 }
25}
diff --git a/src/WixToolset.Data.WindowsInstaller/Data/actions.xml b/src/WixToolset.Data.WindowsInstaller/Data/actions.xml
new file mode 100644
index 00000000..f65b792d
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Data/actions.xml
@@ -0,0 +1,76 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<actions xmlns="http://wixtoolset.org/schemas/v4/wi/actions">
6 <action name="InstallInitialize" sequence="1500" AdminExecuteSequence="yes" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
7 <action name="InstallExecute" condition="NOT Installed" sequence="6500" InstallExecuteSequence="yes" />
8 <action name="InstallExecuteAgain" condition="NOT Installed" sequence="6550" InstallExecuteSequence="yes" />
9 <action name="InstallFinalize" sequence="6600" AdminExecuteSequence="yes" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
10 <action name="InstallFiles" sequence="4000" AdminExecuteSequence="yes" InstallExecuteSequence="yes" />
11 <action name="InstallAdminPackage" sequence="3900" AdminExecuteSequence="yes" />
12 <action name="FileCost" sequence="900" AdminExecuteSequence="yes" AdminUISequence="yes" InstallExecuteSequence="yes" InstallUISequence="yes" />
13 <action name="CostInitialize" sequence="800" AdminExecuteSequence="yes" AdminUISequence="yes" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" InstallUISequence="yes" />
14 <action name="CostFinalize" sequence="1000" AdminExecuteSequence="yes" AdminUISequence="yes" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" InstallUISequence="yes" />
15 <action name="InstallValidate" sequence="1400" AdminExecuteSequence="yes" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
16 <action name="ExecuteAction" sequence="1300" AdminUISequence="yes" InstallUISequence="yes" />
17 <action name="CreateShortcuts" sequence="4500" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
18 <action name="MsiPublishAssemblies" sequence="6250" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
19 <action name="PublishComponents" sequence="6200" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
20 <action name="PublishFeatures" sequence="6300" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
21 <action name="PublishProduct" sequence="6400" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
22 <action name="RegisterClassInfo" sequence="4600" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
23 <action name="RegisterExtensionInfo" sequence="4700" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
24 <action name="RegisterMIMEInfo" sequence="4900" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
25 <action name="RegisterProgIdInfo" sequence="4800" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
26 <action name="AllocateRegistrySpace" condition="NOT Installed" sequence="1550" InstallExecuteSequence="yes" />
27 <action name="AppSearch" sequence="50" InstallExecuteSequence="yes" InstallUISequence="yes" />
28 <action name="BindImage" sequence="4300" InstallExecuteSequence="yes" />
29 <action name="CCPSearch" condition="NOT Installed" sequence="500" InstallExecuteSequence="yes" InstallUISequence="yes" />
30 <action name="CreateFolders" sequence="3700" InstallExecuteSequence="yes" />
31 <action name="DeleteServices" condition="VersionNT" sequence="2000" InstallExecuteSequence="yes" />
32 <action name="DuplicateFiles" sequence="4210" InstallExecuteSequence="yes" />
33 <action name="FindRelatedProducts" sequence="25" InstallExecuteSequence="yes" InstallUISequence="yes" />
34 <action name="InstallODBC" sequence="5400" InstallExecuteSequence="yes" />
35 <action name="InstallServices" condition="VersionNT" sequence="5800" InstallExecuteSequence="yes" />
36 <action name="MsiConfigureServices" condition="VersionNT>=600" sequence="5850" InstallExecuteSequence="yes" />
37 <action name="IsolateComponents" sequence="950" InstallExecuteSequence="yes" InstallUISequence="yes" />
38 <action name="LaunchConditions" sequence="100" AdminExecuteSequence="yes" AdminUISequence="yes" InstallExecuteSequence="yes" InstallUISequence="yes" />
39 <action name="MigrateFeatureStates" sequence="1200" InstallExecuteSequence="yes" InstallUISequence="yes" />
40 <action name="MoveFiles" sequence="3800" InstallExecuteSequence="yes" />
41 <action name="PatchFiles" sequence="4090" AdminExecuteSequence="yes" InstallExecuteSequence="yes" />
42 <action name="ProcessComponents" sequence="1600" InstallExecuteSequence="yes" />
43 <action name="RegisterComPlus" sequence="5700" InstallExecuteSequence="yes" />
44 <action name="RegisterFonts" sequence="5300" InstallExecuteSequence="yes" />
45 <action name="RegisterProduct" sequence="6100" InstallExecuteSequence="yes" />
46 <action name="RegisterTypeLibraries" sequence="5500" InstallExecuteSequence="yes" />
47 <action name="RegisterUser" sequence="6000" InstallExecuteSequence="yes" />
48 <action name="RemoveDuplicateFiles" sequence="3400" InstallExecuteSequence="yes" />
49 <action name="RemoveEnvironmentStrings" sequence="3300" InstallExecuteSequence="yes" />
50 <action name="RemoveFiles" sequence="3500" InstallExecuteSequence="yes" />
51 <action name="RemoveFolders" sequence="3600" InstallExecuteSequence="yes" />
52 <action name="RemoveIniValues" sequence="3100" InstallExecuteSequence="yes" />
53 <action name="RemoveODBC" sequence="2400" InstallExecuteSequence="yes" />
54 <action name="RemoveRegistryValues" sequence="2600" InstallExecuteSequence="yes" />
55 <action name="RemoveShortcuts" sequence="3200" InstallExecuteSequence="yes" />
56 <action name="RMCCPSearch" condition="NOT Installed" sequence="600" InstallExecuteSequence="yes" InstallUISequence="yes" />
57 <action name="SelfRegModules" sequence="5600" InstallExecuteSequence="yes" />
58 <action name="SelfUnregModules" sequence="2200" InstallExecuteSequence="yes" />
59 <action name="SetODBCFolders" sequence="1100" InstallExecuteSequence="yes" />
60 <action name="StartServices" condition="VersionNT" sequence="5900" InstallExecuteSequence="yes" />
61 <action name="StopServices" condition="VersionNT" sequence="1900" InstallExecuteSequence="yes" />
62 <action name="MsiUnpublishAssemblies" sequence="1750" InstallExecuteSequence="yes" />
63 <action name="UnpublishComponents" sequence="1700" InstallExecuteSequence="yes" />
64 <action name="UnpublishFeatures" sequence="1800" InstallExecuteSequence="yes" />
65 <action name="UnregisterClassInfo" sequence="2700" InstallExecuteSequence="yes" />
66 <action name="UnregisterComPlus" sequence="2100" InstallExecuteSequence="yes" />
67 <action name="UnregisterExtensionInfo" sequence="2800" InstallExecuteSequence="yes" />
68 <action name="UnregisterFonts" sequence="2500" InstallExecuteSequence="yes" />
69 <action name="UnregisterMIMEInfo" sequence="3000" InstallExecuteSequence="yes" />
70 <action name="UnregisterProgIdInfo" sequence="2900" InstallExecuteSequence="yes" />
71 <action name="UnregisterTypeLibraries" sequence="2300" InstallExecuteSequence="yes" />
72 <action name="ValidateProductID" sequence="700" InstallExecuteSequence="yes" InstallUISequence="yes" />
73 <action name="WriteEnvironmentStrings" sequence="5200" InstallExecuteSequence="yes" />
74 <action name="WriteIniValues" sequence="5100" InstallExecuteSequence="yes" />
75 <action name="WriteRegistryValues" sequence="5000" InstallExecuteSequence="yes" />
76</actions>
diff --git a/src/WixToolset.Data.WindowsInstaller/Data/tables.xml b/src/WixToolset.Data.WindowsInstaller/Data/tables.xml
new file mode 100644
index 00000000..280d87a8
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Data/tables.xml
@@ -0,0 +1,1962 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<tableDefinitions xmlns="http://wixtoolset.org/schemas/v4/wi/tables">
6 <tableDefinition name="ActionText">
7 <columnDefinition name="Action" type="string" length="72" primaryKey="yes" modularize="column"
8 category="identifier" description="Name of action to be described."/>
9 <columnDefinition name="Description" type="localized" length="0" nullable="yes" escapeIdtCharacters="yes"
10 category="text" description="Localized description displayed in progress dialog and log when action is executing."/>
11 <columnDefinition name="Template" type="localized" length="0" nullable="yes" escapeIdtCharacters="yes" modularize="property"
12 category="template" description="Optional localized format template used to format action data records for display during action execution."/>
13 </tableDefinition>
14 <tableDefinition name="AdminExecuteSequence">
15 <columnDefinition name="Action" type="string" length="72" primaryKey="yes"
16 category="identifier" description="Name of action to invoke, either in the engine or the handler DLL."/>
17 <columnDefinition name="Condition" type="string" length="255" nullable="yes" localizable="yes"
18 category="condition" description="Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData."/>
19 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
20 minValue="-4" maxValue="32767" description="Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action."/>
21 </tableDefinition>
22 <tableDefinition name="Condition">
23 <columnDefinition name="Feature_" type="string" length="38" primaryKey="yes"
24 keyTable="Feature" keyColumn="1" category="identifier" description="Reference to a Feature entry in Feature table."/>
25 <columnDefinition name="Level" type="number" length="2" primaryKey="yes"
26 minValue="0" maxValue="32767" description="New selection Level to set in Feature table if Condition evaluates to TRUE."/>
27 <columnDefinition name="Condition" type="string" length="255" nullable="yes" localizable="yes"
28 category="condition" description="Expression evaluated to determine if Level in the Feature table is to change."/>
29 </tableDefinition>
30 <tableDefinition name="AdminUISequence">
31 <columnDefinition name="Action" type="string" length="72" primaryKey="yes"
32 category="identifier" description="Name of action to invoke, either in the engine or the handler DLL."/>
33 <columnDefinition name="Condition" type="string" length="255" nullable="yes" localizable="yes"
34 category="condition" description="Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData."/>
35 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
36 minValue="-4" maxValue="32767" description="Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action."/>
37 </tableDefinition>
38 <tableDefinition name="AdvtExecuteSequence">
39 <columnDefinition name="Action" type="string" length="72" primaryKey="yes"
40 category="identifier" description="Name of action to invoke, either in the engine or the handler DLL."/>
41 <columnDefinition name="Condition" type="string" length="255" nullable="yes" localizable="yes"
42 category="condition" description="Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData."/>
43 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
44 minValue="-4" maxValue="32767" description="Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action."/>
45 </tableDefinition>
46 <tableDefinition name="AdvtUISequence">
47 <columnDefinition name="Action" type="string" length="72" primaryKey="yes"
48 category="identifier" description="Name of action to invoke, either in the engine or the handler DLL."/>
49 <columnDefinition name="Condition" type="string" length="255" nullable="yes" localizable="yes"
50 category="condition" description="Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData."/>
51 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
52 minValue="-4" maxValue="32767" description="Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action."/>
53 </tableDefinition>
54 <tableDefinition name="AppId" createSymbols="yes">
55 <columnDefinition name="AppId" type="string" length="38" primaryKey="yes"
56 category="guid"/>
57 <columnDefinition name="RemoteServerName" type="string" length="255" nullable="yes" modularize="property"
58 category="formatted"/>
59 <columnDefinition name="LocalService" type="string" length="255" nullable="yes"
60 category="text"/>
61 <columnDefinition name="ServiceParameters" type="string" length="255" nullable="yes"
62 category="text"/>
63 <columnDefinition name="DllSurrogate" type="string" length="255" nullable="yes"
64 category="text"/>
65 <columnDefinition name="ActivateAtStorage" type="number" length="2" nullable="yes"
66 minValue="0" maxValue="1"/>
67 <columnDefinition name="RunAsInteractiveUser" type="number" length="2" nullable="yes"
68 minValue="0" maxValue="1"/>
69 </tableDefinition>
70 <tableDefinition name="AppSearch">
71 <columnDefinition name="Property" type="string" length="72" primaryKey="yes" modularize="column"
72 category="identifier" description="The property associated with a Signature"/>
73 <columnDefinition name="Signature_" type="string" length="72" primaryKey="yes" modularize="column"
74 keyTable="Signature;RegLocator;IniLocator;DrLocator;CompLocator" keyColumn="1" category="identifier" description="The Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables."/>
75 </tableDefinition>
76 <tableDefinition name="Property" createSymbols="yes">
77 <columnDefinition name="Property" type="string" length="72" primaryKey="yes" modularize="column"
78 category="identifier" description="Name of property, uppercase if settable by launcher or loader."/>
79 <columnDefinition name="Value" type="localized" length="0" escapeIdtCharacters="yes"
80 category="text" description="String value for property. Never null or empty."/>
81 </tableDefinition>
82 <tableDefinition name="BBControl" createSymbols="yes">
83 <columnDefinition name="Billboard_" type="string" length="50" primaryKey="yes" modularize="column"
84 keyTable="Billboard" keyColumn="1" category="identifier" description="External key to the Billboard table, name of the billboard."/>
85 <columnDefinition name="BBControl" type="string" length="50" primaryKey="yes"
86 category="identifier" description="Name of the control. This name must be unique within a billboard, but can repeat on different billboard."/>
87 <columnDefinition name="Type" type="string" length="50"
88 category="identifier" description="The type of the control."/>
89 <columnDefinition name="X" type="number" length="2" localizable="yes"
90 minValue="0" maxValue="32767" description="Horizontal coordinate of the upper left corner of the bounding rectangle of the control."/>
91 <columnDefinition name="Y" type="number" length="2" localizable="yes"
92 minValue="0" maxValue="32767" description="Vertical coordinate of the upper left corner of the bounding rectangle of the control."/>
93 <columnDefinition name="Width" type="number" length="2" localizable="yes"
94 minValue="0" maxValue="32767" description="Width of the bounding rectangle of the control."/>
95 <columnDefinition name="Height" type="number" length="2" localizable="yes"
96 minValue="0" maxValue="32767" description="Height of the bounding rectangle of the control."/>
97 <columnDefinition name="Attributes" type="number" length="4" nullable="yes"
98 minValue="0" maxValue="2147483647" description="A 32-bit word that specifies the attribute flags to be applied to this control."/>
99 <columnDefinition name="Text" type="localized" length="50" nullable="yes" escapeIdtCharacters="yes"
100 category="text" description="A string used to set the initial text contained within a control (if appropriate)."/>
101 </tableDefinition>
102 <tableDefinition name="Billboard" createSymbols="yes">
103 <columnDefinition name="Billboard" type="string" length="50" primaryKey="yes" modularize="column"
104 category="identifier" description="Name of the billboard."/>
105 <columnDefinition name="Feature_" type="string" length="38"
106 keyTable="Feature" keyColumn="1" category="identifier" description="An external key to the Feature Table. The billboard is shown only if this feature is being installed."/>
107 <columnDefinition name="Action" type="string" length="50" nullable="yes"
108 category="identifier" description="The name of an action. The billboard is displayed during the progress messages received from this action."/>
109 <columnDefinition name="Ordering" type="number" length="2" nullable="yes"
110 minValue="0" maxValue="32767" description="A positive integer. If there is more than one billboard corresponding to an action they will be shown in the order defined by this column."/>
111 </tableDefinition>
112 <tableDefinition name="Feature" createSymbols="yes">
113 <columnDefinition name="Feature" type="string" length="38" primaryKey="yes"
114 category="identifier" description="Primary key used to identify a particular feature record."/>
115 <columnDefinition name="Feature_Parent" type="string" length="38" nullable="yes"
116 keyTable="Feature" keyColumn="1" category="identifier" description="Optional key of a parent record in the same table. If the parent is not selected, then the record will not be installed. Null indicates a root item."/>
117 <columnDefinition name="Title" type="localized" length="64" nullable="yes" escapeIdtCharacters="yes"
118 category="text" description="Short text identifying a visible feature item."/>
119 <columnDefinition name="Description" type="localized" length="255" nullable="yes" escapeIdtCharacters="yes"
120 category="text" description="Longer descriptive text describing a visible feature item."/>
121 <columnDefinition name="Display" type="number" length="2" nullable="yes"
122 minValue="0" maxValue="32767" description="Numeric sort order, used to force a specific display ordering."/>
123 <columnDefinition name="Level" type="number" length="2"
124 minValue="0" maxValue="32767" description="The install level at which record will be initially selected. An install level of 0 will disable an item and prevent its display."/>
125 <columnDefinition name="Directory_" type="string" length="72" nullable="yes" modularize="column"
126 keyTable="Directory" keyColumn="1" category="upperCase" description="The name of the Directory that can be configured by the UI. A non-null value will enable the browse button."/>
127 <columnDefinition name="Attributes" type="number" length="2"
128 set="0;1;2;4;5;6;8;9;10;16;17;18;20;21;22;24;25;26;32;33;34;36;37;38;48;49;50;52;53;54" description="Feature attributes"/>
129 </tableDefinition>
130 <tableDefinition name="Binary" createSymbols="yes">
131 <columnDefinition name="Name" type="string" length="72" primaryKey="yes" modularize="column"
132 category="identifier" description="Unique key identifying the binary data."/>
133 <columnDefinition name="Data" type="object" length="0"
134 category="binary" description="The unformatted binary data."/>
135 </tableDefinition>
136 <tableDefinition name="BindImage">
137 <columnDefinition name="File_" type="string" length="72" primaryKey="yes" modularize="column"
138 keyTable="File" keyColumn="1" category="identifier" description="The index into the File table. This must be an executable file."/>
139 <columnDefinition name="Path" type="string" length="255" nullable="yes" modularize="property"
140 category="paths" description="A list of ; delimited paths that represent the paths to be searched for the import DLLS. The list is usually a list of properties each enclosed within square brackets [] ."/>
141 </tableDefinition>
142 <tableDefinition name="File" createSymbols="yes">
143 <columnDefinition name="File" type="string" length="72" primaryKey="yes" modularize="column"
144 category="identifier" description="Primary key, non-localized token, must match identifier in cabinet. For uncompressed files, this field is ignored."/>
145 <columnDefinition name="Component_" type="string" length="72" modularize="column"
146 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key referencing Component that controls the file."/>
147 <columnDefinition name="FileName" type="localized" length="255"
148 category="filename" description="File name used for installation, may be localized. This may contain a &quot;short name|long name&quot; pair."/>
149 <columnDefinition name="FileSize" type="number" length="4"
150 minValue="0" maxValue="2147483647" description="Size of file in bytes (long integer)."/>
151 <columnDefinition name="Version" type="string" length="72" nullable="yes" modularize="companionFile"
152 keyTable="File" keyColumn="1" category="version" description="Version string for versioned files; Blank for unversioned files."/>
153 <columnDefinition name="Language" type="string" length="20" nullable="yes"
154 category="language" description="List of decimal language Ids, comma-separated if more than one."/>
155 <columnDefinition name="Attributes" type="number" length="2" nullable="yes"
156 minValue="0" maxValue="32767" description="Integer containing bit flags representing file attributes (with the decimal value of each bit position in parentheses)"/>
157 <columnDefinition name="Sequence" type="number" length="4"
158 minValue="1" maxValue="2147483647" description="Sequence with respect to the media images; order must track cabinet order."/>
159 </tableDefinition>
160 <tableDefinition name="CCPSearch">
161 <columnDefinition name="Signature_" type="string" length="72" primaryKey="yes"
162 keyTable="Signature;RegLocator;IniLocator;DrLocator;CompLocator" keyColumn="1" category="identifier" description="The Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables."/>
163 </tableDefinition>
164 <tableDefinition name="CheckBox" createSymbols="yes">
165 <columnDefinition name="Property" type="string" length="72" primaryKey="yes" modularize="column"
166 category="identifier" description="A named property to be tied to the item."/>
167 <columnDefinition name="Value" type="string" length="64" nullable="yes" modularize="property"
168 category="formatted" description="The value string associated with the item."/>
169 </tableDefinition>
170 <tableDefinition name="Class" createSymbols="yes">
171 <columnDefinition name="CLSID" type="string" length="38" primaryKey="yes"
172 category="guid" description="The CLSID of an OLE factory."/>
173 <columnDefinition name="Context" type="string" length="32" primaryKey="yes"
174 category="identifier" description="The numeric server context for this server. CLSCTX_xxxx"/>
175 <columnDefinition name="Component_" type="string" length="72" primaryKey="yes" modularize="column"
176 keyTable="Component" keyColumn="1" category="identifier" description="Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent."/>
177 <columnDefinition name="ProgId_Default" type="string" length="255" nullable="yes"
178 keyTable="ProgId" keyColumn="1" category="text" description="Optional ProgId associated with this CLSID."/>
179 <columnDefinition name="Description" type="localized" length="255" nullable="yes" escapeIdtCharacters="yes"
180 category="text" description="Localized description for the Class."/>
181 <columnDefinition name="AppId_" type="string" length="38" nullable="yes"
182 keyTable="AppId" keyColumn="1" category="guid" description="Optional AppID containing DCOM information for associated application (string GUID)."/>
183 <columnDefinition name="FileTypeMask" type="string" length="255" nullable="yes"
184 category="text" description="Optional string containing information for the HKCRthis CLSID) key. If multiple patterns exist, they must be delimited by a semicolon, and numeric subkeys will be generated: 0,1,2..."/>
185 <columnDefinition name="Icon_" type="string" length="72" nullable="yes" modularize="icon"
186 keyTable="Icon" keyColumn="1" category="identifier" description="Optional foreign key into the Icon Table, specifying the icon file associated with this CLSID. Will be written under the DefaultIcon key."/>
187 <columnDefinition name="IconIndex" type="number" length="2" nullable="yes"
188 minValue="-32767" maxValue="32767" description="Optional icon index."/>
189 <columnDefinition name="DefInprocHandler" type="string" length="32" nullable="yes"
190 category="filename" set="1;2;3" description="Optional default inproc handler. Only optionally provided if Context=CLSCTX_LOCAL_SERVER. Typically &quot;ole32.dll&quot; or &quot;mapi32.dll&quot;"/>
191 <columnDefinition name="Argument" type="string" length="255" nullable="yes"
192 category="formatted" description="optional argument for LocalServers."/>
193 <columnDefinition name="Feature_" type="string" length="38"
194 keyTable="Feature" keyColumn="1" category="identifier" description="Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational."/>
195 <columnDefinition name="Attributes" type="number" length="2" nullable="yes"
196 maxValue="32767" description="Class registration attributes."/>
197 </tableDefinition>
198 <tableDefinition name="Component" createSymbols="yes">
199 <columnDefinition name="Component" type="string" length="72" primaryKey="yes" modularize="column"
200 category="identifier" description="Primary key used to identify a particular component record."/>
201 <columnDefinition name="ComponentId" type="string" length="38" nullable="yes"
202 category="guid" description="A string GUID unique to this component, version, and language."/>
203 <columnDefinition name="Directory_" type="string" length="72" modularize="column"
204 keyTable="Directory" keyColumn="1" category="identifier" description="Required key of a Directory table record. This is actually a property name whose value contains the actual path, set either by the AppSearch action or with the default setting obtained from the Directory table."/>
205 <columnDefinition name="Attributes" type="number" length="2"
206 description="Remote execution option, one of irsEnum"/>
207 <columnDefinition name="Condition" type="string" length="255" nullable="yes" modularize="condition" localizable="yes"
208 category="condition" description="A conditional statement that will disable this component if the specified condition evaluates to the 'True' state. If a component is disabled, it will not be installed, regardless of the 'Action' state associated with the component."/>
209 <columnDefinition name="KeyPath" type="string" length="72" nullable="yes" modularize="column"
210 keyTable="File;Registry;ODBCDataSource" keyColumn="1" category="identifier" description="Either the primary key into the File table, Registry table, or ODBCDataSource table. This extract path is stored when the component is installed, and is used to detect the presence of the component and to return the path to it."/>
211 </tableDefinition>
212 <tableDefinition name="Icon" createSymbols="yes">
213 <columnDefinition name="Name" type="string" length="72" primaryKey="yes" modularize="icon"
214 category="identifier" description="Primary key. Name of the icon file."/>
215 <columnDefinition name="Data" type="object" length="0"
216 category="binary" description="Binary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format."/>
217 </tableDefinition>
218 <tableDefinition name="ProgId">
219 <columnDefinition name="ProgId" type="string" length="255" primaryKey="yes"
220 category="text" description="The Program Identifier. Primary key."/>
221 <columnDefinition name="ProgId_Parent" type="string" length="255" nullable="yes"
222 keyTable="ProgId" keyColumn="1" category="text" description="The Parent Program Identifier. If specified, the ProgId column becomes a version independent prog id."/>
223 <columnDefinition name="Class_" type="string" length="38" nullable="yes"
224 keyTable="Class" keyColumn="1" category="guid" description="The CLSID of an OLE factory corresponding to the ProgId."/>
225 <columnDefinition name="Description" type="localized" length="255" nullable="yes" escapeIdtCharacters="yes"
226 category="text" description="Localized description for the Program identifier."/>
227 <columnDefinition name="Icon_" type="string" length="72" nullable="yes" modularize="icon"
228 keyTable="Icon" keyColumn="1" category="identifier" description="Optional foreign key into the Icon Table, specifying the icon file associated with this ProgId. Will be written under the DefaultIcon key."/>
229 <columnDefinition name="IconIndex" type="number" length="2" nullable="yes"
230 minValue="-32767" maxValue="32767" description="Optional icon index."/>
231 </tableDefinition>
232 <tableDefinition name="ComboBox">
233 <columnDefinition name="Property" type="string" length="72" primaryKey="yes" modularize="column"
234 category="identifier" description="A named property to be tied to this item. All the items tied to the same property become part of the same combobox."/>
235 <columnDefinition name="Order" type="number" length="2" primaryKey="yes"
236 minValue="1" maxValue="32767" description="A positive integer used to determine the ordering of the items within one list. The integers do not have to be consecutive."/>
237 <columnDefinition name="Value" type="string" length="64" modularize="property" localizable="yes"
238 category="formatted" description="The value string associated with this item. Selecting the line will set the associated property to this value."/>
239 <columnDefinition name="Text" type="localized" length="64" nullable="yes" modularize="property" escapeIdtCharacters="yes"
240 category="formatted" description="The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value."/>
241 </tableDefinition>
242 <tableDefinition name="CompLocator">
243 <columnDefinition name="Signature_" type="string" length="72" primaryKey="yes" modularize="column"
244 category="identifier" description="The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table."/>
245 <columnDefinition name="ComponentId" type="string" length="38"
246 category="guid" description="A string GUID unique to this component, version, and language."/>
247 <columnDefinition name="Type" type="number" length="2" nullable="yes"
248 minValue="0" maxValue="1" description="A boolean value that determines if the registry value is a filename or a directory location."/>
249 </tableDefinition>
250 <tableDefinition name="Complus">
251 <columnDefinition name="Component_" type="string" length="72" primaryKey="yes" modularize="column"
252 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key referencing Component that controls the ComPlus component."/>
253 <columnDefinition name="ExpType" type="number" length="2" nullable="yes"
254 minValue="0" maxValue="32767" description="ComPlus component attributes."/>
255 </tableDefinition>
256 <tableDefinition name="Directory" createSymbols="yes">
257 <columnDefinition name="Directory" type="string" length="72" primaryKey="yes" modularize="column"
258 category="identifier" description="Unique identifier for directory entry, primary key. If a property by this name is defined, it contains the full path to the directory."/>
259 <columnDefinition name="Directory_Parent" type="string" length="72" nullable="yes" modularize="column"
260 keyTable="Directory" keyColumn="1" category="identifier" description="Reference to the entry in this table specifying the default parent directory. A record parented to itself or with a Null parent represents a root of the install tree."/>
261 <columnDefinition name="DefaultDir" type="localized" length="255"
262 category="defaultDir" description="The default sub-path under parent's path."/>
263 </tableDefinition>
264 <tableDefinition name="Control">
265 <columnDefinition name="Dialog_" type="string" length="72" primaryKey="yes" modularize="column"
266 keyTable="Dialog" keyColumn="1" category="identifier" description="External key to the Dialog table, name of the dialog."/>
267 <columnDefinition name="Control" type="string" length="50" primaryKey="yes"
268 category="identifier" description="Name of the control. This name must be unique within a dialog, but can repeat on different dialogs. "/>
269 <columnDefinition name="Type" type="string" length="20"
270 category="identifier" description="The type of the control."/>
271 <columnDefinition name="X" type="number" length="2" localizable="yes"
272 minValue="0" maxValue="32767" description="Horizontal coordinate of the upper left corner of the bounding rectangle of the control."/>
273 <columnDefinition name="Y" type="number" length="2" localizable="yes"
274 minValue="0" maxValue="32767" description="Vertical coordinate of the upper left corner of the bounding rectangle of the control."/>
275 <columnDefinition name="Width" type="number" length="2" localizable="yes"
276 minValue="0" maxValue="32767" description="Width of the bounding rectangle of the control."/>
277 <columnDefinition name="Height" type="number" length="2" localizable="yes"
278 minValue="0" maxValue="32767" description="Height of the bounding rectangle of the control."/>
279 <columnDefinition name="Attributes" type="number" length="4" nullable="yes"
280 minValue="0" maxValue="2147483647" description="A 32-bit word that specifies the attribute flags to be applied to this control."/>
281 <columnDefinition name="Property" type="string" length="72" nullable="yes" modularize="column"
282 category="identifier" description="The name of a defined property to be linked to this control. "/>
283 <columnDefinition name="Text" type="localized" length="0" nullable="yes" modularize="controlText" escapeIdtCharacters="yes"
284 category="formatted" description="A string used to set the initial text contained within a control (if appropriate)."/>
285 <columnDefinition name="Control_Next" type="string" length="50" nullable="yes"
286 keyTable="Control" keyColumn="2" category="identifier" description="The name of an other control on the same dialog. This link defines the tab order of the controls. The links have to form one or more cycles!"/>
287 <columnDefinition name="Help" type="localized" length="50" nullable="yes" escapeIdtCharacters="yes"
288 category="text" description="The help strings used with the button. The text is optional. "/>
289 </tableDefinition>
290 <tableDefinition name="Dialog" createSymbols="yes">
291 <columnDefinition name="Dialog" type="string" length="72" primaryKey="yes" modularize="column"
292 category="identifier" description="Name of the dialog."/>
293 <columnDefinition name="HCentering" type="number" length="2"
294 minValue="0" maxValue="100" description="Horizontal position of the dialog on a 0-100 scale. 0 means left end, 100 means right end of the screen, 50 center."/>
295 <columnDefinition name="VCentering" type="number" length="2"
296 minValue="0" maxValue="100" description="Vertical position of the dialog on a 0-100 scale. 0 means top end, 100 means bottom end of the screen, 50 center."/>
297 <columnDefinition name="Width" type="number" length="2"
298 minValue="0" maxValue="32767" description="Width of the bounding rectangle of the dialog."/>
299 <columnDefinition name="Height" type="number" length="2"
300 minValue="0" maxValue="32767" description="Height of the bounding rectangle of the dialog."/>
301 <columnDefinition name="Attributes" type="number" length="4" nullable="yes"
302 minValue="0" maxValue="2147483647" description="A 32-bit word that specifies the attribute flags to be applied to this dialog."/>
303 <columnDefinition name="Title" type="localized" length="128" nullable="yes" modularize="property" escapeIdtCharacters="yes"
304 category="formatted" description="A text string specifying the title to be displayed in the title bar of the dialog's window."/>
305 <columnDefinition name="Control_First" type="string" length="50"
306 keyTable="Control" keyColumn="2" category="identifier" description="Defines the control that has the focus when the dialog is created."/>
307 <columnDefinition name="Control_Default" type="string" length="50" nullable="yes"
308 keyTable="Control" keyColumn="2" category="identifier" description="Defines the default control. Hitting return is equivalent to pushing this button."/>
309 <columnDefinition name="Control_Cancel" type="string" length="50" nullable="yes"
310 keyTable="Control" keyColumn="2" category="identifier" description="Defines the cancel control. Hitting escape or clicking on the close icon on the dialog is equivalent to pushing this button."/>
311 </tableDefinition>
312 <tableDefinition name="ControlCondition">
313 <columnDefinition name="Dialog_" type="string" length="72" primaryKey="yes" modularize="column"
314 keyTable="Dialog" keyColumn="1" category="identifier" description="A foreign key to the Dialog table, name of the dialog."/>
315 <columnDefinition name="Control_" type="string" length="50" primaryKey="yes"
316 keyTable="Control" keyColumn="2" category="identifier" description="A foreign key to the Control table, name of the control."/>
317 <columnDefinition name="Action" type="string" length="50" primaryKey="yes"
318 set="Default;Disable;Enable;Hide;Show" description="The desired action to be taken on the specified control."/>
319 <columnDefinition name="Condition" type="string" length="255" primaryKey="yes" modularize="condition" localizable="yes"
320 category="condition" description="A standard conditional statement that specifies under which conditions the action should be triggered."/>
321 </tableDefinition>
322 <tableDefinition name="ControlEvent" createSymbols="yes">
323 <columnDefinition name="Dialog_" type="string" length="72" primaryKey="yes" modularize="column"
324 keyTable="Dialog" keyColumn="1" category="identifier" description="A foreign key to the Dialog table, name of the dialog."/>
325 <columnDefinition name="Control_" type="string" length="50" primaryKey="yes"
326 keyTable="Control" keyColumn="2" category="identifier" description="A foreign key to the Control table, name of the control"/>
327 <columnDefinition name="Event" type="string" length="50" primaryKey="yes" modularize="property"
328 category="formatted" description="An identifier that specifies the type of the event that should take place when the user interacts with control specified by the first two entries."/>
329 <columnDefinition name="Argument" type="string" length="255" primaryKey="yes" modularize="controlEventArgument" localizable="yes"
330 category="formatted" description="A value to be used as a modifier when triggering a particular event."/>
331 <columnDefinition name="Condition" type="string" length="255" primaryKey="yes" nullable="yes" modularize="condition" localizable="yes"
332 category="condition" description="A standard conditional statement that specifies under which conditions an event should be triggered."/>
333 <columnDefinition name="Ordering" type="number" length="2" nullable="yes"
334 minValue="0" maxValue="2147483647" description="An integer used to order several events tied to the same control. Can be left blank."/>
335 </tableDefinition>
336 <tableDefinition name="CreateFolder">
337 <columnDefinition name="Directory_" type="string" length="72" primaryKey="yes" modularize="column"
338 keyTable="Directory" keyColumn="1" category="identifier" description="Primary key, could be foreign key into the Directory table."/>
339 <columnDefinition name="Component_" type="string" length="72" primaryKey="yes" modularize="column"
340 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into the Component table."/>
341 </tableDefinition>
342 <tableDefinition name="CustomAction" createSymbols="yes">
343 <columnDefinition name="Action" type="string" length="72" primaryKey="yes" modularize="column"
344 category="identifier" description="Primary key, name of action, normally appears in sequence table unless private use."/>
345 <columnDefinition name="Type" type="number" length="2"
346 minValue="1" maxValue="32767" description="The numeric custom action type, consisting of source location, code type, entry, option flags."/>
347 <columnDefinition name="Source" type="string" length="72" nullable="yes" modularize="column"
348 category="customSource" description="The table reference of the source of the code."/>
349 <columnDefinition name="Target" type="string" length="255" nullable="yes" modularize="property" escapeIdtCharacters="yes" localizable="yes"
350 category="formatted" description="Excecution parameter, depends on the type of custom action"/>
351 <columnDefinition name="ExtendedType" type="number" length="4" nullable="yes" minValue="0" maxValue="2147483647"
352 description="A numeric custom action type that extends code type or option flags of the Type column."/>
353 </tableDefinition>
354 <tableDefinition name="DrLocator" createSymbols="yes">
355 <columnDefinition name="Signature_" type="string" length="72" primaryKey="yes" modularize="column"
356 category="identifier" description="The Signature_ represents a unique file signature and is also the foreign key in the Signature table."/>
357 <columnDefinition name="Parent" type="string" length="72" primaryKey="yes" nullable="yes" modularize="column"
358 category="identifier" description="The parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path."/>
359 <columnDefinition name="Path" type="string" length="255" primaryKey="yes" nullable="yes" modularize="property"
360 category="anyPath" description="The path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded."/>
361 <columnDefinition name="Depth" type="number" length="2" nullable="yes"
362 minValue="0" maxValue="32767" description="The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0."/>
363 </tableDefinition>
364 <tableDefinition name="DuplicateFile">
365 <columnDefinition name="FileKey" type="string" length="72" primaryKey="yes" modularize="column"
366 category="identifier" description="Primary key used to identify a particular file entry"/>
367 <columnDefinition name="Component_" type="string" length="72" modularize="column"
368 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key referencing Component that controls the duplicate file."/>
369 <columnDefinition name="File_" type="string" length="72" modularize="column"
370 keyTable="File" keyColumn="1" category="identifier" description="Foreign key referencing the source file to be duplicated."/>
371 <columnDefinition name="DestName" type="localized" length="255" nullable="yes"
372 category="filename" description="Filename to be given to the duplicate file."/>
373 <columnDefinition name="DestFolder" type="string" length="72" nullable="yes" modularize="column"
374 category="identifier" description="Name of a property whose value is assumed to resolve to the full pathname to a destination folder."/>
375 </tableDefinition>
376 <tableDefinition name="Environment">
377 <columnDefinition name="Environment" type="string" length="72" primaryKey="yes" modularize="column"
378 category="identifier" description="Unique identifier for the environmental variable setting"/>
379 <columnDefinition name="Name" type="localized" length="255"
380 category="text" description="The name of the environmental value."/>
381 <columnDefinition name="Value" type="localized" length="255" nullable="yes" modularize="property"
382 category="formatted" description="The value to set in the environmental settings."/>
383 <columnDefinition name="Component_" type="string" length="72" modularize="column"
384 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into the Component table referencing component that controls the installing of the environmental value."/>
385 </tableDefinition>
386 <tableDefinition name="Error" createSymbols="yes">
387 <columnDefinition name="Error" type="number" length="2" primaryKey="yes"
388 minValue="0" maxValue="32767" description="Integer error number, obtained from header file IError(...) macros."/>
389 <columnDefinition name="Message" type="localized" length="0" nullable="yes" escapeIdtCharacters="yes" useCData="yes" modularize="property"
390 category="template" description="Error formatting template, obtained from user ed. or localizers."/>
391 </tableDefinition>
392 <tableDefinition name="EventMapping">
393 <columnDefinition name="Dialog_" type="string" length="72" primaryKey="yes" modularize="column"
394 keyTable="Dialog" keyColumn="1" category="identifier" description="A foreign key to the Dialog table, name of the Dialog."/>
395 <columnDefinition name="Control_" type="string" length="50" primaryKey="yes"
396 keyTable="Control" keyColumn="2" category="identifier" description="A foreign key to the Control table, name of the control."/>
397 <columnDefinition name="Event" type="string" length="50" primaryKey="yes"
398 category="identifier" description="An identifier that specifies the type of the event that the control subscribes to."/>
399 <columnDefinition name="Attribute" type="string" length="50"
400 category="identifier" description="The name of the control attribute, that is set when this event is received."/>
401 </tableDefinition>
402 <tableDefinition name="Extension">
403 <columnDefinition name="Extension" type="string" length="255" primaryKey="yes"
404 category="text" description="The extension associated with the table row."/>
405 <columnDefinition name="Component_" type="string" length="72" primaryKey="yes" modularize="column"
406 keyTable="Component" keyColumn="1" category="identifier" description="Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent."/>
407 <columnDefinition name="ProgId_" type="string" length="255" nullable="yes"
408 keyTable="ProgId" keyColumn="1" category="text" description="Optional ProgId associated with this extension."/>
409 <columnDefinition name="MIME_" type="string" length="64" nullable="yes"
410 keyTable="MIME" keyColumn="1" category="text" description="Optional Context identifier, typically &quot;type/format&quot; associated with the extension"/>
411 <columnDefinition name="Feature_" type="string" length="38"
412 keyTable="Feature" keyColumn="1" category="identifier" description="Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational."/>
413 </tableDefinition>
414 <tableDefinition name="MIME">
415 <columnDefinition name="ContentType" type="string" length="64" primaryKey="yes"
416 category="text" description="Primary key. Context identifier, typically &quot;type/format&quot;."/>
417 <columnDefinition name="Extension_" type="string" length="255"
418 keyTable="Extension" keyColumn="1" category="text" description="Optional associated extension (without dot)"/>
419 <columnDefinition name="CLSID" type="string" length="38" nullable="yes"
420 category="guid" description="Optional associated CLSID."/>
421 </tableDefinition>
422 <tableDefinition name="FeatureComponents">
423 <columnDefinition name="Feature_" type="string" length="38" primaryKey="yes"
424 keyTable="Feature" keyColumn="1" category="identifier" description="Foreign key into Feature table."/>
425 <columnDefinition name="Component_" type="string" length="72" primaryKey="yes" modularize="column"
426 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into Component table."/>
427 </tableDefinition>
428 <tableDefinition name="FileSFPCatalog">
429 <columnDefinition name="File_" type="string" length="72" primaryKey="yes" modularize="column"
430 keyTable="File" keyColumn="1" category="identifier" description="File associated with the catalog"/>
431 <columnDefinition name="SFPCatalog_" type="string" length="255" primaryKey="yes"
432 keyTable="SFPCatalog" keyColumn="1" category="filename" description="Catalog associated with the file"/>
433 </tableDefinition>
434 <tableDefinition name="SFPCatalog">
435 <columnDefinition name="SFPCatalog" type="string" length="255" primaryKey="yes"
436 category="filename" description="File name for the catalog."/>
437 <columnDefinition name="Catalog" type="object" length="0"
438 category="binary" description="SFP Catalog"/>
439 <columnDefinition name="Dependency" type="string" length="0" nullable="yes" modularize="property"
440 category="formatted" description="Parent catalog - only used by SFP"/>
441 </tableDefinition>
442 <tableDefinition name="Font">
443 <columnDefinition name="File_" type="string" length="72" primaryKey="yes" modularize="column"
444 keyTable="File" keyColumn="1" category="identifier" description="Primary key, foreign key into File table referencing font file."/>
445 <columnDefinition name="FontTitle" type="string" length="128" nullable="yes"
446 category="text" description="Font name."/>
447 </tableDefinition>
448 <tableDefinition name="IniFile">
449 <columnDefinition name="IniFile" type="string" length="72" primaryKey="yes" modularize="column"
450 category="identifier" description="Primary key, non-localized token."/>
451 <columnDefinition name="FileName" type="localized" length="255"
452 category="filename" description="The .INI file name in which to write the information"/>
453 <columnDefinition name="DirProperty" type="string" length="72" nullable="yes" modularize="column"
454 category="identifier" description="Foreign key into the Directory table denoting the directory where the .INI file is."/>
455 <columnDefinition name="Section" type="localized" length="96" modularize="property"
456 category="formatted" description="The .INI file Section."/>
457 <columnDefinition name="Key" type="localized" length="128" modularize="property"
458 category="formatted" description="The .INI file key below Section."/>
459 <columnDefinition name="Value" type="localized" length="255" modularize="property" escapeIdtCharacters="yes"
460 category="formatted" description="The value to be written."/>
461 <columnDefinition name="Action" type="number" length="2"
462 set="0;1;3" description="The type of modification to be made, one of iifEnum"/>
463 <columnDefinition name="Component_" type="string" length="72" modularize="column"
464 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into the Component table referencing component that controls the installing of the .INI value."/>
465 </tableDefinition>
466 <tableDefinition name="IniLocator">
467 <columnDefinition name="Signature_" type="string" length="72" primaryKey="yes" modularize="column"
468 category="identifier" description="The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table."/>
469 <columnDefinition name="FileName" type="string" length="255"
470 category="filename" description="The .INI file name."/>
471 <columnDefinition name="Section" type="string" length="96"
472 category="text" description="Section name within in file (within square brackets in INI file)."/>
473 <columnDefinition name="Key" type="string" length="128"
474 category="text" description="Key value (followed by an equals sign in INI file)."/>
475 <columnDefinition name="Field" type="number" length="2" nullable="yes"
476 minValue="0" maxValue="32767" description="The field in the .INI line. If Field is null or 0 the entire line is read."/>
477 <columnDefinition name="Type" type="number" length="2" nullable="yes"
478 minValue="0" maxValue="2" description="An integer value that determines if the .INI value read is a filename or a directory location or to be used as is w/o interpretation."/>
479 </tableDefinition>
480 <tableDefinition name="InstallExecuteSequence">
481 <columnDefinition name="Action" type="string" length="72" primaryKey="yes"
482 category="identifier" description="Name of action to invoke, either in the engine or the handler DLL."/>
483 <columnDefinition name="Condition" type="string" length="255" nullable="yes" localizable="yes"
484 category="condition" description="Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData."/>
485 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
486 minValue="-4" maxValue="32767" description="Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action."/>
487 </tableDefinition>
488 <tableDefinition name="InstallUISequence">
489 <columnDefinition name="Action" type="string" length="72" primaryKey="yes"
490 category="identifier" description="Name of action to invoke, either in the engine or the handler DLL."/>
491 <columnDefinition name="Condition" type="string" length="255" nullable="yes" localizable="yes"
492 category="condition" description="Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData."/>
493 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
494 minValue="-4" maxValue="32767" description="Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action."/>
495 </tableDefinition>
496 <tableDefinition name="IsolatedComponent">
497 <columnDefinition name="Component_Shared" type="string" length="72" primaryKey="yes" modularize="column"
498 keyTable="Component" keyColumn="1" category="identifier" description="Key to Component table item to be isolated"/>
499 <columnDefinition name="Component_Application" type="string" length="72" primaryKey="yes" modularize="column"
500 keyTable="Component" keyColumn="1" category="identifier" description="Key to Component table item for application"/>
501 </tableDefinition>
502 <tableDefinition name="LaunchCondition">
503 <columnDefinition name="Condition" type="string" length="255" primaryKey="yes" localizable="yes"
504 category="condition" description="Expression which must evaluate to TRUE in order for install to commence."/>
505 <columnDefinition name="Description" type="localized" length="255" escapeIdtCharacters="yes"
506 category="formatted" description="Localizable text to display when condition fails and install must abort."/>
507 </tableDefinition>
508 <tableDefinition name="ListBox">
509 <columnDefinition name="Property" type="string" length="72" primaryKey="yes" modularize="column"
510 category="identifier" description="A named property to be tied to this item. All the items tied to the same property become part of the same listbox."/>
511 <columnDefinition name="Order" type="number" length="2" primaryKey="yes"
512 minValue="1" maxValue="32767" description="A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive."/>
513 <columnDefinition name="Value" type="string" length="64" modularize="property"
514 category="formatted" description="The value string associated with this item. Selecting the line will set the associated property to this value."/>
515 <columnDefinition name="Text" type="localized" length="64" nullable="yes" escapeIdtCharacters="yes"
516 category="text" description="The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value."/>
517 </tableDefinition>
518 <tableDefinition name="ListView">
519 <columnDefinition name="Property" type="string" length="72" primaryKey="yes" modularize="column"
520 category="identifier" description="A named property to be tied to this item. All the items tied to the same property become part of the same listview."/>
521 <columnDefinition name="Order" type="number" length="2" primaryKey="yes"
522 minValue="1" maxValue="32767" description="A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive."/>
523 <columnDefinition name="Value" type="string" length="64" modularize="property"
524 category="formatted" description="The value string associated with this item. Selecting the line will set the associated property to this value."/>
525 <columnDefinition name="Text" type="localized" length="64" nullable="yes" escapeIdtCharacters="yes" modularize="property"
526 category="formatted" description="The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value."/>
527 <columnDefinition name="Binary_" type="string" length="72" nullable="yes" modularize="column"
528 keyTable="Binary" keyColumn="1" category="identifier" description="The name of the icon to be displayed with the icon. The binary information is looked up from the Binary Table."/>
529 </tableDefinition>
530 <tableDefinition name="LockPermissions">
531 <columnDefinition name="LockObject" type="string" length="72" primaryKey="yes" modularize="column"
532 category="identifier" description="Foreign key into Registry or File table"/>
533 <columnDefinition name="Table" type="string" length="32" primaryKey="yes"
534 category="identifier" set="Directory;File;Registry" description="Reference to another table name"/>
535 <columnDefinition name="Domain" type="string" length="255" primaryKey="yes" nullable="yes" modularize="property"
536 category="formatted" description="Domain name for user whose permissions are being set. (usually a property)"/>
537 <columnDefinition name="User" type="string" length="255" primaryKey="yes" modularize="property"
538 category="formatted" description="User for permissions to be set. (usually a property)"/>
539 <columnDefinition name="Permission" type="number" length="4" nullable="yes"
540 minValue="-2147483647" maxValue="2147483647" description="Permission Access mask. Full Control = 268435456 (GENERIC_ALL = 0x10000000)"/>
541 </tableDefinition>
542 <tableDefinition name="MsiLockPermissionsEx">
543 <columnDefinition name="MsiLockPermissionsEx" type="string" length="72" primaryKey="yes" modularize="column"
544 category="identifier" description="Primary key, non-localized token"/>
545 <columnDefinition name="LockObject" type="string" length="72" modularize="column"
546 category="identifier" description="Foreign key into Registry, File, CreateFolder, or ServiceInstall table"/>
547 <columnDefinition name="Table" type="string" length="32"
548 category="identifier" set="CreateFolder;File;Registry;ServiceInstall" description="Reference to another table name"/>
549 <columnDefinition name="SDDLText" type="string" length="0" modularize="property"
550 category="formattedSddl" description="String to indicate permissions to be applied to the LockObject"/>
551 <columnDefinition name="Condition" type="string" length="255" modularize="property" nullable="yes"
552 category="formatted" description="Expression which must evaluate to TRUE in order for this set of permissions to be applied"/>
553 </tableDefinition>
554 <tableDefinition name="Media" createSymbols="yes">
555 <columnDefinition name="DiskId" type="number" length="2" primaryKey="yes"
556 minValue="1" maxValue="32767" description="Primary key, integer to determine sort order for table."/>
557 <columnDefinition name="LastSequence" type="number" length="4"
558 minValue="0" maxValue="2147483647" description="File sequence number for the last file for this media."/>
559 <columnDefinition name="DiskPrompt" type="localized" length="64" nullable="yes" escapeIdtCharacters="yes"
560 category="text" description="Disk name: the visible text actually printed on the disk. This will be used to prompt the user when this disk needs to be inserted."/>
561 <columnDefinition name="Cabinet" type="string" length="255" nullable="yes"
562 category="cabinet" description="If some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet."/>
563 <columnDefinition name="VolumeLabel" type="string" length="32" nullable="yes"
564 category="text" description="The label attributed to the volume."/>
565 <columnDefinition name="Source" type="string" length="72" nullable="yes"
566 category="property" description="The property defining the location of the cabinet file."/>
567 </tableDefinition>
568 <tableDefinition name="MoveFile">
569 <columnDefinition name="FileKey" type="string" length="72" primaryKey="yes" modularize="column"
570 category="identifier" description="Primary key that uniquely identifies a particular MoveFile record"/>
571 <columnDefinition name="Component_" type="string" length="72" modularize="column"
572 keyTable="Component" keyColumn="1" category="identifier" description="If this component is not &quot;selected&quot; for installation or removal, no action will be taken on the associated MoveFile entry"/>
573 <columnDefinition name="SourceName" type="localized" length="255" nullable="yes"
574 category="text" description="Name of the source file(s) to be moved or copied. Can contain the '*' or '?' wildcards."/>
575 <columnDefinition name="DestName" type="localized" length="255" nullable="yes"
576 category="filename" description="Name to be given to the original file after it is moved or copied. If blank, the destination file will be given the same name as the source file"/>
577 <columnDefinition name="SourceFolder" type="string" length="72" nullable="yes" modularize="column"
578 category="identifier" description="Name of a property whose value is assumed to resolve to the full path to the source directory"/>
579 <columnDefinition name="DestFolder" type="string" length="72" modularize="column"
580 category="identifier" description="Name of a property whose value is assumed to resolve to the full path to the destination directory"/>
581 <columnDefinition name="Options" type="number" length="2"
582 minValue="0" maxValue="1" description="Integer value specifying the MoveFile operating mode, one of imfoEnum"/>
583 </tableDefinition>
584 <tableDefinition name="MsiAssembly">
585 <columnDefinition name="Component_" type="string" length="72" primaryKey="yes" modularize="column"
586 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into Component table."/>
587 <columnDefinition name="Feature_" type="string" length="38"
588 keyTable="Feature" keyColumn="1" category="identifier" description="Foreign key into Feature table."/>
589 <columnDefinition name="File_Manifest" type="string" length="72" nullable="yes" modularize="column"
590 keyTable="File" keyColumn="1" category="identifier" description="Foreign key into the File table denoting the manifest file for the assembly."/>
591 <columnDefinition name="File_Application" type="string" length="72" nullable="yes" modularize="column"
592 keyTable="File" keyColumn="1" category="identifier" description="Foreign key into File table, denoting the application context for private assemblies. Null for global assemblies."/>
593 <columnDefinition name="Attributes" type="number" length="2" nullable="yes"
594 description="Assembly attributes"/>
595 </tableDefinition>
596 <tableDefinition name="MsiAssemblyName">
597 <columnDefinition name="Component_" type="string" length="72" primaryKey="yes" modularize="column"
598 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into Component table."/>
599 <columnDefinition name="Name" type="string" length="255" primaryKey="yes"
600 category="text" description="The name part of the name-value pairs for the assembly name."/>
601 <columnDefinition name="Value" type="string" length="255"
602 category="text" description="The value part of the name-value pairs for the assembly name."/>
603 </tableDefinition>
604 <tableDefinition name="MsiDigitalCertificate">
605 <columnDefinition name="DigitalCertificate" type="string" length="72" primaryKey="yes"
606 category="identifier" description="A unique identifier for the row"/>
607 <columnDefinition name="CertData" type="object" length="0"
608 category="binary" description="A certificate context blob for a signer certificate"/>
609 </tableDefinition>
610 <tableDefinition name="MsiDigitalSignature">
611 <columnDefinition name="Table" type="string" length="32" primaryKey="yes"
612 set="Media" description="Reference to another table name (only Media table is supported)"/>
613 <columnDefinition name="SignObject" type="string" length="72" primaryKey="yes"
614 category="text" description="Foreign key to Media table"/>
615 <columnDefinition name="DigitalCertificate_" type="string" length="72"
616 keyTable="MsiDigitalCertificate" keyColumn="1" category="identifier" description="Foreign key to MsiDigitalCertificate table identifying the signer certificate"/>
617 <columnDefinition name="Hash" type="object" length="0" nullable="yes"
618 category="binary" description="The encoded hash blob from the digital signature"/>
619 </tableDefinition>
620 <tableDefinition name="MsiEmbeddedChainer" createSymbols="yes">
621 <columnDefinition name="MsiEmbeddedChainer" type="string" length="72" primaryKey="yes" modularize="column"
622 category="identifier" description="The primary key for the table."/>
623 <columnDefinition name="Condition" type="string" length="255" nullable="yes" localizable="yes"
624 category="condition" description="A conditional statement for running the user-defined function."/>
625 <columnDefinition name="CommandLine" type="string" length="255" nullable="yes" modularize="property"
626 category="formatted" description="The value in this field is a part of the command line string passed to the executable file identified in the Source column."/>
627 <columnDefinition name="Source" type="string" length="72" modularize="column"
628 category="customSource" description="The location of the executable file for the user-defined function."/>
629 <columnDefinition name="Type" type="number" length="2"
630 set="2;18;50" description="The functions listed in the MsiEmbeddedChainer table are described using the following custom action numeric types."/>
631 </tableDefinition>
632 <tableDefinition name="MsiEmbeddedUI">
633 <columnDefinition name="MsiEmbeddedUI" type="string" length="72" primaryKey="yes" modularize="column"
634 category="identifier" description="The primary key for the table."/>
635 <columnDefinition name="FileName" type="localized" length="255"
636 category="text" description="The name of the file that receives the binary information in the Data column."/>
637 <columnDefinition name="Attributes" type="number" length="2"
638 set="0;1;2;3" description="Information about the data in the Data column."/>
639 <columnDefinition name="MessageFilter" type="number" length="4" nullable="yes"
640 description="Specifies the types of messages that are sent to the user interface DLL."/>
641 <columnDefinition name="Data" type="object" length="0"
642 category="binary" description="This column contains binary information."/>
643 </tableDefinition>
644 <tableDefinition name="MsiFileHash">
645 <columnDefinition name="File_" type="string" length="72" primaryKey="yes" modularize="column"
646 keyTable="File" keyColumn="1" category="identifier" description="Primary key, foreign key into File table referencing file with this hash"/>
647 <columnDefinition name="Options" type="number" length="2"
648 minValue="0" maxValue="32767" description="Various options and attributes for this hash."/>
649 <columnDefinition name="HashPart1" type="number" length="4"
650 description="Size of file in bytes (long integer)."/>
651 <columnDefinition name="HashPart2" type="number" length="4"
652 description="Size of file in bytes (long integer)."/>
653 <columnDefinition name="HashPart3" type="number" length="4"
654 description="Size of file in bytes (long integer)."/>
655 <columnDefinition name="HashPart4" type="number" length="4"
656 description="Size of file in bytes (long integer)."/>
657 </tableDefinition>
658 <tableDefinition name="MsiPackageCertificate">
659 <columnDefinition name="PackageCertificate" type="string" length="72" primaryKey="yes"
660 category="identifier" description="Primary key. A unique identifier for the row."/>
661 <columnDefinition name="DigitalCertificate_" type="string" length="72" primaryKey="yes"
662 keyTable="MsiDigitalCertificate" keyColumn="1" category="identifier" description="Foreign key to MsiDigitalCertificate table identifying the signer certificate."/>
663 </tableDefinition>
664 <tableDefinition name="MsiPatchCertificate">
665 <columnDefinition name="PatchCertificate" type="string" length="72" primaryKey="yes"
666 category="identifier" description="Primary key. A unique identifier for the row."/>
667 <columnDefinition name="DigitalCertificate_" type="string" length="72" primaryKey="yes"
668 keyTable="MsiDigitalCertificate" keyColumn="1" category="identifier" description="Foreign key to MsiDigitalCertificate table identifying the signer certificate."/>
669 </tableDefinition>
670 <tableDefinition name="MsiPatchHeaders">
671 <columnDefinition name="StreamRef" type="string" length="38" primaryKey="yes"
672 category="identifier" description="Primary key. A unique identifier for the row."/>
673 <columnDefinition name="Header" type="object" length="0"
674 category="binary" description="Binary stream. The patch header, used for patch validation."/>
675 </tableDefinition>
676 <tableDefinition name="PatchMetadata">
677 <columnDefinition name="Company" type="string" length="72" primaryKey="yes" nullable="yes"
678 category="identifier" description="Primary key. The name of the company."/>
679 <columnDefinition name="Property" type="string" length="72" primaryKey="yes"
680 category="identifier" description="Primary key. The name of the property."/>
681 <columnDefinition name="Value" type="localized" length="0" escapeIdtCharacters="yes"
682 category="text" description="Non-null, non-empty value of the metadata property."/>
683 </tableDefinition>
684 <tableDefinition name="MsiPatchMetadata">
685 <columnDefinition name="Company" type="string" length="72" primaryKey="yes" nullable="yes"
686 />
687 <columnDefinition name="Property" type="string" length="72" primaryKey="yes"
688 />
689 <columnDefinition name="Value" type="localized" length="0"
690 />
691 </tableDefinition>
692 <tableDefinition name="MsiPatchOldAssemblyFile">
693 <columnDefinition name="File_" type="string" length="72" primaryKey="yes" modularize="column"
694 keyTable="File" keyColumn="1" category="identifier" description="Foreign key into File table. Patch-only table."/>
695 <columnDefinition name="Assembly_" type="string" length="72" primaryKey="yes" modularize="column"
696 keyTable="MsiPatchOldAssemblyName" keyColumn="1" category="identifier" description="Foreign key into MsiPatchOldAssemblyName table."/>
697 </tableDefinition>
698 <tableDefinition name="MsiPatchOldAssemblyName">
699 <columnDefinition name="Assembly" type="string" length="72" primaryKey="yes" modularize="column"
700 category="identifier" description="A unique identifier for the row."/>
701 <columnDefinition name="Name" type="string" length="255" primaryKey="yes"
702 category="text" description="The name part of the name-value pairs for the assembly name. This represents the old name for the assembly."/>
703 <columnDefinition name="Value" type="string" length="255"
704 category="text" description="The value part of the name-value pairs for the assembly name. This represents the old name for the assembly."/>
705 </tableDefinition>
706 <tableDefinition name="PatchSequence">
707 <columnDefinition name="PatchFamily" type="string" length="72" primaryKey="yes"
708 category="identifier" description="Primary key. The name of the family for the patch."/>
709 <columnDefinition name="Target" type="string" length="72" primaryKey="yes" nullable="yes"
710 category="text" description="Primary key. Determines product code filtering for family."/>
711 <columnDefinition name="Sequence" type="string" length="72" nullable="yes"
712 category="text" description="Sequence information in version (x.x.x.x) format."/>
713 <columnDefinition name="Supersede" type="number" length="4" nullable="yes"
714 description="Indicates that this patch supersedes earlier patches."/>
715 </tableDefinition>
716 <tableDefinition name="MsiPatchSequence" createSymbols="yes">
717 <columnDefinition name="PatchFamily" type="string" length="72" primaryKey="yes"
718 />
719 <columnDefinition name="ProductCode" type="string" length="38" primaryKey="yes" nullable="yes"
720 />
721 <columnDefinition name="Sequence" type="string" length="72"
722 />
723 <columnDefinition name="Attributes" type="number" length="4" nullable="yes"
724 />
725 </tableDefinition>
726 <tableDefinition name="ODBCAttribute">
727 <columnDefinition name="Driver_" type="string" length="72" primaryKey="yes" modularize="column"
728 keyTable="ODBCDriver" keyColumn="1" category="identifier" description="Reference to ODBC driver in ODBCDriver table"/>
729 <columnDefinition name="Attribute" type="string" length="40" primaryKey="yes"
730 category="text" description="Name of ODBC driver attribute"/>
731 <columnDefinition name="Value" type="localized" length="255" nullable="yes"
732 category="formatted" description="Value for ODBC driver attribute"/>
733 </tableDefinition>
734 <tableDefinition name="ODBCDriver">
735 <columnDefinition name="Driver" type="string" length="72" primaryKey="yes" modularize="column"
736 category="identifier" description="Primary key, non-localized.internal token for driver"/>
737 <columnDefinition name="Component_" type="string" length="72" modularize="column"
738 keyTable="Component" keyColumn="1" category="identifier" description="Reference to associated component"/>
739 <columnDefinition name="Description" type="string" length="255"
740 category="text" description="Text used as registered name for driver, non-localized"/>
741 <columnDefinition name="File_" type="string" length="72" modularize="column"
742 keyTable="File" keyColumn="1" category="identifier" description="Reference to key driver file"/>
743 <columnDefinition name="File_Setup" type="string" length="72" nullable="yes" modularize="column"
744 keyTable="File" keyColumn="1" category="identifier" description="Optional reference to key driver setup DLL"/>
745 </tableDefinition>
746 <tableDefinition name="ODBCDataSource">
747 <columnDefinition name="DataSource" type="string" length="72" primaryKey="yes" modularize="column"
748 category="identifier" description="Primary key, non-localized.internal token for data source"/>
749 <columnDefinition name="Component_" type="string" length="72" modularize="column"
750 keyTable="Component" keyColumn="1" category="identifier" description="Reference to associated component"/>
751 <columnDefinition name="Description" type="string" length="255"
752 category="text" description="Text used as registered name for data source"/>
753 <columnDefinition name="DriverDescription" type="string" length="255"
754 category="text" description="Reference to driver description, may be existing driver"/>
755 <columnDefinition name="Registration" type="number" length="2"
756 minValue="0" maxValue="1" description="Registration option: 0=machine, 1=user, others t.b.d."/>
757 </tableDefinition>
758 <tableDefinition name="ODBCSourceAttribute">
759 <columnDefinition name="DataSource_" type="string" length="72" primaryKey="yes" modularize="column"
760 keyTable="ODBCDataSource" keyColumn="1" category="identifier" description="Reference to ODBC data source in ODBCDataSource table"/>
761 <columnDefinition name="Attribute" type="string" length="32" primaryKey="yes"
762 category="text" description="Name of ODBC data source attribute"/>
763 <columnDefinition name="Value" type="localized" length="255" nullable="yes"
764 category="formatted" description="Value for ODBC data source attribute"/>
765 </tableDefinition>
766 <tableDefinition name="ODBCTranslator">
767 <columnDefinition name="Translator" type="string" length="72" primaryKey="yes" modularize="column"
768 category="identifier" description="Primary key, non-localized.internal token for translator"/>
769 <columnDefinition name="Component_" type="string" length="72" modularize="column"
770 keyTable="Component" keyColumn="1" category="identifier" description="Reference to associated component"/>
771 <columnDefinition name="Description" type="string" length="255"
772 category="text" description="Text used as registered name for translator"/>
773 <columnDefinition name="File_" type="string" length="72" modularize="column"
774 keyTable="File" keyColumn="1" category="identifier" description="Reference to key translator file"/>
775 <columnDefinition name="File_Setup" type="string" length="72" nullable="yes" modularize="column"
776 keyTable="File" keyColumn="1" category="identifier" description="Optional reference to key translator setup DLL"/>
777 </tableDefinition>
778 <tableDefinition name="Patch">
779 <columnDefinition name="File_" type="string" length="72" primaryKey="yes" modularize="column"
780 category="identifier" description="Primary key, non-localized token, foreign key to File table, must match identifier in cabinet."/>
781 <columnDefinition name="Sequence" type="number" length="4" primaryKey="yes"
782 minValue="0" maxValue="2147483647" description="Primary key, sequence with respect to the media images; order must track cabinet order."/>
783 <columnDefinition name="PatchSize" type="number" length="4"
784 minValue="0" maxValue="2147483647" description="Size of patch in bytes (long integer)."/>
785 <columnDefinition name="Attributes" type="number" length="2"
786 minValue="0" maxValue="32767" description="Integer containing bit flags representing patch attributes"/>
787 <columnDefinition name="Header" type="object" length="0" nullable="yes"
788 category="binary" description="Binary stream. The patch header, used for patch validation."/>
789 <columnDefinition name="StreamRef_" type="string" length="38" nullable="yes"
790 category="identifier" description="Identifier. Foreign key to the StreamRef column of the MsiPatchHeaders table."/>
791 </tableDefinition>
792 <tableDefinition name="PatchPackage">
793 <columnDefinition name="PatchId" type="string" length="38" primaryKey="yes"
794 category="guid" description="A unique string GUID representing this patch."/>
795 <columnDefinition name="Media_" type="number" length="2"
796 minValue="0" maxValue="32767" description="Foreign key to DiskId column of Media table. Indicates the disk containing the patch package."/>
797 </tableDefinition>
798 <tableDefinition name="PublishComponent">
799 <columnDefinition name="ComponentId" type="string" length="38" primaryKey="yes"
800 category="guid" description="A string GUID that represents the component id that will be requested by the alien product."/>
801 <columnDefinition name="Qualifier" type="string" length="255" primaryKey="yes"
802 category="text" description="This is defined only when the ComponentId column is an Qualified Component Id. This is the Qualifier for ProvideComponentIndirect."/>
803 <columnDefinition name="Component_" type="string" length="72" primaryKey="yes" modularize="column"
804 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into the Component table."/>
805 <columnDefinition name="AppData" type="localized" length="0" nullable="yes" escapeIdtCharacters="yes"
806 category="text" description="This is localisable Application specific data that can be associated with a Qualified Component."/>
807 <columnDefinition name="Feature_" type="string" length="38"
808 keyTable="Feature" keyColumn="1" category="identifier" description="Foreign key into the Feature table."/>
809 </tableDefinition>
810 <tableDefinition name="RadioButton">
811 <columnDefinition name="Property" type="string" length="72" primaryKey="yes" modularize="column"
812 category="identifier" description="A named property to be tied to this radio button. All the buttons tied to the same property become part of the same group."/>
813 <columnDefinition name="Order" type="number" length="2" primaryKey="yes"
814 minValue="1" maxValue="32767" description="A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive."/>
815 <columnDefinition name="Value" type="string" length="64" modularize="property" escapeIdtCharacters="yes"
816 category="formatted" description="The value string associated with this button. Selecting the button will set the associated property to this value."/>
817 <columnDefinition name="X" type="number" length="2" localizable="yes"
818 minValue="0" maxValue="32767" description="The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button."/>
819 <columnDefinition name="Y" type="number" length="2" localizable="yes"
820 minValue="0" maxValue="32767" description="The vertical coordinate of the upper left corner of the bounding rectangle of the radio button."/>
821 <columnDefinition name="Width" type="number" length="2" localizable="yes"
822 minValue="0" maxValue="32767" description="The width of the button."/>
823 <columnDefinition name="Height" type="number" length="2" localizable="yes"
824 minValue="0" maxValue="32767" description="The height of the button."/>
825 <columnDefinition name="Text" type="localized" length="0" nullable="yes" escapeIdtCharacters="yes"
826 category="text" description="The visible title to be assigned to the radio button."/>
827 <columnDefinition name="Help" type="localized" length="50" nullable="yes" escapeIdtCharacters="yes"
828 category="text" description="The help strings used with the button. The text is optional."/>
829 </tableDefinition>
830 <tableDefinition name="Registry">
831 <columnDefinition name="Registry" type="string" length="72" primaryKey="yes" modularize="column"
832 category="identifier" description="Primary key, non-localized token."/>
833 <columnDefinition name="Root" type="number" length="2"
834 minValue="-1" maxValue="3" description="The predefined root key for the registry value, one of rrkEnum."/>
835 <columnDefinition name="Key" type="localized" length="255" modularize="property"
836 category="regPath" description="The key for the registry value."/>
837 <columnDefinition name="Name" type="localized" length="255" nullable="yes" modularize="property"
838 category="formatted" description="The registry value name."/>
839 <columnDefinition name="Value" type="localized" length="0" nullable="yes" modularize="property" escapeIdtCharacters="yes"
840 category="formatted" description="The registry value."/>
841 <columnDefinition name="Component_" type="string" length="72" modularize="column"
842 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into the Component table referencing component that controls the installing of the registry value."/>
843 </tableDefinition>
844 <tableDefinition name="RegLocator" createSymbols="yes">
845 <columnDefinition name="Signature_" type="string" length="72" primaryKey="yes" modularize="column"
846 category="identifier" description="The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. If the type is 0, the registry values refers a directory, and _Signature is not a foreign key."/>
847 <columnDefinition name="Root" type="number" length="2"
848 minValue="0" maxValue="3" description="The predefined root key for the registry value, one of rrkEnum."/>
849 <columnDefinition name="Key" type="string" length="255" modularize="property" localizable="yes"
850 category="regPath" description="The key for the registry value."/>
851 <columnDefinition name="Name" type="string" length="255" nullable="yes" modularize="property" localizable="yes"
852 category="formatted" description="The registry value name."/>
853 <columnDefinition name="Type" type="number" length="2" nullable="yes"
854 minValue="0" maxValue="18" description="An integer value that determines if the registry value is a filename or a directory location or to be used as is w/o interpretation."/>
855 </tableDefinition>
856 <tableDefinition name="RemoveFile">
857 <columnDefinition name="FileKey" type="string" length="72" primaryKey="yes" modularize="column"
858 category="identifier" description="Primary key used to identify a particular file entry"/>
859 <columnDefinition name="Component_" type="string" length="72" modularize="column"
860 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key referencing Component that controls the file to be removed."/>
861 <columnDefinition name="FileName" type="localized" length="255" nullable="yes"
862 category="wildCardFilename" description="Name of the file to be removed."/>
863 <columnDefinition name="DirProperty" type="string" length="72" modularize="column"
864 category="identifier" description="Name of a property whose value is assumed to resolve to the full pathname to the folder of the file to be removed."/>
865 <columnDefinition name="InstallMode" type="number" length="2"
866 set="1;2;3" description="Installation option, one of iimEnum."/>
867 </tableDefinition>
868 <tableDefinition name="RemoveIniFile">
869 <columnDefinition name="RemoveIniFile" type="string" length="72" primaryKey="yes" modularize="column"
870 category="identifier" description="Primary key, non-localized token."/>
871 <columnDefinition name="FileName" type="localized" length="255"
872 category="filename" description="The .INI file name in which to delete the information"/>
873 <columnDefinition name="DirProperty" type="string" length="72" nullable="yes" modularize="column"
874 category="identifier" description="Foreign key into the Directory table denoting the directory where the .INI file is."/>
875 <columnDefinition name="Section" type="localized" length="96" modularize="property"
876 category="formatted" description="The .INI file Section."/>
877 <columnDefinition name="Key" type="localized" length="128" modularize="property"
878 category="formatted" description="The .INI file key below Section."/>
879 <columnDefinition name="Value" type="localized" length="255" nullable="yes" modularize="property"
880 category="formatted" description="The value to be deleted. The value is required when Action is iifIniRemoveTag"/>
881 <columnDefinition name="Action" type="number" length="2"
882 set="2;4" description="The type of modification to be made, one of iifEnum."/>
883 <columnDefinition name="Component_" type="string" length="72" modularize="column"
884 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into the Component table referencing component that controls the deletion of the .INI value."/>
885 </tableDefinition>
886 <tableDefinition name="RemoveRegistry">
887 <columnDefinition name="RemoveRegistry" type="string" length="72" primaryKey="yes" modularize="column"
888 category="identifier" description="Primary key, non-localized token."/>
889 <columnDefinition name="Root" type="number" length="2"
890 minValue="-1" maxValue="3" description="The predefined root key for the registry value, one of rrkEnum"/>
891 <columnDefinition name="Key" type="localized" length="255" modularize="property"
892 category="regPath" description="The key for the registry value."/>
893 <columnDefinition name="Name" type="localized" length="255" nullable="yes" modularize="property"
894 category="formatted" description="The registry value name."/>
895 <columnDefinition name="Component_" type="string" length="72" modularize="column"
896 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into the Component table referencing component that controls the deletion of the registry value."/>
897 </tableDefinition>
898 <tableDefinition name="ReserveCost">
899 <columnDefinition name="ReserveKey" type="string" length="72" primaryKey="yes" modularize="column"
900 category="identifier" description="Primary key that uniquely identifies a particular ReserveCost record"/>
901 <columnDefinition name="Component_" type="string" length="72" modularize="column"
902 keyTable="Component" keyColumn="1" category="identifier" description="Reserve a specified amount of space if this component is to be installed."/>
903 <columnDefinition name="ReserveFolder" type="string" length="72" nullable="yes" modularize="column"
904 category="identifier" description="Name of a property whose value is assumed to resolve to the full path to the destination directory"/>
905 <columnDefinition name="ReserveLocal" type="number" length="4"
906 minValue="0" maxValue="2147483647" description="Disk space to reserve if linked component is installed locally."/>
907 <columnDefinition name="ReserveSource" type="number" length="4"
908 minValue="0" maxValue="2147483647" description="Disk space to reserve if linked component is installed to run from the source location."/>
909 </tableDefinition>
910 <tableDefinition name="SelfReg">
911 <columnDefinition name="File_" type="string" length="72" primaryKey="yes" modularize="column"
912 keyTable="File" keyColumn="1" category="identifier" description="Foreign key into the File table denoting the module that needs to be registered."/>
913 <columnDefinition name="Cost" type="number" length="2" nullable="yes"
914 minValue="0" maxValue="32767" description="The cost of registering the module."/>
915 </tableDefinition>
916 <tableDefinition name="ServiceControl">
917 <columnDefinition name="ServiceControl" type="string" length="72" primaryKey="yes" modularize="column"
918 category="identifier" description="Primary key, non-localized token."/>
919 <columnDefinition name="Name" type="localized" length="255" modularize="property"
920 category="formatted" description="Name of a service. /, \, comma and space are invalid"/>
921 <columnDefinition name="Event" type="number" length="2"
922 minValue="0" maxValue="187" description="Bit field: Install: 0x1 = Start, 0x2 = Stop, 0x8 = Delete, Uninstall: 0x10 = Start, 0x20 = Stop, 0x80 = Delete"/>
923 <columnDefinition name="Arguments" type="localized" length="255" nullable="yes" modularize="property"
924 category="formatted" description="Arguments for the service. Separate by [~]."/>
925 <columnDefinition name="Wait" type="number" length="2" nullable="yes"
926 minValue="0" maxValue="1" description="Boolean for whether to wait for the service to fully start"/>
927 <columnDefinition name="Component_" type="string" length="72" modularize="column"
928 keyTable="Component" keyColumn="1" category="identifier" description="Required foreign key into the Component Table that controls the startup of the service"/>
929 </tableDefinition>
930 <tableDefinition name="ServiceInstall">
931 <columnDefinition name="ServiceInstall" type="string" length="72" primaryKey="yes" modularize="column"
932 category="identifier" description="Primary key, non-localized token."/>
933 <columnDefinition name="Name" type="string" length="255" modularize="property"
934 category="formatted" description="Internal Name of the Service"/>
935 <columnDefinition name="DisplayName" type="localized" length="255" nullable="yes" escapeIdtCharacters="yes" modularize="property"
936 category="formatted" description="External Name of the Service"/>
937 <columnDefinition name="ServiceType" type="number" length="4"
938 minValue="-2147483647" maxValue="2147483647" description="Type of the service"/>
939 <columnDefinition name="StartType" type="number" length="4"
940 minValue="0" maxValue="4" description="Type of the service"/>
941 <columnDefinition name="ErrorControl" type="number" length="4"
942 minValue="-2147483647" maxValue="2147483647" description="Severity of error if service fails to start"/>
943 <columnDefinition name="LoadOrderGroup" type="string" length="255" nullable="yes" modularize="property"
944 category="formatted" description="LoadOrderGroup"/>
945 <columnDefinition name="Dependencies" type="string" length="255" nullable="yes" modularize="property"
946 category="formatted" description="Other services this depends on to start. Separate by [~], and end with [~][~]"/>
947 <columnDefinition name="StartName" type="string" length="255" nullable="yes" modularize="property"
948 category="formatted" description="User or object name to run service as"/>
949 <columnDefinition name="Password" type="string" length="255" nullable="yes" modularize="property"
950 category="formatted" description="password to run service with. (with StartName)"/>
951 <columnDefinition name="Arguments" type="string" length="255" nullable="yes" modularize="property"
952 category="formatted" description="Arguments to include in every start of the service, passed to WinMain"/>
953 <columnDefinition name="Component_" type="string" length="72" modularize="column"
954 keyTable="Component" keyColumn="1" category="identifier" description="Required foreign key into the Component Table that controls the startup of the service"/>
955 <columnDefinition name="Description" type="localized" length="255" nullable="yes" escapeIdtCharacters="yes" modularize="property"
956 category="text" description="Description of service."/>
957 </tableDefinition>
958 <tableDefinition name="MsiServiceConfig">
959 <columnDefinition name="MsiServiceConfig" type="string" length="72" primaryKey="yes" modularize="column"
960 category="identifier" description="Primary key, non-localized token."/>
961 <columnDefinition name="Name" type="localized" length="255" modularize="property"
962 category="formatted" description="Name of a service. /, \, comma and space are invalid"/>
963 <columnDefinition name="Event" type="number" length="2"
964 minValue="0" maxValue="7" description="Bit field: 0x1 = Install, 0x2 = Uninstall, 0x4 = Reinstall"/>
965 <columnDefinition name="ConfigType" type="number" length="4"
966 minValue="-2147483647" maxValue="2147483647" description="Service Configuration Option"/>
967 <columnDefinition name="Argument" type="string" length="0" nullable="yes"
968 category="text" description="Argument(s) for service configuration. Value depends on the content of the ConfigType field"/>
969 <columnDefinition name="Component_" type="string" length="72" modularize="column"
970 keyTable="Component" keyColumn="1" category="identifier" description="Required foreign key into the Component Table that controls the configuration of the service"/>
971 </tableDefinition>
972 <tableDefinition name="MsiServiceConfigFailureActions">
973 <columnDefinition name="MsiServiceConfigFailureActions" type="string" length="72" primaryKey="yes" modularize="column"
974 category="identifier" description="Primary key, non-localized token"/>
975 <columnDefinition name="Name" type="localized" length="255" modularize="property"
976 category="formatted" description="Name of a service. /, \, comma and space are invalid"/>
977 <columnDefinition name="Event" type="number" length="2"
978 minValue="0" maxValue="7" description="Bit field: 0x1 = Install, 0x2 = Uninstall, 0x4 = Reinstall"/>
979 <columnDefinition name="ResetPeriod" type="number" length="4" nullable="yes"
980 minValue="0" maxValue="2147483647" description="Time in seconds after which to reset the failure count to zero. Leave blank if it should never be reset"/>
981 <columnDefinition name="RebootMessage" type="localized" length="255" nullable="yes"
982 category="formatted" description="Message to be broadcast to server users before rebooting"/>
983 <columnDefinition name="Command" type="localized" length="255" nullable="yes"
984 category="formatted" description="Command line of the process to CreateProcess function to execute"/>
985 <columnDefinition name="Actions" type="string" length="0" nullable="yes"
986 category="text" description="A list of integer actions separated by [~] delimiters: 0 = SC_ACTION_NONE, 1 = SC_ACTION_RESTART, 2 = SC_ACTION_REBOOT, 3 = SC_ACTION_RUN_COMMAND. Terminate with [~][~]"/>
987 <columnDefinition name="DelayActions" type="string" length="0" nullable="yes"
988 category="text" description="A list of delays (time in milli-seconds), separated by [~] delmiters, to wait before taking the corresponding Action. Terminate with [~][~]"/>
989 <columnDefinition name="Component_" type="string" length="72" modularize="column"
990 keyTable="Component" keyColumn="1" category="identifier" description="Required foreign key into the Component Table that controls the configuration of failure actions for the service"/>
991 </tableDefinition>
992 <tableDefinition name="Shortcut">
993 <columnDefinition name="Shortcut" type="string" length="72" primaryKey="yes" modularize="column"
994 category="identifier" description="Primary key, non-localized token."/>
995 <columnDefinition name="Directory_" type="string" length="72" modularize="column"
996 keyTable="Directory" keyColumn="1" category="identifier" description="Foreign key into the Directory table denoting the directory where the shortcut file is created."/>
997 <columnDefinition name="Name" type="localized" length="128"
998 category="filename" description="The name of the shortcut to be created."/>
999 <columnDefinition name="Component_" type="string" length="72" modularize="column"
1000 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into the Component table denoting the component whose selection gates the the shortcut creation/deletion."/>
1001 <columnDefinition name="Target" type="string" length="72" modularize="property"
1002 category="shortcut" description="The shortcut target. This is usually a property that is expanded to a file or a folder that the shortcut points to."/>
1003 <columnDefinition name="Arguments" type="string" length="255" nullable="yes" modularize="property"
1004 category="formatted" description="The command-line arguments for the shortcut."/>
1005 <columnDefinition name="Description" type="localized" length="255" nullable="yes" escapeIdtCharacters="yes"
1006 category="text" description="The description for the shortcut."/>
1007 <columnDefinition name="Hotkey" type="number" length="2" nullable="yes"
1008 minValue="0" maxValue="32767" description="The hotkey for the shortcut. It has the virtual-key code for the key in the low-order byte, and the modifier flags in the high-order byte. "/>
1009 <columnDefinition name="Icon_" type="string" length="72" nullable="yes" modularize="icon"
1010 keyTable="Icon" keyColumn="1" category="identifier" description="Foreign key into the File table denoting the external icon file for the shortcut."/>
1011 <columnDefinition name="IconIndex" type="number" length="2" nullable="yes"
1012 minValue="-32767" maxValue="32767" description="The icon index for the shortcut."/>
1013 <columnDefinition name="ShowCmd" type="number" length="2" nullable="yes"
1014 set="1;3;7" description="The show command for the application window.The following values may be used."/>
1015 <columnDefinition name="WkDir" type="string" length="72" nullable="yes" modularize="column"
1016 category="identifier" description="Name of property defining location of working directory."/>
1017 <columnDefinition name="DisplayResourceDLL" type="string" length="255" nullable="yes" modularize="property"
1018 category="formatted" description="The Formatted string providing the full path to the language neutral file containing the MUI Manifest."/>
1019 <columnDefinition name="DisplayResourceId" type="number" length="2" nullable="yes"
1020 minValue="0" maxValue="32767" description="The display name index for the shortcut. This must be a non-negative number."/>
1021 <columnDefinition name="DescriptionResourceDLL" type="string" length="255" nullable="yes" modularize="property"
1022 category="formatted" description="The Formatted string providing the full path to the language neutral file containing the MUI Manifest."/>
1023 <columnDefinition name="DescriptionResourceId" type="number" length="2" nullable="yes"
1024 minValue="0" maxValue="32767" description="The description name index for the shortcut. This must be a non-negative number."/>
1025 </tableDefinition>
1026 <tableDefinition name="MsiShortcutProperty">
1027 <columnDefinition name="MsiShortcutProperty" type="string" length="72" primaryKey="yes" modularize="column"
1028 category="identifier" description="Primary key, non-localized token"/>
1029 <columnDefinition name="Shortcut_" type="string" length="72" modularize="column"
1030 keyTable="Shortcut" keyColumn="1" category="identifier" description="Foreign key into the Shortcut table"/>
1031 <columnDefinition name="PropertyKey" type="string" length="0" modularize="property"
1032 category="formatted" description="Canonical string representation of the Property Key being set"/>
1033 <columnDefinition name="PropVariantValue" type="string" length="0" modularize="property"
1034 category="formatted" description="String representation of the value in the property"/>
1035 </tableDefinition>
1036 <tableDefinition name="Signature" createSymbols="yes">
1037 <columnDefinition name="Signature" type="string" length="72" primaryKey="yes" modularize="column"
1038 category="identifier" description="The table key. The Signature represents a unique file signature."/>
1039 <columnDefinition name="FileName" type="string" length="255"
1040 category="text" description="The name of the file. This may contain a &quot;short name|long name&quot; pair."/>
1041 <columnDefinition name="MinVersion" type="string" length="20" nullable="yes"
1042 category="text" description="The minimum version of the file."/>
1043 <columnDefinition name="MaxVersion" type="string" length="20" nullable="yes"
1044 category="text" description="The maximum version of the file."/>
1045 <columnDefinition name="MinSize" type="number" length="4" nullable="yes"
1046 minValue="0" maxValue="2147483647" description="The minimum size of the file."/>
1047 <columnDefinition name="MaxSize" type="number" length="4" nullable="yes"
1048 minValue="0" maxValue="2147483647" description="The maximum size of the file. "/>
1049 <columnDefinition name="MinDate" type="number" length="4" nullable="yes"
1050 minValue="0" maxValue="2147483647" description="The minimum creation date of the file."/>
1051 <columnDefinition name="MaxDate" type="number" length="4" nullable="yes"
1052 minValue="0" maxValue="2147483647" description="The maximum creation date of the file."/>
1053 <columnDefinition name="Languages" type="string" length="255" nullable="yes"
1054 category="language" description="The languages supported by the file."/>
1055 </tableDefinition>
1056 <tableDefinition name="TextStyle">
1057 <columnDefinition name="TextStyle" type="string" length="72" primaryKey="yes"
1058 category="identifier" description="Name of the style. The primary key of this table. This name is embedded in the texts to indicate a style change."/>
1059 <columnDefinition name="FaceName" type="string" length="32" localizable="yes"
1060 category="text" description="A string indicating the name of the font used. Required. The string must be at most 31 characters long."/>
1061 <columnDefinition name="Size" type="number" length="2" localizable="yes"
1062 minValue="0" maxValue="32767" description="The size of the font used. This size is given in our units (1/12 of the system font height). Assuming that the system font is set to 12 point size, this is equivalent to the point size."/>
1063 <columnDefinition name="Color" type="number" length="4" nullable="yes"
1064 minValue="0" maxValue="16777215" description="A long integer indicating the color of the string in the RGB format (Red, Green, Blue each 0-255, RGB = R + 256*G + 256^2*B)."/>
1065 <columnDefinition name="StyleBits" type="number" length="2" nullable="yes"
1066 minValue="0" maxValue="15" description="A combination of style bits."/>
1067 </tableDefinition>
1068 <tableDefinition name="TypeLib">
1069 <columnDefinition name="LibID" type="string" length="38" primaryKey="yes"
1070 category="guid" description="The GUID that represents the library."/>
1071 <columnDefinition name="Language" type="number" length="2" primaryKey="yes"
1072 minValue="0" maxValue="32767" description="The language of the library."/>
1073 <columnDefinition name="Component_" type="string" length="72" primaryKey="yes" modularize="column"
1074 keyTable="Component" keyColumn="1" category="identifier" description="Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent."/>
1075 <columnDefinition name="Version" type="number" length="4" nullable="yes"
1076 minValue="0" maxValue="16777215" description="The version of the library. The minor version is in the lower 8 bits of the integer. The major version is in the next 16 bits. "/>
1077 <columnDefinition name="Description" type="localized" length="128" nullable="yes" escapeIdtCharacters="yes"
1078 category="text"/>
1079 <columnDefinition name="Directory_" type="string" length="72" nullable="yes" modularize="column"
1080 keyTable="Directory" keyColumn="1" category="identifier" description="Optional. The foreign key into the Directory table denoting the path to the help file for the type library."/>
1081 <columnDefinition name="Feature_" type="string" length="38"
1082 keyTable="Feature" keyColumn="1" category="identifier" description="Required foreign key into the Feature Table, specifying the feature to validate or install in order for the type library to be operational."/>
1083 <columnDefinition name="Cost" type="number" length="4" nullable="yes"
1084 minValue="0" maxValue="2147483647" description="The cost associated with the registration of the typelib. This column is currently optional."/>
1085 </tableDefinition>
1086 <tableDefinition name="UIText">
1087 <columnDefinition name="Key" type="string" length="72" primaryKey="yes"
1088 category="identifier" description="A unique key that identifies the particular string."/>
1089 <columnDefinition name="Text" type="localized" length="255" nullable="yes" escapeIdtCharacters="yes"
1090 category="text" description="The localized version of the string."/>
1091 </tableDefinition>
1092 <tableDefinition name="Upgrade">
1093 <columnDefinition name="UpgradeCode" type="string" length="38" primaryKey="yes"
1094 category="guid" description="The UpgradeCode GUID belonging to the products in this set."/>
1095 <columnDefinition name="VersionMin" type="string" length="20" primaryKey="yes" nullable="yes"
1096 category="text" description="The minimum ProductVersion of the products in this set. The set may or may not include products with this particular version."/>
1097 <columnDefinition name="VersionMax" type="string" length="20" primaryKey="yes" nullable="yes"
1098 category="text" description="The maximum ProductVersion of the products in this set. The set may or may not include products with this particular version."/>
1099 <columnDefinition name="Language" type="string" length="255" primaryKey="yes" nullable="yes" localizable="yes"
1100 category="language" description="A comma-separated list of languages for either products in this set or products not in this set."/>
1101 <columnDefinition name="Attributes" type="number" length="4" primaryKey="yes"
1102 minValue="0" maxValue="2147483647" description="The attributes of this product set."/>
1103 <columnDefinition name="Remove" type="string" length="255" nullable="yes"
1104 category="formatted" description="The list of features to remove when uninstalling a product from this set. The default is &quot;ALL&quot;."/>
1105 <columnDefinition name="ActionProperty" type="string" length="72"
1106 category="upperCase" description="The property to set when a product in this set is found."/>
1107 </tableDefinition>
1108 <tableDefinition name="Verb">
1109 <columnDefinition name="Extension_" type="string" length="255" primaryKey="yes"
1110 keyTable="Extension" keyColumn="1" category="text" description="The extension associated with the table row."/>
1111 <columnDefinition name="Verb" type="string" length="32" primaryKey="yes"
1112 category="text" description="The verb for the command."/>
1113 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
1114 minValue="0" maxValue="32767" description="Order within the verbs for a particular extension. Also used simply to specify the default verb."/>
1115 <columnDefinition name="Command" type="localized" length="255" nullable="yes" modularize="property"
1116 category="formatted" description="The command text."/>
1117 <columnDefinition name="Argument" type="localized" length="255" nullable="yes" modularize="property"
1118 category="formatted" description="Optional value for the command arguments."/>
1119 </tableDefinition>
1120 <!-- Merge Module -->
1121 <tableDefinition name="ModuleAdminExecuteSequence">
1122 <columnDefinition name="Action" type="string" length="64" primaryKey="yes" modularize="column"
1123 category="identifier" description="Action to insert"/>
1124 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
1125 minValue="-4" maxValue="32767" description="Standard Sequence number"/>
1126 <columnDefinition name="BaseAction" type="string" length="64" nullable="yes" modularize="column"
1127 keyTable="ModuleAdminExecuteSequence" keyColumn="1" category="identifier" description="Base action to determine insert location."/>
1128 <columnDefinition name="After" type="number" length="2" nullable="yes"
1129 minValue="0" maxValue="1" description="Before (0) or After (1)"/>
1130 <columnDefinition name="Condition" type="string" length="255" nullable="yes" modularize="condition" localizable="yes"
1131 category="condition"/>
1132 </tableDefinition>
1133 <tableDefinition name="ModuleAdminUISequence">
1134 <columnDefinition name="Action" type="string" length="64" primaryKey="yes" modularize="column"
1135 category="identifier" description="Action to insert"/>
1136 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
1137 minValue="-4" maxValue="32767" description="Standard Sequence number"/>
1138 <columnDefinition name="BaseAction" type="string" length="64" nullable="yes" modularize="column"
1139 keyTable="ModuleAdminUISequence" keyColumn="1" category="identifier" description="Base action to determine insert location."/>
1140 <columnDefinition name="After" type="number" length="2" nullable="yes"
1141 minValue="0" maxValue="1" description="Before (0) or After (1)"/>
1142 <columnDefinition name="Condition" type="string" length="255" nullable="yes" modularize="condition" localizable="yes"
1143 category="condition"/>
1144 </tableDefinition>
1145 <tableDefinition name="ModuleAdvtExecuteSequence">
1146 <columnDefinition name="Action" type="string" length="64" primaryKey="yes" modularize="column"
1147 category="identifier" description="Action to insert"/>
1148 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
1149 minValue="-4" maxValue="32767" description="Standard Sequence number"/>
1150 <columnDefinition name="BaseAction" type="string" length="64" nullable="yes" modularize="column"
1151 keyTable="ModuleAdvtExecuteSequence" keyColumn="1" category="identifier" description="Base action to determine insert location."/>
1152 <columnDefinition name="After" type="number" length="2" nullable="yes"
1153 minValue="0" maxValue="1" description="Before (0) or After (1)"/>
1154 <columnDefinition name="Condition" type="string" length="255" nullable="yes" modularize="condition" localizable="yes"
1155 category="condition"/>
1156 </tableDefinition>
1157 <tableDefinition name="ModuleAdvtUISequence">
1158 <columnDefinition name="Action" type="string" length="64" primaryKey="yes" modularize="column"
1159 category="identifier" description="Action to insert"/>
1160 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
1161 minValue="-4" maxValue="32767" description="Standard Sequence number"/>
1162 <columnDefinition name="BaseAction" type="string" length="64" nullable="yes" modularize="column"
1163 keyTable="ModuleAdvtUISequence" keyColumn="1" category="identifier" description="Base action to determine insert location."/>
1164 <columnDefinition name="After" type="number" length="2" nullable="yes"
1165 minValue="0" maxValue="1" description="Before (0) or After (1)"/>
1166 <columnDefinition name="Condition" type="string" length="255" nullable="yes" modularize="condition" localizable="yes"
1167 category="condition"/>
1168 </tableDefinition>
1169 <tableDefinition name="ModuleComponents">
1170 <columnDefinition name="Component" type="string" length="72" primaryKey="yes" modularize="column"
1171 keyTable="Component" keyColumn="1" category="identifier" description="Component contained in the module."/>
1172 <columnDefinition name="ModuleID" type="string" length="72" primaryKey="yes" modularize="column"
1173 keyTable="ModuleSignature" keyColumn="1" category="identifier" description="Module containing the component."/>
1174 <columnDefinition name="Language" type="number" length="2" primaryKey="yes" localizable="yes"
1175 keyTable="ModuleSignature" keyColumn="2" description="Default language ID for module (may be changed by transform)."/>
1176 </tableDefinition>
1177 <tableDefinition name="ModuleSignature">
1178 <columnDefinition name="ModuleID" type="string" length="72" primaryKey="yes" modularize="column"
1179 category="identifier" description="Module identifier (String.GUID)."/>
1180 <columnDefinition name="Language" type="number" length="2" primaryKey="yes" localizable="yes"
1181 description="Default decimal language of module."/>
1182 <columnDefinition name="Version" type="string" length="32"
1183 category="version" description="Version of the module."/>
1184 </tableDefinition>
1185 <tableDefinition name="ModuleConfiguration">
1186 <columnDefinition name="Name" type="string" length="72" primaryKey="yes"
1187 category="identifier" description="Unique identifier for this row."/>
1188 <columnDefinition name="Format" type="number" length="2"
1189 minValue="0" maxValue="3" description="Format of this item."/>
1190 <columnDefinition name="Type" type="string" length="72" nullable="yes"
1191 category="identifier" description="Additional type information for this item."/>
1192 <columnDefinition name="ContextData" type="localized" length="0" nullable="yes"
1193 category="text" description="Additional context information about this item."/>
1194 <columnDefinition name="DefaultValue" type="localized" length="0" nullable="yes"
1195 category="text" description="Default value for this item."/>
1196 <columnDefinition name="Attributes" type="number" length="4" nullable="yes"
1197 minValue="0" maxValue="3" description="Additional type-specific attributes."/>
1198 <columnDefinition name="DisplayName" type="localized" length="72" nullable="yes"
1199 category="text" description="A short human-readable name for this item."/>
1200 <columnDefinition name="Description" type="localized" length="0" nullable="yes"
1201 category="text" description="A human-readable description."/>
1202 <columnDefinition name="HelpLocation" type="string" length="0" nullable="yes"
1203 category="text" description="Filename or namespace of the context-sensitive help for this item."/>
1204 <columnDefinition name="HelpKeyword" type="string" length="0" nullable="yes"
1205 category="text" description="Keyword index into the HelpLocation for this item."/>
1206 </tableDefinition>
1207 <tableDefinition name="ModuleDependency">
1208 <columnDefinition name="ModuleID" type="string" length="72" primaryKey="yes" modularize="column"
1209 keyTable="ModuleSignature" keyColumn="1" category="identifier" description="Module requiring the dependency."/>
1210 <columnDefinition name="ModuleLanguage" type="number" length="2" primaryKey="yes" localizable="yes"
1211 keyTable="ModuleSignature" keyColumn="2" description="Language of module requiring the dependency."/>
1212 <columnDefinition name="RequiredID" type="string" length="72" primaryKey="yes"
1213 description="String.GUID of required module."/>
1214 <columnDefinition name="RequiredLanguage" type="number" length="2" primaryKey="yes" localizable="yes"
1215 description="LanguageID of the required module."/>
1216 <columnDefinition name="RequiredVersion" type="string" length="32" nullable="yes"
1217 category="version" description="Version of the required version."/>
1218 </tableDefinition>
1219 <tableDefinition name="ModuleExclusion">
1220 <columnDefinition name="ModuleID" type="string" length="72" primaryKey="yes" modularize="column"
1221 keyTable="ModuleSignature" keyColumn="1" category="identifier" description="String.GUID of module with exclusion requirement."/>
1222 <columnDefinition name="ModuleLanguage" type="number" length="2" primaryKey="yes" localizable="yes"
1223 keyTable="ModuleSignature" keyColumn="2" description="LanguageID of module with exclusion requirement."/>
1224 <columnDefinition name="ExcludedID" type="string" length="72" primaryKey="yes"
1225 description="String.GUID of excluded module."/>
1226 <columnDefinition name="ExcludedLanguage" type="number" length="2" primaryKey="yes" localizable="yes"
1227 description="Language of excluded module."/>
1228 <columnDefinition name="ExcludedMinVersion" type="string" length="32" nullable="yes"
1229 category="version" description="Minimum version of excluded module."/>
1230 <columnDefinition name="ExcludedMaxVersion" type="string" length="32" nullable="yes"
1231 category="version" description="Maximum version of excluded module."/>
1232 </tableDefinition>
1233 <tableDefinition name="ModuleIgnoreTable">
1234 <columnDefinition name="Table" type="string" length="72" primaryKey="yes"
1235 category="identifier" description="Table name to ignore during merge operation."/>
1236 </tableDefinition>
1237 <tableDefinition name="ModuleInstallExecuteSequence">
1238 <columnDefinition name="Action" type="string" length="64" primaryKey="yes" modularize="column"
1239 category="identifier" description="Action to insert"/>
1240 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
1241 minValue="-4" maxValue="32767" description="Standard Sequence number"/>
1242 <columnDefinition name="BaseAction" type="string" length="64" nullable="yes" modularize="column"
1243 keyTable="ModuleInstallExecuteSequence" keyColumn="1" category="identifier" description="Base action to determine insert location."/>
1244 <columnDefinition name="After" type="number" length="2" nullable="yes"
1245 minValue="0" maxValue="1" description="Before (0) or After (1)"/>
1246 <columnDefinition name="Condition" type="string" length="255" nullable="yes" modularize="condition" localizable="yes"
1247 category="condition"/>
1248 </tableDefinition>
1249 <tableDefinition name="ModuleInstallUISequence">
1250 <columnDefinition name="Action" type="string" length="64" primaryKey="yes" modularize="column"
1251 category="identifier" description="Action to insert"/>
1252 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
1253 minValue="-4" maxValue="32767" description="Standard Sequence number"/>
1254 <columnDefinition name="BaseAction" type="string" length="64" nullable="yes" modularize="column"
1255 keyTable="ModuleInstallUISequence" keyColumn="1" category="identifier" description="Base action to determine insert location."/>
1256 <columnDefinition name="After" type="number" length="2" nullable="yes"
1257 minValue="0" maxValue="1" description="Before (0) or After (1)"/>
1258 <columnDefinition name="Condition" type="string" length="255" nullable="yes" modularize="condition" localizable="yes"
1259 category="condition"/>
1260 </tableDefinition>
1261 <tableDefinition name="ModuleSubstitution">
1262 <columnDefinition name="Table" type="string" length="72" primaryKey="yes"
1263 category="identifier" description="Table containing the data to be modified."/>
1264 <columnDefinition name="Row" type="string" length="0" primaryKey="yes" modularize="semicolonDelimited"
1265 category="text" description="Row containing the data to be modified."/>
1266 <columnDefinition name="Column" type="string" length="72" primaryKey="yes"
1267 category="identifier" description="Column containing the data to be modified."/>
1268 <columnDefinition name="Value" type="localized" length="0" nullable="yes"
1269 category="text" description="Template for modification data."/>
1270 </tableDefinition>
1271 <tableDefinition name="Properties">
1272 <columnDefinition name="Name" type="string" length="72" primaryKey="yes"
1273 category="text" description="Primary key, non-localized token"/>
1274 <columnDefinition name="Value" type="string" length="0"
1275 category="text" description="Value of the property"/>
1276 </tableDefinition>
1277 <tableDefinition name="ImageFamilies">
1278 <columnDefinition name="Family" type="string" length="8" primaryKey="yes"
1279 category="text" description="Primary key"/>
1280 <columnDefinition name="MediaSrcPropName" type="string" length="72" nullable="yes"
1281 category="text"/>
1282 <columnDefinition name="MediaDiskId" type="number" length="0" nullable="yes"
1283 category="integer"/>
1284 <columnDefinition name="FileSequenceStart" type="number" length="4" nullable="yes"
1285 minValue="1" maxValue="214743647" category="integer"/>
1286 <columnDefinition name="DiskPrompt" type="string" length="128" nullable="yes" escapeIdtCharacters="yes" localizable="yes"
1287 category="text"/>
1288 <columnDefinition name="VolumeLabel" type="string" length="32" nullable="yes"
1289 category="text"/>
1290 </tableDefinition>
1291 <tableDefinition name="UpgradedImages">
1292 <columnDefinition name="Upgraded" type="string" length="13" primaryKey="yes"
1293 category="text" description="Primary key"/>
1294 <columnDefinition name="MsiPath" type="string" length="255"
1295 category="text"/>
1296 <columnDefinition name="PatchMsiPath" type="string" length="255" nullable="yes"
1297 category="text"/>
1298 <columnDefinition name="SymbolPaths" type="string" length="255" nullable="yes"
1299 category="text"/>
1300 <columnDefinition name="Family" type="string" length="8"
1301 keyTable="ImageFamilies" keyColumn="1" category="text" description="Foreign key, Family to which this image belongs"/>
1302 </tableDefinition>
1303 <tableDefinition name="UpgradedFilesToIgnore">
1304 <columnDefinition name="Upgraded" type="string" length="13" primaryKey="yes"
1305 keyTable="UpgradedImages" keyColumn="1" category="text" description="Foreign key, Upgraded image"/>
1306 <columnDefinition name="FTK" type="string" length="255" primaryKey="yes" modularize="column"
1307 keyTable="File" keyColumn="1" category="text" description="Foreign key, File to ignore"/>
1308 </tableDefinition>
1309 <tableDefinition name="UpgradedFiles_OptionalData">
1310 <columnDefinition name="Upgraded" type="string" length="13" primaryKey="yes"
1311 keyTable="UpgradedImages" keyColumn="1" category="text" description="Foreign key, Upgraded image"/>
1312 <columnDefinition name="FTK" type="string" length="255" primaryKey="yes" modularize="column"
1313 keyTable="File" keyColumn="1" category="text" description="Foreign key, File to ignore"/>
1314 <columnDefinition name="SymbolPaths" type="string" length="255" nullable="yes"
1315 category="text"/>
1316 <columnDefinition name="AllowIgnoreOnPatchError" type="number" length="0" nullable="yes"
1317 category="integer"/>
1318 <columnDefinition name="IncludeWholeFile" type="number" length="0" nullable="yes"
1319 category="integer"/>
1320 </tableDefinition>
1321 <tableDefinition name="TargetImages" createSymbols="yes">
1322 <columnDefinition name="Target" type="string" length="13" primaryKey="yes"
1323 category="text"/>
1324 <columnDefinition name="MsiPath" type="string" length="255"
1325 category="text"/>
1326 <columnDefinition name="SymbolPaths" type="string" length="255" nullable="yes"
1327 category="text"/>
1328 <columnDefinition name="Upgraded" type="string" length="13"
1329 keyTable="UpgradedImages" keyColumn="1" category="text" description="Foreign key, Upgraded image"/>
1330 <columnDefinition name="Order" type="number" length="0"
1331 category="integer"/>
1332 <columnDefinition name="ProductValidateFlags" type="string" length="16" nullable="yes"
1333 category="text"/>
1334 <columnDefinition name="IgnoreMissingSrcFiles" type="number" length="0"
1335 category="integer"/>
1336 </tableDefinition>
1337 <tableDefinition name="TargetFiles_OptionalData">
1338 <columnDefinition name="Target" type="string" length="13" primaryKey="yes"
1339 keyTable="TargetImages" keyColumn="1" category="text" description="Foreign key, Target image"/>
1340 <columnDefinition name="FTK" type="string" length="255" primaryKey="yes" modularize="column"
1341 keyTable="File" keyColumn="1" category="text" description="Foreign key, File to ignore"/>
1342 <columnDefinition name="SymbolPaths" type="string" length="255" nullable="yes"
1343 category="text"/>
1344 <columnDefinition name="IgnoreOffsets" type="string" length="255" nullable="yes"
1345 category="text"/>
1346 <columnDefinition name="IgnoreLengths" type="string" length="255" nullable="yes"
1347 category="text"/>
1348 <columnDefinition name="RetainOffsets" type="string" length="255" nullable="yes"
1349 category="text"/>
1350 </tableDefinition>
1351 <tableDefinition name="FamilyFileRanges">
1352 <columnDefinition name="Family" type="string" length="8" primaryKey="yes"
1353 keyTable="ImageFamilies" keyColumn="1" category="text" description="Foreign key, Family"/>
1354 <columnDefinition name="FTK" type="string" length="255" primaryKey="yes" modularize="column"
1355 keyTable="File" keyColumn="1" category="text" description="Foreign key, File to ignore"/>
1356 <columnDefinition name="RetainOffsets" type="string" length="128"
1357 category="text"/>
1358 <columnDefinition name="RetainLengths" type="string" length="128"
1359 category="text"/>
1360 </tableDefinition>
1361 <tableDefinition name="ExternalFiles">
1362 <columnDefinition name="Family" type="string" length="8" primaryKey="yes"
1363 keyTable="ImageFamilies" keyColumn="1" category="text" description="Foreign key, Family"/>
1364 <columnDefinition name="FTK" type="string" length="255" primaryKey="yes" modularize="column"
1365 keyTable="File" keyColumn="1" category="text" description="Foreign key, File to ignore"/>
1366 <columnDefinition name="FilePath" type="string" length="255" primaryKey="yes"
1367 category="text"/>
1368 <columnDefinition name="SymbolPaths" type="string" length="255" nullable="yes"
1369 category="text"/>
1370 <columnDefinition name="IgnoreOffsets" type="string" length="255" nullable="yes"
1371 category="text"/>
1372 <columnDefinition name="IgnoreLengths" type="string" length="255" nullable="yes"
1373 category="text"/>
1374 <columnDefinition name="RetainOffsets" type="string" length="255" nullable="yes"
1375 category="text"/>
1376 <columnDefinition name="Order" type="number" length="0"
1377 category="integer"/>
1378 </tableDefinition>
1379 <tableDefinition name="WixAction" createSymbols="yes" unreal="yes">
1380 <columnDefinition name="SequenceTable" type="string" length="62" primaryKey="yes"/>
1381 <columnDefinition name="Action" type="string" length="72" primaryKey="yes"/>
1382 <columnDefinition name="Condition" type="string" length="255" nullable="yes" localizable="yes"/>
1383 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"/>
1384 <columnDefinition name="Before" type="string" length="72" nullable="yes"/>
1385 <columnDefinition name="After" type="string" length="72" nullable="yes"/>
1386 <columnDefinition name="Overridable" type="number" length="2" nullable="yes"/>
1387 </tableDefinition>
1388 <tableDefinition name="WixBBControl" createSymbols="yes" unreal="yes">
1389 <columnDefinition name="Billboard_" type="string" length="50" primaryKey="yes" modularize="column"/>
1390 <columnDefinition name="BBControl_" type="string" length="50" primaryKey="yes"/>
1391 <columnDefinition name="SourceFile" type="object" length="0"/>
1392 </tableDefinition>
1393 <tableDefinition name="WixComplexReference" unreal="yes">
1394 <columnDefinition name="Parent" type="string" length="0" localizable="yes"/>
1395 <columnDefinition name="ParentAttributes" type="number" length="4"/>
1396 <columnDefinition name="ParentLanguage" type="string" length="0" nullable="yes"/>
1397 <columnDefinition name="Child" type="string" length="0" localizable="yes"/>
1398 <columnDefinition name="ChildAttributes" type="number" length="4"/>
1399 <columnDefinition name="Attributes" type="number" length="4"/>
1400 </tableDefinition>
1401 <tableDefinition name="WixComponentGroup" createSymbols="yes" unreal="yes">
1402 <columnDefinition name="WixComponentGroup" type="string" length="0" primaryKey="yes"/>
1403 </tableDefinition>
1404 <tableDefinition name="WixControl" unreal="yes">
1405 <columnDefinition name="Dialog_" type="string" length="72" primaryKey="yes" modularize="column"/>
1406 <columnDefinition name="Control_" type="string" length="50" primaryKey="yes"/>
1407 <columnDefinition name="SourceFile" type="object" length="0"/>
1408 </tableDefinition>
1409 <tableDefinition name="WixCustomRow" unreal="yes">
1410 <columnDefinition name="Table" type="string" length="62"/>
1411 <columnDefinition name="FieldData" type="string" length="0"/>
1412 </tableDefinition>
1413 <tableDefinition name="WixCustomTable" createSymbols="yes" unreal="yes">
1414 <columnDefinition name="Table" type="string" length="62" primaryKey="yes"/>
1415 <columnDefinition name="ColumnCount" type="number" length="2"/>
1416 <columnDefinition name="ColumnNames" type="string" length="0"/>
1417 <columnDefinition name="ColumnTypes" type="string" length="0"/>
1418 <columnDefinition name="PrimaryKeys" type="string" length="0"/>
1419 <columnDefinition name="MinValues" type="string" length="0"/>
1420 <columnDefinition name="MaxValues" type="string" length="0"/>
1421 <columnDefinition name="KeyTables" type="string" length="0"/>
1422 <columnDefinition name="KeyColumns" type="string" length="0"/>
1423 <columnDefinition name="Categories" type="string" length="0"/>
1424 <columnDefinition name="Sets" type="string" length="0"/>
1425 <columnDefinition name="Descriptions" type="string" length="0"/>
1426 <columnDefinition name="Modularizations" type="string" length="0"/>
1427 <columnDefinition name="BootstrapperApplicationData" type="number" length="2"/>
1428 </tableDefinition>
1429 <tableDefinition name="WixDirectory" unreal="yes">
1430 <columnDefinition name="Directory_" type="string" length="0" primaryKey="yes" modularize="column"/>
1431 <columnDefinition name="ComponentGuidGenerationSeed" type="string" length="38" nullable="yes"/>
1432 </tableDefinition>
1433 <tableDefinition name="WixEnsureTable" unreal="yes">
1434 <columnDefinition name="Table" type="string" length="31"/>
1435 </tableDefinition>
1436 <tableDefinition name="WixFeatureGroup" createSymbols="yes" unreal="yes">
1437 <columnDefinition name="WixFeatureGroup" type="string" length="0" primaryKey="yes"/>
1438 </tableDefinition>
1439 <tableDefinition name="WixPatchFamilyGroup" createSymbols="yes" unreal="yes">
1440 <columnDefinition name="WixPatchFamilyGroup" type="string" length="0" primaryKey="yes"/>
1441 </tableDefinition>
1442 <tableDefinition name="WixGroup" unreal="yes">
1443 <columnDefinition name="ParentId" type="string" length="0" primaryKey="yes" nullable="no" category="identifier"
1444 description="Primary key used to identify a particular record in a parent table."/>
1445 <columnDefinition name="ParentType" type="string" length="0" primaryKey="yes" nullable="no"
1446 description="Primary key used to identify a particular parent type in a parent table."/>
1447 <columnDefinition name="ChildId" type="string" length="0" primaryKey="yes" nullable="no" category="identifier"
1448 description="Primary key used to identify a particular record in a child table."/>
1449 <columnDefinition name="ChildType" type="string" length="0" primaryKey="yes" nullable="no"
1450 description="Primary key used to identify a particular child type in a child table."/>
1451 </tableDefinition>
1452 <tableDefinition name="WixFeatureModules" unreal="yes">
1453 <columnDefinition name="Feature_" type="string" length="38" primaryKey="yes"/>
1454 <columnDefinition name="WixMerge_" type="string" length="72" primaryKey="yes"/>
1455 </tableDefinition>
1456 <tableDefinition name="WixFile" unreal="yes">
1457 <columnDefinition name="File_" type="string" length="0" category="identifier" primaryKey="yes"
1458 modularize="column" keyTable="File" keyColumn="1" />
1459 <columnDefinition name="AssemblyType" type="number" length="2" minValue="0" maxValue="1" />
1460 <columnDefinition name="File_AssemblyManifest" type="string" length="72" category="identifier" nullable="yes"
1461 modularize="column" keyTable="File" keyColumn="1" />
1462 <columnDefinition name="File_AssemblyApplication" type="string" length="72" category="identifier" nullable="yes"
1463 modularize="column" keyTable="File" keyColumn="1" />
1464 <columnDefinition name="Directory_" type="string" length="72" modularize="column" keyTable="Directory" keyColumn="1" />
1465 <columnDefinition name="DiskId" type="number" length="4" nullable="yes"/>
1466 <columnDefinition name="Source" type="object" length="0"/>
1467 <columnDefinition name="ProcessorArchitecture" type="string" length="0" nullable="yes"/>
1468 <columnDefinition name="PatchGroup" type="number" length="4" />
1469 <columnDefinition name="Attributes" type="number" length="4"/>
1470 <columnDefinition name="PatchAttributes" type="number" length="4" nullable="yes"/>
1471 <columnDefinition name="DeltaPatchHeaderSource" type="string" length="0"/>
1472 </tableDefinition>
1473 <tableDefinition name="WixBindUpdatedFiles" unreal="yes">
1474 <columnDefinition name="File_" type="string" length="0" primaryKey="yes" modularize="column" keyTable="File" keyColumn="1" category="identifier" />
1475 </tableDefinition>
1476 <tableDefinition name="WixBuildInfo" unreal="yes">
1477 <columnDefinition name="WixVersion" type="string" length="20"
1478 category="text" description="Version number of WiX."/>
1479 <columnDefinition name="WixOutputFile" type="string" length="0" nullable="yes" escapeIdtCharacters="yes"
1480 category="text" description="Path to output file, if supplied."/>
1481 <columnDefinition name="WixProjectFile" type="string" length="0" nullable="yes" escapeIdtCharacters="yes"
1482 category="text" description="Path to .wixproj file, if supplied."/>
1483 <columnDefinition name="WixPdbFile" type="string" length="0" nullable="yes" escapeIdtCharacters="yes"
1484 category="text" description="Path to .wixpdb file, if supplied."/>
1485 </tableDefinition>
1486 <tableDefinition name="WixFragment" createSymbols="yes" unreal="yes">
1487 <columnDefinition name="WixFragment" type="string" length="0" primaryKey="yes"/>
1488 </tableDefinition>
1489 <tableDefinition name="WixInstanceComponent" unreal="yes">
1490 <columnDefinition name="Component_" type="string" length="0" primaryKey="yes" modularize="column"/>
1491 </tableDefinition>
1492 <tableDefinition name="WixInstanceTransforms" unreal="yes" createSymbols="yes">
1493 <columnDefinition name="Id" type="string" length="0" primaryKey="yes"/>
1494 <columnDefinition name="PropertyId" type="string" length="0"/>
1495 <columnDefinition name="ProductCode" type="string" length="0" category="guid"/>
1496 <columnDefinition name="ProductName" type="localized" localizable="yes" length="0" nullable="yes"/>
1497 <columnDefinition name="UpgradeCode" type="string" length="38" category="guid" nullable="yes"/>
1498 </tableDefinition>
1499 <tableDefinition name="WixMedia" unreal="yes">
1500 <columnDefinition name="DiskId_" type="number" length="2" primaryKey="yes"/>
1501 <columnDefinition name="CompressionLevel" type="number" length="2" nullable="yes" minValue="0" maxValue="4" />
1502 <columnDefinition name="Layout" type="string" length="0" nullable="yes"/>
1503 </tableDefinition>
1504 <tableDefinition name="WixMediaTemplate" unreal="yes">
1505 <columnDefinition name="CabinetTemplate" type="string" length="0" nullable="yes"/>
1506 <columnDefinition name="CompressionLevel" type="number" length="2" nullable="yes" minValue="0" maxValue="4" />
1507 <columnDefinition name="DiskPrompt" type="string" length="0" nullable="yes"/>
1508 <columnDefinition name="VolumeLabel" type="string" length="0" nullable="yes"/>
1509 <columnDefinition name="MaximumUncompressedMediaSize" type="number" length="4" />
1510 <columnDefinition name="MaximumCabinetSizeForLargeFileSplitting" type="number" length="4" />
1511 </tableDefinition>
1512 <tableDefinition name="WixMerge" createSymbols="yes" unreal="yes">
1513 <columnDefinition name="WixMerge" type="string" length="72" primaryKey="yes"/>
1514 <columnDefinition name="Language" type="number" length="2" localizable="yes"/>
1515 <columnDefinition name="Directory_" type="string" nullable="yes" length="72"/>
1516 <columnDefinition name="SourceFile" type="object" length="0"/>
1517 <columnDefinition name="DiskId" type="number" length="2"/>
1518 <columnDefinition name="FileCompression" type="number" length="2" nullable="yes"/>
1519 <columnDefinition name="ConfigurationData" type="string" length="255" nullable="yes"/>
1520 <columnDefinition name="Feature_" type="string" length="72"/>
1521 </tableDefinition>
1522 <tableDefinition name="WixOrdering" createSymbols="yes" unreal="yes">
1523 <columnDefinition name="ItemType" type="string" length="0" primaryKey="yes" nullable="no"
1524 description="Primary key used to identify the item in another table."/>
1525 <columnDefinition name="ItemId_" type="string" length="72" category="identifier" primaryKey="yes"
1526 description="Reference to an entry in another table."/>
1527 <columnDefinition name="DependsOnType" type="string" length="0" primaryKey="yes" nullable="no"
1528 description="Primary key used to identify the item in another table."/>
1529 <columnDefinition name="DependsOnId_" type="string" length="72" category="identifier" primaryKey="yes"
1530 description="Reference to an entry in another table."/>
1531 </tableDefinition>
1532 <tableDefinition name="WixDeltaPatchFile" unreal="yes">
1533 <columnDefinition name="File_" type="string" length="72" primaryKey="yes" modularize="column" keyTable="File" keyColumn="1" />
1534 <columnDefinition name="RetainLengths" type="preserved" length="0" nullable="yes" category="text"/>
1535 <columnDefinition name="IgnoreOffsets" type="preserved" length="0" nullable="yes" category="text"/>
1536 <columnDefinition name="IgnoreLengths" type="preserved" length="0" nullable="yes" category="text"/>
1537 <columnDefinition name="RetainOffsets" type="preserved" length="0" nullable="yes" category="text"/>
1538 <columnDefinition name="SymbolPaths" type="preserved" length="0" nullable="yes" category="text"/>
1539 </tableDefinition>
1540 <tableDefinition name="WixDeltaPatchSymbolPaths" unreal="yes">
1541 <columnDefinition name="Id" type="string" length="72" primaryKey="yes" />
1542 <columnDefinition name="Type" type="number" length="2" primaryKey="yes" minValue="0" maxValue="4" />
1543 <columnDefinition name="SymbolPaths" type="preserved" length="0" category="text"/>
1544 </tableDefinition>
1545 <tableDefinition name="WixProperty" unreal="yes">
1546 <columnDefinition name="Property_" type="string" length="72" modularize="column"/>
1547 <columnDefinition name="Attributes" type="number" length="4"/>
1548 </tableDefinition>
1549 <tableDefinition name="WixSimpleReference" unreal="yes">
1550 <columnDefinition name="Table" type="string" length="32"/>
1551 <columnDefinition name="PrimaryKeys" type="string" length="0"/>
1552 </tableDefinition>
1553 <tableDefinition name="WixSuppressAction" unreal="yes">
1554 <columnDefinition name="SequenceTable" type="string" length="72" primaryKey="yes"/>
1555 <columnDefinition name="Action" type="string" length="72" primaryKey="yes"/>
1556 </tableDefinition>
1557 <tableDefinition name="WixSuppressModularization" unreal="yes">
1558 <columnDefinition name="WixSuppressModularization" type="string" length="72"/>
1559 </tableDefinition>
1560 <tableDefinition name="WixPatchBaseline" unreal="yes">
1561 <columnDefinition name="WixPatchBaseline" type="string" length="72" primaryKey="yes"
1562 category="identifier" description="Primary key used to identify sets of transforms in a patch."/>
1563 <columnDefinition name="DiskId" type="number" length="2"/>
1564 <columnDefinition name="ValidationFlags" type="number" length="4" category="integer" description="Patch transform validation flags for the associated patch baseline."/>
1565 </tableDefinition>
1566 <tableDefinition name="WixPatchRef" unreal="yes">
1567 <columnDefinition name="Table" type="string" length="32"/>
1568 <columnDefinition name="PrimaryKeys" type="string" length="0"/>
1569 </tableDefinition>
1570 <tableDefinition name="WixPatchId" unreal="yes">
1571 <columnDefinition name="ProductCode" type="string" length="38" nullable="no"/>
1572 <columnDefinition name="ClientPatchId" type="string" length="72" nullable="no"/>
1573 <columnDefinition name="OptimizePatchSizeForLargeFiles" type="number" length="2" nullable="yes"
1574 minValue="0" maxValue="1"/>
1575 <columnDefinition name="ApiPatchingSymbolFlags" type="number" length="4" nullable="yes"
1576 minValue="0" maxValue="7"/>
1577 </tableDefinition>
1578 <tableDefinition name="WixPatchTarget" unreal="yes">
1579 <columnDefinition name="ProductCode" type="string" length="38" nullable="no" />
1580 </tableDefinition>
1581 <tableDefinition name="WixPatchMetadata" unreal="yes">
1582 <columnDefinition name="Property" type="string" length="72" primaryKey="yes"/>
1583 <columnDefinition name="Value" type="localized" length="0"/>
1584 </tableDefinition>
1585 <tableDefinition name="WixUI" createSymbols="yes" unreal="yes">
1586 <columnDefinition name="WixUI" type="string" length="0" primaryKey="yes"/>
1587 </tableDefinition>
1588 <tableDefinition name="WixVariable" unreal="yes">
1589 <columnDefinition name="WixVariable" type="string" length="0"/>
1590 <columnDefinition name="Value" type="localized" length="0" nullable="yes"/>
1591 <columnDefinition name="Attributes" type="number" length="4"/>
1592 </tableDefinition>
1593 <tableDefinition name="WixBundleContainer" createSymbols="yes" unreal="yes">
1594 <columnDefinition name="WixBundleContainer" type="string" length="0" category="identifier" primaryKey="yes"/>
1595 <columnDefinition name="Name" type="string" length="0"/>
1596 <columnDefinition name="Type" type="number" length="2" minValue="0" maxValue="1" />
1597 <columnDefinition name="DownloadUrl" type="string" length="0" nullable="yes" />
1598 <columnDefinition name="Size" type="number" length="4" minValue="0" nullable="yes" />
1599 <columnDefinition name="Hash" type="string" length="0" nullable="yes" />
1600 <columnDefinition name="AttachedContainerIndex" type="number" length="2" nullable="yes" />
1601 <columnDefinition name="WorkingPath" type="string" length="0" nullable="yes" />
1602 </tableDefinition>
1603 <tableDefinition name="WixBundlePayloadGroup" createSymbols="yes" unreal="yes">
1604 <columnDefinition name="WixBundlePayloadGroup" type="string" length="0" category="identifier" primaryKey="yes"/>
1605 </tableDefinition>
1606 <tableDefinition name="WixBundlePayload" createSymbols="yes" unreal="yes">
1607 <columnDefinition name="WixBundlePayload" type="string" length="0" category="identifier" primaryKey="yes"/>
1608 <columnDefinition name="Name" type="string" length="0" nullable="yes"/>
1609 <columnDefinition name="SourceFile" type="object" length="0" nullable="yes"/>
1610 <columnDefinition name="DownloadUrl" type="string" length="0" nullable="yes" />
1611 <columnDefinition name="Compressed" type="number" length="2" minValue="0" maxValue="2" />
1612 <columnDefinition name="UnresolvedSourceFile" type="string" length="0" nullable="yes" />
1613 <columnDefinition name="DisplayName" type="string" length="0" nullable="yes" />
1614 <columnDefinition name="Description" type="string" length="0" nullable="yes" />
1615 <columnDefinition name="EnableSignatureValidation" type="number" length="2" nullable="yes" minValue="0" maxValue="1" />
1616 <columnDefinition name="FileSize" type="number" length="4" minValue="0" maxValue="2147483647" nullable="yes" />
1617 <columnDefinition name="Version" type="string" length="24" nullable="yes" />
1618 <columnDefinition name="Hash" type="string" length="0" nullable="yes" />
1619 <columnDefinition name="PublicKey" type="string" length="0" nullable="yes" />
1620 <columnDefinition name="Thumbprint" type="string" length="0" nullable="yes" />
1621 <columnDefinition name="Catalog_" type="string" length="0" nullable="yes" category="identifier"
1622 keyTable="WixBundleCatalog" keyColumn="1" description="Reference to a catalog entry in the WixBundleCatalog table."/>
1623 <columnDefinition name="Container_" type="string" length="0" nullable="yes"
1624 keyTable="WixBundleContainer" keyColumn="1" description="Reference to a container entry in the WixBundleContainer table."/>
1625 <columnDefinition name="Package" type="string" length="0" nullable="yes" />
1626 <columnDefinition name="ContentFile" type="number" length="2" nullable="yes" minValue="0" maxValue="1" />
1627 <columnDefinition name="EmbeddedId" type="string" length="0" nullable="yes" />
1628 <columnDefinition name="LayoutOnly" type="number" length="2" nullable="yes" minValue="0" maxValue="1" />
1629 <columnDefinition name="Packaging" type="number" length="2" nullable="yes" minValue="1" maxValue="2" />
1630 <columnDefinition name="ParentPackagePayload_" type="string" length="0" nullable="yes" />
1631 </tableDefinition>
1632 <tableDefinition name="WixBundlePatchTargetCode" createSymbols="yes" unreal="yes">
1633 <columnDefinition name="PackageId" type="string" length="0" category="identifier" primaryKey="yes" />
1634 <columnDefinition name="TargetCode" type="string" length="0" nullable="yes" primaryKey="yes" />
1635 <columnDefinition name="Attributes" type="number" length="4" nullable="yes" minValue="0" maxValue="2147483647" />
1636 </tableDefinition>
1637 <tableDefinition name="WixBundle" unreal="yes">
1638 <columnDefinition name="Version" type="string" length="24" />
1639 <columnDefinition name="Copyright" type="string" length="0" nullable="yes" />
1640 <columnDefinition name="Name" type="string" length="0" nullable="yes" />
1641 <columnDefinition name="AboutUrl" type="string" length="0" nullable="yes" />
1642 <columnDefinition name="DisableModify" type="number" length="2" nullable="yes" minValue="0" maxValue="2"/>
1643 <columnDefinition name="DisableRemove" type="number" length="2" nullable="yes" minValue="0" maxValue="1"/>
1644 <columnDefinition name="DisableRepair" type="number" length="2" nullable="yes" minValue="0" maxValue="1"/>
1645 <columnDefinition name="HelpTelephone" type="string" length="0" nullable="yes" />
1646 <columnDefinition name="HelpUrl" type="string" length="0" nullable="yes" />
1647 <columnDefinition name="Manufacturer" type="string" length="0" nullable="yes" />
1648 <columnDefinition name="UpdateUrl" type="string" length="0" nullable="yes" />
1649 <columnDefinition name="Compressed" type="number" length="2" nullable="yes" minValue="0" maxValue="1" />
1650 <columnDefinition name="LogPrefixAndExtension" type="string" length="0" nullable="yes" />
1651 <columnDefinition name="IconSourceFile" type="object" length="0" nullable="yes" />
1652 <columnDefinition name="SplashScreenSourceFile" type="object" length="0" nullable="yes" />
1653 <columnDefinition name="Condition" type="string" length="0" nullable="yes" />
1654 <columnDefinition name="Tag" type="string" length="0" nullable="yes" />
1655 <columnDefinition name="Platform" type="string" length="4" />
1656 <columnDefinition name="ParentName" type="string" length="0" nullable="yes" />
1657 <columnDefinition name="UpgradeCode" type="string" length="38" category="guid" />
1658 <columnDefinition name="BundleId" type="string" length="38" category="guid" description="Only valid after binding." />
1659 <columnDefinition name="ProviderKey" type="string" length="38" category="guid" nullable="yes" description="Only valid after binding." />
1660 <columnDefinition name="PerMachine" type="number" length="2" nullable="yes" minValue="0" maxValue="1" description="Only valid after binding." />
1661 </tableDefinition>
1662 <tableDefinition name="WixApprovedExeForElevation" createSymbols="yes" unreal="yes">
1663 <columnDefinition name="Id" type="string" length="0" category="identifier" primaryKey="yes" />
1664 <columnDefinition name="Key" type="string" length="0" />
1665 <columnDefinition name="Value" type="string" length="0" nullable="yes" />
1666 <columnDefinition name="Attributes" type="number" length="4" minValue="0" maxValue="1" />
1667 </tableDefinition>
1668 <tableDefinition name="WixBundleUpdate" unreal="yes">
1669 <columnDefinition name="Location" type="string" length="0" />
1670 <columnDefinition name="Attributes" type="number" length="4" nullable="yes" />
1671 </tableDefinition>
1672 <tableDefinition name="WixBootstrapperApplication" createSymbols="yes" unreal="yes">
1673 <columnDefinition name="Id" type="string" length="0" category="identifier" primaryKey="yes"/>
1674 </tableDefinition>
1675 <tableDefinition name="WixUpdateRegistration" unreal="yes">
1676 <columnDefinition name="Manufacturer" type="string" length="0" />
1677 <columnDefinition name="Department" type="string" length="0" nullable="yes" />
1678 <columnDefinition name="ProductFamily" type="string" length="0" nullable="yes" />
1679 <columnDefinition name="Name" type="string" length="0" />
1680 <columnDefinition name="Classification" type="string" length="0" />
1681 </tableDefinition>
1682 <tableDefinition name="WixBundleCatalog" createSymbols="yes" unreal="yes">
1683 <columnDefinition name="WixBundleCatalog" type="string" length="0" category="identifier" primaryKey="yes"/>
1684 <columnDefinition name="Payload_" type="string" length="0" category="identifier"
1685 keyTable="WixBundlePayload" keyColumn="1" description="Reference to a payload entry in the WixBundlePayload table." />
1686 </tableDefinition>
1687 <tableDefinition name="WixChain" unreal="yes">
1688 <columnDefinition name="Attributes" type="number" length="4" nullable="no" minValue="0" maxValue="2147483647" description="A 32-bit word that specifies the attribute flags to be applied to the chain."/>
1689 </tableDefinition>
1690 <tableDefinition name="WixChainItem" createSymbols="yes" unreal="yes">
1691 <columnDefinition name="Id" type="string" length="0" category="identifier" primaryKey="yes"/>
1692 </tableDefinition>
1693 <tableDefinition name="WixBundleRollbackBoundary" createSymbols="yes" unreal="yes">
1694 <columnDefinition name="WixChainItem_" type="string" length="0" category="identifier" primaryKey="yes"
1695 keyTable="WixChainItem" keyColumn="1" description="Reference to a WixChainItem entry in the WixChainItem table."/>
1696 <columnDefinition name="Vital" type="number" length="2" nullable="yes" minValue="0" maxValue="1"/>
1697 <columnDefinition name="Transaction" type="number" length="2" nullable="yes" minValue="0" maxValue="1"/>
1698 </tableDefinition>
1699 <tableDefinition name="WixBundlePackageGroup" createSymbols="yes" unreal="yes">
1700 <columnDefinition name="WixBundlePackageGroup" type="string" length="0" category="identifier" primaryKey="yes"/>
1701 </tableDefinition>
1702 <tableDefinition name="WixBundlePackage" createSymbols="yes" unreal="yes">
1703 <columnDefinition name="WixChainItem_" type="string" length="0" category="identifier" primaryKey="yes"
1704 keyTable="WixChainItem" keyColumn="1" description="Reference to a WixChainItem entry in the WixChainItem table."/>
1705 <columnDefinition name="Type" type="number" length="2" minValue="0" maxValue="3" />
1706 <columnDefinition name="Payload_" type="string" length="0" category="identifier"
1707 keyTable="WixBundlePayload" keyColumn="1" description="Reference to a payload entry in the WixBundlePayload table."/>
1708 <columnDefinition name="Attributes" type="number" length="4" nullable="no" minValue="0" maxValue="2147483647" description="A 32-bit word that specifies the attribute flags to be applied to this package."/>
1709 <columnDefinition name="InstallCondition" type="string" length="0" nullable="yes"/>
1710 <columnDefinition name="Cache" type="number" length="2" nullable="yes" minValue="0" maxValue="2"/>
1711 <columnDefinition name="CacheId" type="string" length="0" nullable="yes"/>
1712 <columnDefinition name="Vital" type="number" length="2" nullable="yes" minValue="0" maxValue="1"/>
1713 <columnDefinition name="PerMachine" type="number" length="2" nullable="yes" minValue="0" maxValue="2"/>
1714 <columnDefinition name="LogPathVariable" type="string" length="0" nullable="yes"/>
1715 <columnDefinition name="RollbackLogPathVariable" type="string" length="0" nullable="yes"/>
1716 <columnDefinition name="Size" type="number" length="4"/>
1717 <columnDefinition name="InstallSize" type="number" length="4"/>
1718 <columnDefinition name="Version" type="string" length="24" category="version" nullable="yes" />
1719 <columnDefinition name="Language" type="number" length="2" nullable="yes" />
1720 <columnDefinition name="DisplayName" type="string" length="0" nullable="yes" />
1721 <columnDefinition name="Description" type="string" length="0" nullable="yes" />
1722 <columnDefinition name="RollbackBoundary_" type="string" length="0" nullable="yes"
1723 keyTable="WixBundleRollbackBoundary" keyColumn="1" description="Reference to a rollback boundary entry in the WixBundleRollbackBoundary table."/>
1724 <columnDefinition name="RollbackBoundaryBackward_" type="string" length="0" nullable="yes"
1725 keyTable="WixBundleRollbackBoundary" keyColumn="1" description="Reference to a rollback boundary entry in the WixBundleRollbackBoundary table."/>
1726 <columnDefinition name="x64" type="number" length="2" nullable="yes" minValue="0" maxValue="1"/>
1727 </tableDefinition>
1728 <tableDefinition name="WixBundleExePackage" createSymbols="yes" unreal="yes">
1729 <columnDefinition name="WixBundlePackage_" type="string" length="0" category="identifier" primaryKey="yes"
1730 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table."/>
1731 <columnDefinition name="Attributes" type="number" length="4" nullable="no" minValue="0" maxValue="2147483647" description="A 32-bit word that specifies the attribute flags to be applied to this MSI package."/>
1732 <columnDefinition name="DetectCondition" type="string" length="0" nullable="yes"/>
1733 <columnDefinition name="InstallCommand" type="string" length="0" nullable="yes"/>
1734 <columnDefinition name="RepairCommand" type="string" length="0" nullable="yes"/>
1735 <columnDefinition name="UninstallCommand" type="string" length="0" nullable="yes"/>
1736 <columnDefinition name="ExeProtocol" type="string" length="0" nullable="yes"/>
1737 </tableDefinition>
1738 <tableDefinition name="WixBundleMsiPackage" createSymbols="yes" unreal="yes">
1739 <columnDefinition name="WixBundlePackage_" type="string" length="0" category="identifier" primaryKey="yes"
1740 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table."/>
1741 <columnDefinition name="Attributes" type="number" length="4" nullable="no" minValue="0" maxValue="2147483647" description="A 32-bit word that specifies the attribute flags to be applied to this MSI package."/>
1742 <columnDefinition name="ProductCode" type="string" length="38" category="guid" />
1743 <columnDefinition name="UpgradeCode" type="string" length="38" category="guid" nullable="yes" />
1744 <columnDefinition name="ProductVersion" type="string" length="20" />
1745 <columnDefinition name="ProductLanguage" type="number" length="2" />
1746 <columnDefinition name="ProductName" type="string" length="0" />
1747 <columnDefinition name="Manufacturer" type="string" length="0" nullable="yes" />
1748 </tableDefinition>
1749 <tableDefinition name="WixBundleMspPackage" createSymbols="yes" unreal="yes">
1750 <columnDefinition name="WixBundlePackage_" type="string" length="0" category="identifier" primaryKey="yes"
1751 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table."/>
1752 <columnDefinition name="Attributes" type="number" length="2" nullable="yes" minValue="0" maxValue="1" />
1753 <columnDefinition name="PatchCode" type="string" length="38" category="guid" nullable="yes" />
1754 <columnDefinition name="Manufacturer" type="string" length="0" nullable="yes" />
1755 <columnDefinition name="PatchXml" type="string" length="0" nullable="yes" />
1756 </tableDefinition>
1757 <tableDefinition name="WixBundleMsuPackage" createSymbols="yes" unreal="yes">
1758 <columnDefinition name="WixBundlePackage_" type="string" length="0" category="identifier" primaryKey="yes"
1759 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table."/>
1760 <columnDefinition name="DetectCondition" type="string" length="0" nullable="yes"/>
1761 <columnDefinition name="MsuKB" type="string" length="0" nullable="yes"/>
1762 </tableDefinition>
1763 <tableDefinition name="WixBundlePackageExitCode" createSymbols="yes" unreal="yes">
1764 <columnDefinition name="WixBundlePackage_" type="string" length="0" category="identifier" primaryKey="yes"
1765 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table for the parent Exe."/>
1766 <columnDefinition name="Code" type="number" length="0" category="integer" nullable="yes" primaryKey="yes" />
1767 <columnDefinition name="Behavior" type="number" length="2" category="integer" minValue="0" maxValue="3" />
1768 </tableDefinition>
1769 <tableDefinition name="WixBundleMsiFeature" createSymbols="yes" unreal="yes">
1770 <columnDefinition name="WixBundlePackage_" type="string" length="0" category="identifier" primaryKey="yes"
1771 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table."/>
1772 <columnDefinition name="Name" type="string" length="0" category="identifier" primaryKey="yes" />
1773 <columnDefinition name="Size" type="number" length="4" />
1774 <columnDefinition name="Parent" type="string" length="0" />
1775 <columnDefinition name="Title" type="string" length="0" />
1776 <columnDefinition name="Description" type="string" length="0" />
1777 <columnDefinition name="Display" type="number" length="2" />
1778 <columnDefinition name="Level" type="number" length="2" />
1779 <columnDefinition name="Directory" type="string" length="0" />
1780 <columnDefinition name="Attributes" type="number" length="2" />
1781 </tableDefinition>
1782 <tableDefinition name="WixBundleMsiProperty" createSymbols="yes" unreal="yes">
1783 <columnDefinition name="WixBundlePackage_" type="string" length="0" category="identifier" primaryKey="yes"
1784 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table."/>
1785 <columnDefinition name="Name" type="string" length="0" category="identifier" primaryKey="yes" />
1786 <columnDefinition name="Value" type="string" length="0" />
1787 <columnDefinition name="Condition" type="string" length="0" nullable="yes" />
1788 </tableDefinition>
1789 <tableDefinition name="WixBundleSlipstreamMsp" createSymbols="yes" unreal="yes">
1790 <columnDefinition name="WixBundlePackage_" type="string" length="0" category="identifier" primaryKey="yes"
1791 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table for the parent Msi."/>
1792 <columnDefinition name="WixBundlePackage_Msp" type="string" length="0" category="identifier" primaryKey="yes"
1793 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table for the referenced Msp." />
1794 </tableDefinition>
1795 <tableDefinition name="WixBundlePackageCommandLine" createSymbols="yes" unreal="yes">
1796 <columnDefinition name="WixBundlePackage_" type="string" length="0" category="identifier" primaryKey="yes"
1797 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table." />
1798 <columnDefinition name="InstallArgument" type="string" length="0" nullable="yes" />
1799 <columnDefinition name="UninstallArgument" type="string" length="0" nullable="yes" />
1800 <columnDefinition name="RepairArgument" type="string" length="0" nullable="yes" />
1801 <columnDefinition name="Condition" type="string" length="0" nullable="yes" />
1802 </tableDefinition>
1803 <tableDefinition name="WixRelatedBundle" unreal="yes">
1804 <columnDefinition name="Id" type="string" length="38" category="guid" primaryKey="yes" />
1805 <columnDefinition name="Action" type="number" length="4" />
1806 </tableDefinition>
1807 <tableDefinition name="WixBundleRelatedPackage" unreal="yes">
1808 <columnDefinition name="WixBundlePackage_" type="string" length="0" category="identifier" primaryKey="yes"
1809 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table."/>
1810 <columnDefinition name="Id" type="string" length="0" category="identifier" primaryKey="yes" />
1811 <columnDefinition name="MinVersion" type="string" length="0" />
1812 <columnDefinition name="MaxVersion" type="string" length="0" />
1813 <columnDefinition name="Languages" type="string" length="0" />
1814 <columnDefinition name="MinInclusive" type="number" length="2" minValue="0" maxValue="1"/>
1815 <columnDefinition name="MaxInclusive" type="number" length="2" minValue="0" maxValue="1"/>
1816 <columnDefinition name="LangInclusive" type="number" length="2" minValue="0" maxValue="1"/>
1817 <columnDefinition name="OnlyDetect" type="number" length="2" minValue="0" maxValue="1"/>
1818 </tableDefinition>
1819 <tableDefinition name="WixBundleVariable" createSymbols="yes" unreal="yes">
1820 <columnDefinition name="WixBundleVariable" type="string" length="0" category="identifier" primaryKey="yes" />
1821 <columnDefinition name="Value" type="string" length="0" nullable="yes" />
1822 <columnDefinition name="Type" type="string" length="0" nullable="yes" />
1823 <columnDefinition name="Hidden" type="number" length="2" minValue="0" maxValue="1"/>
1824 <columnDefinition name="Persisted" type="number" length="2" minValue="0" maxValue="1"/>
1825 </tableDefinition>
1826 <tableDefinition name="WixBundleProperties" unreal="yes" bootstrapperApplicationData="yes">
1827 <columnDefinition name="DisplayName" type="string" length="0" nullable="yes"/>
1828 <columnDefinition name="LogPathVariable" type="string" length="0" nullable="yes"/>
1829 <columnDefinition name="Compressed" type="string" length="0" nullable="yes"/>
1830 <columnDefinition name="Id" type="string" length="0" nullable="yes"/>
1831 <columnDefinition name="UpgradeCode" type="string" length="0" nullable="yes"/>
1832 <columnDefinition name="PerMachine" type="string" length="0" nullable="yes"/>
1833 </tableDefinition>
1834 <tableDefinition name="WixPackageFeatureInfo" unreal="yes" bootstrapperApplicationData="yes">
1835 <columnDefinition name="Package" type="string" length="0" />
1836 <columnDefinition name="Feature" type="string" length="0" />
1837 <columnDefinition name="Size" type="string" length="0" />
1838 <columnDefinition name="Parent" type="string" length="0" nullable="yes" />
1839 <columnDefinition name="Title" type="string" length="0" nullable="yes" />
1840 <columnDefinition name="Description" type="string" length="0" nullable="yes" />
1841 <columnDefinition name="Display" type="string" length="0" nullable="yes" />
1842 <columnDefinition name="Level" type="string" length="0" />
1843 <columnDefinition name="Directory" type="string" length="0" nullable="yes"/>
1844 <columnDefinition name="Attributes" type="string" length="0" />
1845 </tableDefinition>
1846 <tableDefinition name="WixPackageProperties" unreal="yes" bootstrapperApplicationData="yes">
1847 <columnDefinition name="Package" type="string" length="0" category="identifier" primaryKey="yes"
1848 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table."/>
1849 <columnDefinition name="Vital" type="string" length="0" nullable="yes" minValue="0" maxValue="1" />
1850 <columnDefinition name="DisplayName" type="string" length="0" nullable="yes"/>
1851 <columnDefinition name="Description" type="string" length="0" nullable="yes"/>
1852 <columnDefinition name="DownloadSize" type="string" length="0" nullable="yes"/>
1853 <columnDefinition name="PackageSize" type="string" length="0" nullable="yes"/>
1854 <columnDefinition name="InstalledSize" type="string" length="0" nullable="yes"/>
1855 <columnDefinition name="PackageType" type="string" length="0" nullable="no"/>
1856 <columnDefinition name="Permanent" type="string" length="0" nullable="yes"/>
1857 <columnDefinition name="LogPathVariable" type="string" length="0" nullable="yes"/>
1858 <columnDefinition name="RollbackLogPathVariable" type="string" length="0" nullable="yes"/>
1859 <columnDefinition name="Compressed" type="string" length="0" nullable="yes"/>
1860 <columnDefinition name="DisplayInternalUI" type="string" length="0" nullable="yes"/>
1861 <columnDefinition name="ProductCode" type="string" length="0" nullable="yes"/>
1862 <columnDefinition name="UpgradeCode" type="string" length="0" nullable="yes"/>
1863 <columnDefinition name="Version" type="string" length="0" nullable="yes"/>
1864 <columnDefinition name="InstallCondition" type="string" length="0" nullable="yes" />
1865 <columnDefinition name="Cache" type="string" length="0" nullable="yes" minValue="0" maxValue="2" />
1866 </tableDefinition>
1867 <tableDefinition name="WixPayloadProperties" unreal="yes" bootstrapperApplicationData="yes">
1868 <columnDefinition name="Payload" type="string" length="0" category="identifier" primaryKey="yes" />
1869 <columnDefinition name="Package" type="string" length="0" category="identifier" primaryKey="yes" nullable="yes"
1870 keyTable="WixBundlePackage" keyColumn="1" description="Reference to a chain package entry in the WixBundlePackage table."/>
1871 <columnDefinition name="Container" type="string" length="0" nullable="yes"
1872 keyTable="WixBundleContainer" keyColumn="1" description="Reference to a container entry in the WixBundleContainer table."/>
1873 <columnDefinition name="Name" type="string" length="0" />
1874 <columnDefinition name="Size" type="string" length="0" />
1875 <columnDefinition name="DownloadUrl" type="string" length="0" nullable="yes" />
1876 <columnDefinition name="LayoutOnly" type="string" length="3" nullable="no" />
1877 </tableDefinition>
1878 <tableDefinition name="_Streams" unreal="yes">
1879 <columnDefinition name="Name" type="string" length="62" primaryKey="yes"/>
1880 <columnDefinition name="Data" type="object" length="0" nullable="yes"/>
1881 </tableDefinition>
1882 <tableDefinition name="_SummaryInformation">
1883 <columnDefinition name="PropertyId" type="number" length="2" primaryKey="yes"/>
1884 <columnDefinition name="Value" type="localized" length="255" escapeIdtCharacters="yes"/>
1885 </tableDefinition>
1886 <tableDefinition name="_TransformView" unreal="yes">
1887 <columnDefinition name="Table" type="string" length="0" primaryKey="yes"/>
1888 <columnDefinition name="Column" type="string" length="0" primaryKey="yes"/>
1889 <columnDefinition name="Row" type="string" length="0"/>
1890 <columnDefinition name="Data" type="string" length="0"/>
1891 <columnDefinition name="Current" type="string" length="0"/>
1892 </tableDefinition>
1893 <tableDefinition name="_Validation">
1894 <columnDefinition name="Table" type="string" length="32" primaryKey="yes"
1895 category="identifier" description="Name of table"/>
1896 <columnDefinition name="Column" type="string" length="32" primaryKey="yes"
1897 category="identifier" description="Name of column"/>
1898 <columnDefinition name="Nullable" type="string" length="4"
1899 set="Y;N" description="Whether the column is nullable"/>
1900 <columnDefinition name="MinValue" type="number" length="4" nullable="yes"
1901 minValue="-2147483647" maxValue="2147483647" description="Minimum value allowed"/>
1902 <columnDefinition name="MaxValue" type="number" length="4" nullable="yes"
1903 minValue="-2147483647" maxValue="2147483647" description="Maximum value allowed"/>
1904 <columnDefinition name="KeyTable" type="string" length="255" nullable="yes"
1905 category="identifier" description="For foreign key, Name of table to which data must link"/>
1906 <columnDefinition name="KeyColumn" type="number" length="2" nullable="yes"
1907 minValue="1" maxValue="32" description="Column to which foreign key connects"/>
1908 <columnDefinition name="Category" type="string" length="32" nullable="yes"
1909 set="Text;Formatted;Template;Condition;Guid;Path;Version;Language;Identifier;Binary;UpperCase;LowerCase;Filename;Paths;AnyPath;WildCardFilename;RegPath;CustomSource;Property;Cabinet;Shortcut;FormattedSDDLText;Integer;DoubleInteger;TimeDate;DefaultDir" description="String category"/>
1910 <columnDefinition name="Set" type="string" length="255" nullable="yes"
1911 category="text" description="Set of values that are permitted"/>
1912 <columnDefinition name="Description" type="string" length="255" nullable="yes"
1913 category="text" description="Description of column"/>
1914 </tableDefinition>
1915 <!-- WixSearch tables are used by multiple extensions and binder knows about them. -->
1916 <tableDefinition name="WixSearch" createSymbols="yes" unreal="yes">
1917 <columnDefinition name="WixSearch" type="string" length="72" category="identifier" primaryKey="yes" />
1918 <columnDefinition name="Variable" type="string" length="72" category="identifier" nullable="yes" />
1919 <columnDefinition name="Condition" type="string" length="255" category="condition" nullable="yes" />
1920 </tableDefinition>
1921 <tableDefinition name="WixSearchRelation" createSymbols="yes" unreal="yes">
1922 <columnDefinition name="WixSearch_" type="string" length="72" category="identifier" primaryKey="yes"
1923 keyTable="WixSearch" keyColumn="1" description="Reference to a WixSearch entry in the WixSearch table."/>
1924 <columnDefinition name="ParentId_" type="string" length="72" category="identifier" primaryKey="yes"
1925 keyTable="WixSearch" keyColumn="1" description="Reference to a WixSearch entry in the WixSearch table."/>
1926 <columnDefinition name="Attributes" type="number" length="4" category="doubleInteger" />
1927 </tableDefinition>
1928 <tableDefinition name="WixFileSearch" createSymbols="yes" unreal="yes">
1929 <columnDefinition name="WixSearch_" type="string" length="72" category="identifier" primaryKey="yes"
1930 keyTable="WixSearch" keyColumn="1" description="Reference to a WixSearch entry in the WixSearch table."/>
1931 <columnDefinition name="Path" type="string" category="text" length="255" />
1932 <columnDefinition name="MinVersion" type="string" length="24" category="version" nullable="yes" />
1933 <columnDefinition name="MaxVersion" type="string" length="24" category="version" nullable="yes" />
1934 <columnDefinition name="MinSize" type="number" length="4" category="doubleInteger" nullable="yes" />
1935 <columnDefinition name="MaxSize" type="number" length="4" category="doubleInteger" nullable="yes" />
1936 <columnDefinition name="MinDate" type="number" length="4" category="doubleInteger" nullable="yes" />
1937 <columnDefinition name="MaxDate" type="number" length="4" category="doubleInteger" nullable="yes" />
1938 <columnDefinition name="Languages" type="string" category="text" length="0" nullable="yes" />
1939 <columnDefinition name="Attributes" type="number" length="4" category="doubleInteger" />
1940 </tableDefinition>
1941 <tableDefinition name="WixRegistrySearch" createSymbols="yes" unreal="yes">
1942 <columnDefinition name="WixSearch_" type="string" length="72" category="identifier" primaryKey="yes"
1943 keyTable="WixSearch" keyColumn="1" description="Reference to a WixSearch entry in the WixSearch table."/>
1944 <columnDefinition name="Root" type="number" length="2" category="doubleInteger" />
1945 <columnDefinition name="Key" type="string" category="text" length="255" />
1946 <columnDefinition name="Value" type="string" category="text" length="255" nullable="yes" />
1947 <columnDefinition name="Attributes" type="number" length="4" category="doubleInteger" />
1948 </tableDefinition>
1949 <tableDefinition name="WixComponentSearch" createSymbols="yes" unreal="yes">
1950 <columnDefinition name="WixSearch_" type="string" length="72" category="identifier" primaryKey="yes"
1951 keyTable="WixSearch" keyColumn="1" description="Reference to a WixSearch entry in the WixSearch table."/>
1952 <columnDefinition name="Guid" type="string" length="38" category="guid" />
1953 <columnDefinition name="ProductCode" type="string" length="38" category="guid" nullable="yes" />
1954 <columnDefinition name="Attributes" type="number" length="4" category="doubleInteger" />
1955 </tableDefinition>
1956 <tableDefinition name="WixProductSearch" createSymbols="yes" unreal="yes">
1957 <columnDefinition name="WixSearch_" type="string" length="72" category="identifier" primaryKey="yes"
1958 keyTable="WixSearch" keyColumn="1" description="Reference to a WixSearch entry in the WixSearch table."/>
1959 <columnDefinition name="Guid" type="string" length="38" category="guid" />
1960 <columnDefinition name="Attributes" type="number" length="4" category="doubleInteger" />
1961 </tableDefinition>
1962</tableDefinitions>
diff --git a/src/WixToolset.Data.WindowsInstaller/Field.cs b/src/WixToolset.Data.WindowsInstaller/Field.cs
new file mode 100644
index 00000000..74b78229
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Field.cs
@@ -0,0 +1,266 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Diagnostics;
7 using System.Globalization;
8 using System.Xml;
9
10 /// <summary>
11 /// Field containing data for a column in a row.
12 /// </summary>
13 public class Field
14 {
15 private object data;
16
17 /// <summary>
18 /// Instantiates a new Field.
19 /// </summary>
20 /// <param name="columnDefinition">Column definition for this field.</param>
21 protected Field(ColumnDefinition columnDefinition)
22 {
23 this.Column = columnDefinition;
24 }
25
26 /// <summary>
27 /// Gets or sets the column definition for this field.
28 /// </summary>
29 /// <value>Column definition.</value>
30 public ColumnDefinition Column { get; private set; }
31
32 /// <summary>
33 /// Gets or sets the data for this field.
34 /// </summary>
35 /// <value>Data in the field.</value>
36 public object Data
37 {
38 get
39 {
40 return this.data;
41 }
42
43 set
44 {
45 // Validate the value before setting it.
46 this.data = this.Column.ValidateValue(value);
47 }
48 }
49
50 /// <summary>
51 /// Gets or sets whether this field is modified.
52 /// </summary>
53 /// <value>Whether this field is modified.</value>
54 public bool Modified { get; set; }
55
56 /// <summary>
57 /// Gets or sets the previous data.
58 /// </summary>
59 /// <value>The previous data.</value>
60 public string PreviousData { get; set; }
61
62 /// <summary>
63 /// Instantiate a new Field object of the correct type.
64 /// </summary>
65 /// <param name="columnDefinition">The column definition for the field.</param>
66 /// <returns>The new Field object.</returns>
67 public static Field Create(ColumnDefinition columnDefinition)
68 {
69 return (ColumnType.Object == columnDefinition.Type) ? new ObjectField(columnDefinition) : new Field(columnDefinition);
70 }
71
72 /// <summary>
73 /// Sets the value of a particular field in the row without validating.
74 /// </summary>
75 /// <param name="field">field index.</param>
76 /// <param name="value">Value of a field in the row.</param>
77 /// <returns>True if successful, false if validation failed.</returns>
78 public bool BestEffortSet(object value)
79 {
80 bool success = true;
81 object bestEffortValue = value;
82
83 try
84 {
85 bestEffortValue = this.Column.ValidateValue(value);
86 }
87 catch (InvalidOperationException)
88 {
89 success = false;
90 }
91
92 this.data = bestEffortValue;
93 return success;
94 }
95
96 /// <summary>
97 /// Determine if this field is identical to another field.
98 /// </summary>
99 /// <param name="field">The other field to compare to.</param>
100 /// <returns>true if they are equal; false otherwise.</returns>
101 public bool IsIdentical(Field field)
102 {
103 return (this.Column.Name == field.Column.Name &&
104 ((null != this.data && this.data.Equals(field.data)) || (null == this.data && null == field.data)));
105 }
106
107 /// <summary>
108 /// Overrides the built in object implementation to return the field's data as a string.
109 /// </summary>
110 /// <returns>Field's data as a string.</returns>
111 public override string ToString()
112 {
113 return this.AsString();
114 }
115
116 /// <summary>
117 /// Gets the field as an integer.
118 /// </summary>
119 /// <returns>Field's data as an integer.</returns>
120 public int AsInteger()
121 {
122 return (this.data is int) ? (int)this.data : Convert.ToInt32(this.data, CultureInfo.InvariantCulture);
123 }
124
125 /// <summary>
126 /// Gets the field as an integer that could be null.
127 /// </summary>
128 /// <returns>Field's data as an integer that could be null.</returns>
129 public int? AsNullableInteger()
130 {
131 return (null == this.data) ? (int?)null : (this.data is int) ? (int)this.data : Convert.ToInt32(this.data, CultureInfo.InvariantCulture);
132 }
133
134 /// <summary>
135 /// Gets the field as a string.
136 /// </summary>
137 /// <returns>Field's data as a string.</returns>
138 public string AsString()
139 {
140 return (null == this.data) ? null : Convert.ToString(this.data, CultureInfo.InvariantCulture);
141 }
142
143 /// <summary>
144 /// Parse a field from the xml.
145 /// </summary>
146 /// <param name="reader">XmlReader where the intermediate is persisted.</param>
147 internal virtual void Read(XmlReader reader)
148 {
149 Debug.Assert("field" == reader.LocalName);
150
151 bool empty = reader.IsEmptyElement;
152
153 while (reader.MoveToNextAttribute())
154 {
155 switch (reader.LocalName)
156 {
157 case "modified":
158 this.Modified = reader.Value.Equals("yes");
159 break;
160 case "previousData":
161 this.PreviousData = reader.Value;
162 break;
163 }
164 }
165
166 if (!empty)
167 {
168 bool done = false;
169
170 while (!done && reader.Read())
171 {
172 switch (reader.NodeType)
173 {
174 case XmlNodeType.Element:
175 throw new XmlException();
176 case XmlNodeType.CDATA:
177 case XmlNodeType.Text:
178 case XmlNodeType.SignificantWhitespace:
179 if (0 < reader.Value.Length)
180 {
181 if (ColumnType.Number == this.Column.Type && !this.Column.IsLocalizable)
182 {
183 // older wix files could persist data as a long value (which would overflow an int)
184 // since the Convert class always throws exceptions for overflows, read in integral
185 // values as a long to avoid the overflow, then cast it to an int (this operation can
186 // overflow without throwing an exception inside an unchecked block)
187 this.data = unchecked((int)Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture));
188 }
189 else
190 {
191 this.data = reader.Value;
192 }
193 }
194 break;
195 case XmlNodeType.EndElement:
196 done = true;
197 break;
198 }
199 }
200
201 if (!done)
202 {
203 throw new XmlException();
204 }
205 }
206 }
207
208 /// <summary>
209 /// Persists a field in an XML format.
210 /// </summary>
211 /// <param name="writer">XmlWriter where the Field should persist itself as XML.</param>
212 internal virtual void Write(XmlWriter writer)
213 {
214 writer.WriteStartElement("field", Intermediate.XmlNamespaceUri);
215
216 if (this.Modified)
217 {
218 writer.WriteAttributeString("modified", "yes");
219 }
220
221 if (null != this.PreviousData)
222 {
223 writer.WriteAttributeString("previousData", this.PreviousData);
224 }
225
226 // Convert the data to a string that will persist nicely (nulls as String.Empty).
227 string text = Convert.ToString(this.data, CultureInfo.InvariantCulture);
228 if (this.Column.UseCData)
229 {
230 writer.WriteCData(text);
231 }
232 else
233 {
234 writer.WriteString(text);
235 }
236
237 writer.WriteEndElement();
238 }
239
240 /// <summary>
241 /// Returns the field data in a format usable in IDT files.
242 /// </summary>
243 /// <returns>Field data in string IDT format.</returns>
244 internal string ToIdtValue()
245 {
246 if (null == this.data)
247 {
248 return null;
249 }
250 else
251 {
252 string fieldData = Convert.ToString(this.data, CultureInfo.InvariantCulture);
253
254 // special idt-specific escaping
255 if (this.Column.EscapeIdtCharacters)
256 {
257 fieldData = fieldData.Replace('\t', '\x10');
258 fieldData = fieldData.Replace('\r', '\x11');
259 fieldData = fieldData.Replace('\n', '\x19');
260 }
261
262 return fieldData;
263 }
264 }
265 }
266}
diff --git a/src/WixToolset.Data.WindowsInstaller/ObjectField.cs b/src/WixToolset.Data.WindowsInstaller/ObjectField.cs
new file mode 100644
index 00000000..42ef111b
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/ObjectField.cs
@@ -0,0 +1,183 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Diagnostics;
7 using System.Globalization;
8 using System.Xml;
9
10 /// <summary>
11 /// Field containing data for an object column in a row.
12 /// </summary>
13 public sealed class ObjectField : Field
14 {
15 /// <summary>
16 /// Instantiates a new Field.
17 /// </summary>
18 /// <param name="columnDefinition">Column definition for this field.</param>
19 internal ObjectField(ColumnDefinition columnDefinition) :
20 base(columnDefinition)
21 {
22 }
23
24 /// <summary>
25 /// Gets or sets the index of the embedded file in a library.
26 /// </summary>
27 /// <value>The index of the embedded file.</value>
28 public int? EmbeddedFileIndex { get; set; }
29
30 /// <summary>
31 /// Gets or sets the previous index of the embedded file in the library.
32 /// </summary>
33 /// <value>The previous index of the embedded file.</value>
34 public int? PreviousEmbeddedFileIndex { get; set; }
35
36 /// <summary>
37 /// Gets or sets the path to the embedded cabinet of the previous file.
38 /// </summary>
39 /// <value>The path of the cabinet containing the previous file.</value>
40 public Uri PreviousBaseUri { get; set; }
41
42 /// <summary>
43 /// Gets the base URI of the object field.
44 /// </summary>
45 /// <value>The base URI of the object field.</value>
46 public Uri BaseUri { get; private set; }
47
48 /// <summary>
49 /// Gets or sets the unresolved data for this field.
50 /// </summary>
51 /// <value>Unresolved Data in the field.</value>
52 public string UnresolvedData { get; set; }
53
54 /// <summary>
55 /// Gets or sets the unresolved previous data.
56 /// </summary>
57 /// <value>The unresolved previous data.</value>
58 public string UnresolvedPreviousData { get; set; }
59
60 /// <summary>
61 /// Parse a field from the xml.
62 /// </summary>
63 /// <param name="reader">XmlReader where the intermediate is persisted.</param>
64 internal override void Read(XmlReader reader)
65 {
66 Debug.Assert("field" == reader.LocalName);
67
68 bool empty = reader.IsEmptyElement;
69
70 this.BaseUri = new Uri(reader.BaseURI);
71
72 while (reader.MoveToNextAttribute())
73 {
74 switch (reader.LocalName)
75 {
76 case "cabinetFileId":
77 this.EmbeddedFileIndex = Convert.ToInt32(reader.Value);
78 break;
79 case "modified":
80 this.Modified = reader.Value.Equals("yes");
81 break;
82 case "previousData":
83 this.PreviousData = reader.Value;
84 break;
85 case "unresolvedPreviousData":
86 this.UnresolvedPreviousData = reader.Value;
87 break;
88 case "unresolvedData":
89 this.UnresolvedData = reader.Value;
90 break;
91 case "previousCabinetFileId":
92 this.PreviousEmbeddedFileIndex = Convert.ToInt32(reader.Value);
93 break;
94 }
95 }
96
97 if (!empty)
98 {
99 bool done = false;
100
101 while (!done && reader.Read())
102 {
103 switch (reader.NodeType)
104 {
105 case XmlNodeType.Element:
106 throw new XmlException();
107 case XmlNodeType.CDATA:
108 case XmlNodeType.Text:
109 if (0 < reader.Value.Length)
110 {
111 this.Data = reader.Value;
112 }
113 break;
114 case XmlNodeType.EndElement:
115 done = true;
116 break;
117 }
118 }
119
120 if (!done)
121 {
122 throw new XmlException();
123 }
124 }
125 }
126
127 /// <summary>
128 /// Persists a field in an XML format.
129 /// </summary>
130 /// <param name="writer">XmlWriter where the Field should persist itself as XML.</param>
131 internal override void Write(XmlWriter writer)
132 {
133 writer.WriteStartElement("field", Intermediate.XmlNamespaceUri);
134
135 if (this.EmbeddedFileIndex.HasValue)
136 {
137 writer.WriteStartAttribute("cabinetFileId");
138 writer.WriteValue(this.EmbeddedFileIndex);
139 writer.WriteEndAttribute();
140 }
141
142 if (this.Modified)
143 {
144 writer.WriteAttributeString("modified", "yes");
145 }
146
147 if (null != this.UnresolvedPreviousData)
148 {
149 writer.WriteAttributeString("unresolvedPreviousData", this.UnresolvedPreviousData);
150 }
151
152 if (null != this.PreviousData)
153 {
154 writer.WriteAttributeString("previousData", this.PreviousData);
155 }
156
157 if (null != this.UnresolvedData)
158 {
159 writer.WriteAttributeString("unresolvedData", this.UnresolvedData);
160 }
161
162 if (this.PreviousEmbeddedFileIndex.HasValue)
163 {
164 writer.WriteStartAttribute("previousCabinetFileId");
165 writer.WriteValue(this.PreviousEmbeddedFileIndex);
166 writer.WriteEndAttribute();
167 }
168
169 // Convert the data to a string that will persist nicely (nulls as String.Empty).
170 string text = Convert.ToString(this.Data, CultureInfo.InvariantCulture);
171 if (this.Column.UseCData)
172 {
173 writer.WriteCData(text);
174 }
175 else
176 {
177 writer.WriteString(text);
178 }
179
180 writer.WriteEndElement();
181 }
182 }
183}
diff --git a/src/WixToolset.Data.WindowsInstaller/Output.cs b/src/WixToolset.Data.WindowsInstaller/Output.cs
new file mode 100644
index 00000000..71faeac7
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Output.cs
@@ -0,0 +1,342 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Globalization;
8 using System.IO;
9 using System.Linq;
10 using System.Xml;
11
12 /// <summary>
13 /// Output is generated by the linker.
14 /// </summary>
15 public sealed class Output
16 {
17 public const string XmlNamespaceUri = "http://wixtoolset.org/schemas/v4/wixout";
18 private static readonly Version CurrentVersion = new Version("4.0.0.0");
19
20 /// <summary>
21 /// Creates a new empty output object.
22 /// </summary>
23 /// <param name="sourceLineNumbers">The source line information for the output.</param>
24 public Output(SourceLineNumber sourceLineNumbers)
25 {
26 this.SourceLineNumbers = sourceLineNumbers;
27 this.SubStorages = new List<SubStorage>();
28 this.Tables = new TableIndexedCollection();
29 }
30
31 /// <summary>
32 /// Gets the type of the output.
33 /// </summary>
34 /// <value>Type of the output.</value>
35 public OutputType Type { get; set; }
36
37 /// <summary>
38 /// Gets or sets the codepage for this output.
39 /// </summary>
40 /// <value>Codepage of the output.</value>
41 public int Codepage { get; set; }
42
43 /// <summary>
44 /// Gets the source line information for this output.
45 /// </summary>
46 /// <value>The source line information for this output.</value>
47 public SourceLineNumber SourceLineNumbers { get; private set; }
48
49 /// <summary>
50 /// Gets the substorages in this output.
51 /// </summary>
52 /// <value>The substorages in this output.</value>
53 public ICollection<SubStorage> SubStorages { get; private set; }
54
55 /// <summary>
56 /// Gets the tables contained in this output.
57 /// </summary>
58 /// <value>Collection of tables.</value>
59 public TableIndexedCollection Tables { get; private set; }
60
61 /// <summary>
62 /// Gets the output type corresponding to a given output filename extension.
63 /// </summary>
64 /// <param name="extension">Case-insensitive output filename extension.</param>
65 /// <returns>Output type for the extension.</returns>
66 public static OutputType GetOutputType(string extension)
67 {
68 if (extension.Equals(".exe", StringComparison.OrdinalIgnoreCase))
69 {
70 return OutputType.Bundle;
71 }
72 if (extension.Equals(".msi", StringComparison.OrdinalIgnoreCase))
73 {
74 return OutputType.Product;
75 }
76 else if (extension.Equals(".msm", StringComparison.OrdinalIgnoreCase))
77 {
78 return OutputType.Module;
79 }
80 else if (extension.Equals(".msp", StringComparison.OrdinalIgnoreCase))
81 {
82 return OutputType.Patch;
83 }
84 else if (extension.Equals(".mst", StringComparison.OrdinalIgnoreCase))
85 {
86 return OutputType.Transform;
87 }
88 else if (extension.Equals(".pcp", StringComparison.OrdinalIgnoreCase))
89 {
90 return OutputType.PatchCreation;
91 }
92 else
93 {
94 return OutputType.Unknown;
95 }
96 }
97
98 /// <summary>
99 /// Gets the filename extension corresponding to a given output type.
100 /// </summary>
101 /// <param name="type">One of the WiX output types.</param>
102 /// <returns>Filename extension for the output type, for example ".msi".</returns>
103 public static string GetExtension(OutputType type)
104 {
105 switch (type)
106 {
107 case OutputType.Bundle:
108 return ".exe";
109 case OutputType.Product:
110 return ".msi";
111 case OutputType.Module:
112 return ".msm";
113 case OutputType.Patch:
114 return ".msp";
115 case OutputType.Transform:
116 return ".mst";
117 case OutputType.PatchCreation:
118 return ".pcp";
119 default:
120 return ".wix";
121 }
122 }
123
124 /// <summary>
125 /// Loads an output from a path on disk.
126 /// </summary>
127 /// <param name="path">Path to output file saved on disk.</param>
128 /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param>
129 /// <returns>Output object.</returns>
130 public static Output Load(string path, bool suppressVersionCheck)
131 {
132 using (FileStream stream = File.OpenRead(path))
133 using (FileStructure fs = FileStructure.Read(stream))
134 {
135 if (FileFormat.Wixout != fs.FileFormat)
136 {
137 throw new WixUnexpectedFileFormatException(path, FileFormat.Wixout, fs.FileFormat);
138 }
139
140 Uri uri = new Uri(Path.GetFullPath(path));
141 using (XmlReader reader = XmlReader.Create(fs.GetDataStream(), null, uri.AbsoluteUri))
142 {
143 try
144 {
145 reader.MoveToContent();
146 return Output.Read(reader, suppressVersionCheck);
147 }
148 catch (XmlException xe)
149 {
150 throw new WixCorruptFileException(path, fs.FileFormat, xe);
151 }
152 }
153 }
154 }
155
156 /// <summary>
157 /// Saves an output to a path on disk.
158 /// </summary>
159 /// <param name="path">Path to save output file to on disk.</param>
160 public void Save(string path)
161 {
162 Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)));
163
164 using (FileStream stream = File.Create(path))
165 using (FileStructure fs = FileStructure.Create(stream, FileFormat.Wixout, null))
166 using (XmlWriter writer = XmlWriter.Create(fs.GetDataStream()))
167 {
168 writer.WriteStartDocument();
169 this.Write(writer);
170 writer.WriteEndDocument();
171 }
172 }
173
174 /// <summary>
175 /// Processes an XmlReader and builds up the output object.
176 /// </summary>
177 /// <param name="reader">Reader to get data from.</param>
178 /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param>
179 /// <returns>The Output represented by the Xml.</returns>
180 internal static Output Read(XmlReader reader, bool suppressVersionCheck)
181 {
182 if (!reader.LocalName.Equals("wixOutput"))
183 {
184 throw new XmlException();
185 }
186
187 bool empty = reader.IsEmptyElement;
188 Output output = new Output(SourceLineNumber.CreateFromUri(reader.BaseURI));
189 SectionType sectionType = SectionType.Unknown;
190 Version version = null;
191
192 while (reader.MoveToNextAttribute())
193 {
194 switch (reader.LocalName)
195 {
196 case "codepage":
197 output.Codepage = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat);
198 break;
199 case "type":
200 switch (reader.Value)
201 {
202 case "Bundle":
203 output.Type = OutputType.Bundle;
204 sectionType = SectionType.Bundle;
205 break;
206 case "Module":
207 output.Type = OutputType.Module;
208 sectionType = SectionType.Module;
209 break;
210 case "Patch":
211 output.Type = OutputType.Patch;
212 break;
213 case "PatchCreation":
214 output.Type = OutputType.PatchCreation;
215 sectionType = SectionType.PatchCreation;
216 break;
217 case "Product":
218 output.Type = OutputType.Product;
219 sectionType = SectionType.Product;
220 break;
221 case "Transform":
222 output.Type = OutputType.Transform;
223 break;
224 default:
225 throw new XmlException();
226 }
227 break;
228 case "version":
229 version = new Version(reader.Value);
230 break;
231 }
232 }
233
234 if (!suppressVersionCheck && null != version && !Output.CurrentVersion.Equals(version))
235 {
236 throw new WixException(WixDataErrors.VersionMismatch(SourceLineNumber.CreateFromUri(reader.BaseURI), "wixOutput", version.ToString(), Output.CurrentVersion.ToString()));
237 }
238
239 // loop through the rest of the xml building up the Output object
240 TableDefinitionCollection tableDefinitions = null;
241 List<Table> tables = new List<Table>();
242 if (!empty)
243 {
244 bool done = false;
245
246 // loop through all the fields in a row
247 while (!done && reader.Read())
248 {
249 switch (reader.NodeType)
250 {
251 case XmlNodeType.Element:
252 switch (reader.LocalName)
253 {
254 case "subStorage":
255 output.SubStorages.Add(SubStorage.Read(reader));
256 break;
257 case "table":
258 if (null == tableDefinitions)
259 {
260 throw new XmlException();
261 }
262 tables.Add(Table.Read(reader, tableDefinitions));
263 break;
264 case "tableDefinitions":
265 tableDefinitions = TableDefinitionCollection.Read(reader);
266 break;
267 default:
268 throw new XmlException();
269 }
270 break;
271 case XmlNodeType.EndElement:
272 done = true;
273 break;
274 }
275 }
276
277 if (!done)
278 {
279 throw new XmlException();
280 }
281 }
282
283 output.Tables = new TableIndexedCollection(tables);
284 return output;
285 }
286
287 /// <summary>
288 /// Ensure this output contains a particular table.
289 /// </summary>
290 /// <param name="tableDefinition">Definition of the table that should exist.</param>
291 /// <param name="section">Optional section to use for the table. If one is not provided, the entry section will be used.</param>
292 /// <returns>The table in this output.</returns>
293 public Table EnsureTable(TableDefinition tableDefinition)
294 {
295 if (!this.Tables.TryGetTable(tableDefinition.Name, out Table table))
296 {
297 table = new Table(tableDefinition);
298 this.Tables.Add(table);
299 }
300
301 return table;
302 }
303
304 /// <summary>
305 /// Persists an output in an XML format.
306 /// </summary>
307 /// <param name="writer">XmlWriter where the Output should persist itself as XML.</param>
308 internal void Write(XmlWriter writer)
309 {
310 writer.WriteStartElement("wixOutput", XmlNamespaceUri);
311
312 writer.WriteAttributeString("type", this.Type.ToString());
313
314 if (0 != this.Codepage)
315 {
316 writer.WriteAttributeString("codepage", this.Codepage.ToString(CultureInfo.InvariantCulture));
317 }
318
319 writer.WriteAttributeString("version", Output.CurrentVersion.ToString());
320
321 // Collect all the table definitions and write them.
322 TableDefinitionCollection tableDefinitions = new TableDefinitionCollection();
323 foreach (Table table in this.Tables)
324 {
325 tableDefinitions.Add(table.Definition);
326 }
327 tableDefinitions.Write(writer);
328
329 foreach (Table table in this.Tables.OrderBy(t => t.Name))
330 {
331 table.Write(writer);
332 }
333
334 foreach (SubStorage subStorage in this.SubStorages)
335 {
336 subStorage.Write(writer);
337 }
338
339 writer.WriteEndElement();
340 }
341 }
342}
diff --git a/src/WixToolset.Data.WindowsInstaller/Pdb.cs b/src/WixToolset.Data.WindowsInstaller/Pdb.cs
new file mode 100644
index 00000000..03c3ddbb
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Pdb.cs
@@ -0,0 +1,163 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.IO;
7 using System.Xml;
8
9 /// <summary>
10 /// Pdb generated by the binder.
11 /// </summary>
12 public sealed class Pdb
13 {
14 public const string XmlNamespaceUri = "http://wixtoolset.org/schemas/v4/wixpdb";
15 private static readonly Version CurrentVersion = new Version("4.0.0.0");
16
17 /// <summary>
18 /// Creates a new empty pdb object.
19 /// </summary>
20 /// <param name="sourceLineNumbers">The source line information for the pdb.</param>
21 public Pdb()
22 {
23 }
24
25 /// <summary>
26 /// Gets or sets the output that is a part of this pdb.
27 /// </summary>
28 /// <value>Type of the output.</value>
29 public Output Output { get; set; }
30
31 /// <summary>
32 /// Loads a pdb from a path on disk.
33 /// </summary>
34 /// <param name="path">Path to pdb file saved on disk.</param>
35 /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param>
36 /// <returns>Pdb pdb.</returns>
37 public static Pdb Load(string path, bool suppressVersionCheck)
38 {
39 using (FileStream stream = File.OpenRead(path))
40 using (FileStructure fs = FileStructure.Read(stream))
41 {
42 if (FileFormat.Wixpdb != fs.FileFormat)
43 {
44 throw new WixUnexpectedFileFormatException(path, FileFormat.Wixpdb, fs.FileFormat);
45 }
46
47 Uri uri = new Uri(Path.GetFullPath(path));
48 using (XmlReader reader = XmlReader.Create(fs.GetDataStream(), null, uri.AbsoluteUri))
49 {
50 try
51 {
52 reader.MoveToContent();
53 return Pdb.Read(reader, suppressVersionCheck);
54 }
55 catch (XmlException xe)
56 {
57 throw new WixCorruptFileException(path, fs.FileFormat, xe);
58 }
59 }
60 }
61 }
62
63 /// <summary>
64 /// Saves a pdb to a path on disk.
65 /// </summary>
66 /// <param name="path">Path to save pdb file to on disk.</param>
67 public void Save(string path)
68 {
69 Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)));
70
71 using (FileStream stream = File.Create(path))
72 using (FileStructure fs = FileStructure.Create(stream, FileFormat.Wixpdb, null))
73 using (XmlWriter writer = XmlWriter.Create(fs.GetDataStream()))
74 {
75 writer.WriteStartDocument();
76 this.Write(writer);
77 writer.WriteEndDocument();
78 }
79 }
80
81 /// <summary>
82 /// Processes an XmlReader and builds up the pdb object.
83 /// </summary>
84 /// <param name="reader">Reader to get data from.</param>
85 /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param>
86 /// <returns>The Pdb represented by the Xml.</returns>
87 internal static Pdb Read(XmlReader reader, bool suppressVersionCheck)
88 {
89 if ("wixPdb" != reader.LocalName)
90 {
91 throw new XmlException();
92 }
93
94 bool empty = reader.IsEmptyElement;
95 Pdb pdb = new Pdb();
96 Version version = null;
97
98 while (reader.MoveToNextAttribute())
99 {
100 switch (reader.LocalName)
101 {
102 case "version":
103 version = new Version(reader.Value);
104 break;
105 }
106 }
107
108 if (!suppressVersionCheck && null != version && !Pdb.CurrentVersion.Equals(version))
109 {
110 throw new WixException(WixDataErrors.VersionMismatch(SourceLineNumber.CreateFromUri(reader.BaseURI), "wixPdb", version.ToString(), Pdb.CurrentVersion.ToString()));
111 }
112
113 // loop through the rest of the pdb building up the Output object
114 if (!empty)
115 {
116 bool done = false;
117
118 // loop through all the fields in a row
119 while (!done && reader.Read())
120 {
121 switch (reader.NodeType)
122 {
123 case XmlNodeType.Element:
124 switch (reader.LocalName)
125 {
126 case "wixOutput":
127 pdb.Output = Output.Read(reader, suppressVersionCheck);
128 break;
129 default:
130 throw new XmlException();
131 }
132 break;
133 case XmlNodeType.EndElement:
134 done = true;
135 break;
136 }
137 }
138
139 if (!done)
140 {
141 throw new XmlException();
142 }
143 }
144
145 return pdb;
146 }
147
148 /// <summary>
149 /// Persists a pdb in an XML format.
150 /// </summary>
151 /// <param name="writer">XmlWriter where the Pdb should persist itself as XML.</param>
152 internal void Write(XmlWriter writer)
153 {
154 writer.WriteStartElement("wixPdb", XmlNamespaceUri);
155
156 writer.WriteAttributeString("version", Pdb.CurrentVersion.ToString());
157
158 this.Output.Write(writer);
159
160 writer.WriteEndElement();
161 }
162 }
163}
diff --git a/src/WixToolset.Data.WindowsInstaller/Row.cs b/src/WixToolset.Data.WindowsInstaller/Row.cs
new file mode 100644
index 00000000..962ed0f4
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Row.cs
@@ -0,0 +1,620 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.Diagnostics.CodeAnalysis;
9 using System.Globalization;
10 using System.Text;
11 using System.Text.RegularExpressions;
12 using System.Xml;
13
14 /// <summary>
15 /// Row containing data for a table.
16 /// </summary>
17 public class Row
18 {
19 private static long rowCount;
20
21 private Field[] fields;
22
23 /// <summary>
24 /// Creates a row that belongs to a table.
25 /// </summary>
26 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
27 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
28 /// <remarks>The compiler should use this constructor exclusively.</remarks>
29 public Row(SourceLineNumber sourceLineNumbers, Table table)
30 : this(sourceLineNumbers, table.Definition)
31 {
32 this.Table = table;
33 }
34
35 /// <summary>
36 /// Creates a row that does not belong to a table.
37 /// </summary>
38 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
39 /// <param name="tableDefinition">TableDefinition this row should get its column definitions from.</param>
40 /// <remarks>This constructor is used in cases where there isn't a clear owner of the row. The linker uses this constructor for the rows it generates.</remarks>
41 public Row(SourceLineNumber sourceLineNumbers, TableDefinition tableDefinition)
42 {
43 this.Number = rowCount++;
44 this.SourceLineNumbers = sourceLineNumbers;
45 this.fields = new Field[tableDefinition.Columns.Count];
46 this.TableDefinition = tableDefinition;
47
48 for (int i = 0; i < this.fields.Length; ++i)
49 {
50 this.fields[i] = Field.Create(this.TableDefinition.Columns[i]);
51 }
52 }
53
54 /// <summary>
55 /// Creates a shallow copy of a row from another row.
56 /// </summary>
57 /// <param name="source">The row the data is copied from.</param>
58 protected Row(Row source)
59 {
60 this.Table = source.Table;
61 this.TableDefinition = source.TableDefinition;
62 this.Number = source.Number;
63 this.Access = source.Access;
64 this.Operation = source.Operation;
65 this.Redundant = source.Redundant;
66 this.SectionId = source.SectionId;
67 this.SourceLineNumbers = source.SourceLineNumbers;
68 this.fields = source.fields;
69 }
70
71 /// <summary>
72 /// Gets or sets the access to the row's primary key.
73 /// </summary>
74 /// <value>The row access modifier.</value>
75 public AccessModifier Access { get; set; }
76
77 /// <summary>
78 /// Gets or sets the row transform operation.
79 /// </summary>
80 /// <value>The row transform operation.</value>
81 public RowOperation Operation { get; set; }
82
83 /// <summary>
84 /// Gets or sets wether the row is a duplicate of another row thus redundant.
85 /// </summary>
86 public bool Redundant { get; set; }
87
88 /// <summary>
89 /// Gets or sets the SectionId property on the row.
90 /// </summary>
91 /// <value>The SectionId property on the row.</value>
92 public string SectionId { get; set; }
93
94 /// <summary>
95 /// Gets the source file and line number for the row.
96 /// </summary>
97 /// <value>Source file and line number.</value>
98 public SourceLineNumber SourceLineNumbers { get; private set; }
99
100 /// <summary>
101 /// Gets the table this row belongs to.
102 /// </summary>
103 /// <value>null if Row does not belong to a Table, or owner Table otherwise.</value>
104 public Table Table { get; private set; }
105
106 /// <summary>
107 /// Gets the table definition for this row.
108 /// </summary>
109 /// <remarks>A Row always has a TableDefinition, even if the Row does not belong to a Table.</remarks>
110 /// <value>TableDefinition for Row.</value>
111 public TableDefinition TableDefinition { get; private set; }
112
113 /// <summary>
114 /// Gets the fields contained by this row.
115 /// </summary>
116 /// <value>Array of field objects</value>
117 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
118 public Field[] Fields
119 {
120 get { return this.fields; }
121 }
122
123 /// <summary>
124 /// Gets the unique number for the row.
125 /// </summary>
126 /// <value>Number for row.</value>
127 public long Number { get; private set; }
128
129 /// <summary>
130 /// Gets or sets the value of a particular field in the row.
131 /// </summary>
132 /// <param name="field">field index.</param>
133 /// <value>Value of a field in the row.</value>
134 public object this[int field]
135 {
136 get { return this.fields[field].Data; }
137 set { this.fields[field].Data = value; }
138 }
139
140 /// <summary>
141 /// Gets the field as an integer.
142 /// </summary>
143 /// <returns>Field's data as an integer.</returns>
144 public int FieldAsInteger(int field)
145 {
146 return this.fields[field].AsInteger();
147 }
148
149 /// <summary>
150 /// Gets the field as an integer that could be null.
151 /// </summary>
152 /// <returns>Field's data as an integer that could be null.</returns>
153 public int? FieldAsNullableInteger(int field)
154 {
155 return this.fields[field].AsNullableInteger();
156 }
157
158 /// <summary>
159 /// Gets the field as a string.
160 /// </summary>
161 /// <returns>Field's data as a string.</returns>
162 public string FieldAsString(int field)
163 {
164 return this.fields[field].AsString();
165 }
166
167 /// <summary>
168 /// Sets the value of a particular field in the row without validating.
169 /// </summary>
170 /// <param name="field">field index.</param>
171 /// <param name="value">Value of a field in the row.</param>
172 /// <returns>True if successful, false if validation failed.</returns>
173 public bool BestEffortSetField(int field, object value)
174 {
175 return this.fields[field].BestEffortSet(value);
176 }
177
178 /// <summary>
179 /// Get the value used to represent the row in a keyed row collection.
180 /// </summary>
181 /// <returns>Primary key or row number if no primary key is available.</returns>
182 public string GetKey()
183 {
184 return this.GetPrimaryKey() ?? Convert.ToString(this.Number, CultureInfo.InvariantCulture);
185 }
186
187 /// <summary>
188 /// Get the primary key of this row.
189 /// </summary>
190 /// <param name="delimiter">Delimiter character for multiple column primary keys.</param>
191 /// <returns>The primary key or null if the row's table has no primary key columns.</returns>
192 public string GetPrimaryKey(char delimiter = '/')
193 {
194 return this.GetPrimaryKey(delimiter, String.Empty);
195 }
196
197 /// <summary>
198 /// Get the primary key of this row.
199 /// </summary>
200 /// <param name="delimiter">Delimiter character for multiple column primary keys.</param>
201 /// <param name="nullReplacement">String to represent null values in the primary key.</param>
202 /// <returns>The primary key or null if the row's table has no primary key columns.</returns>
203 public string GetPrimaryKey(char delimiter, string nullReplacement)
204 {
205 bool foundPrimaryKey = false;
206 StringBuilder primaryKey = new StringBuilder();
207
208 foreach (Field field in this.fields)
209 {
210 if (field.Column.PrimaryKey)
211 {
212 if (foundPrimaryKey)
213 {
214 primaryKey.Append(delimiter);
215 }
216
217 primaryKey.Append((null == field.Data) ? nullReplacement : Convert.ToString(field.Data, CultureInfo.InvariantCulture));
218
219 foundPrimaryKey = true;
220 }
221 else // primary keys must be the first columns of a row so the first non-primary key means we can stop looking.
222 {
223 break;
224 }
225 }
226
227 return foundPrimaryKey ? primaryKey.ToString() : null;
228 }
229
230 /// <summary>
231 /// Returns true if the specified field is null or an empty string.
232 /// </summary>
233 /// <param name="field">Index of the field to check.</param>
234 /// <returns>true if the specified field is null or an empty string, false otherwise.</returns>
235 public bool IsColumnEmpty(int field)
236 {
237 if (null == this.fields[field].Data)
238 {
239 return true;
240 }
241
242 string dataString = this.fields[field].Data as string;
243 if (null != dataString && 0 == dataString.Length)
244 {
245 return true;
246 }
247
248 return false;
249 }
250
251 /// <summary>
252 /// Tests if the passed in row is identical.
253 /// </summary>
254 /// <param name="row">Row to compare against.</param>
255 /// <returns>True if two rows are identical.</returns>
256 public bool IsIdentical(Row row)
257 {
258 bool identical = (this.TableDefinition.Name == row.TableDefinition.Name && this.fields.Length == row.fields.Length);
259
260 for (int i = 0; identical && i < this.fields.Length; ++i)
261 {
262 if (!(this.fields[i].IsIdentical(row.fields[i])))
263 {
264 identical = false;
265 }
266 }
267
268 return identical;
269 }
270
271 /// <summary>
272 /// Returns a string representation of the Row.
273 /// </summary>
274 /// <returns>A string representation of the Row.</returns>
275 public override string ToString()
276 {
277 return String.Join("/", (object[])this.fields);
278 }
279
280 /// <summary>
281 /// Creates a Row from the XmlReader.
282 /// </summary>
283 /// <param name="reader">Reader to get data from.</param>
284 /// <param name="table">Table for this row.</param>
285 /// <returns>New row object.</returns>
286 internal static Row Read(XmlReader reader, Table table)
287 {
288 Debug.Assert("row" == reader.LocalName);
289
290 bool empty = reader.IsEmptyElement;
291 AccessModifier access = AccessModifier.Public;
292 RowOperation operation = RowOperation.None;
293 bool redundant = false;
294 string sectionId = null;
295 SourceLineNumber sourceLineNumbers = null;
296
297 while (reader.MoveToNextAttribute())
298 {
299 switch (reader.LocalName)
300 {
301 case "access":
302 access = (AccessModifier)Enum.Parse(typeof(AccessModifier), reader.Value, true);
303 break;
304 case "op":
305 operation = (RowOperation)Enum.Parse(typeof(RowOperation), reader.Value, true);
306 break;
307 case "redundant":
308 redundant = reader.Value.Equals("yes");
309 break;
310 case "sectionId":
311 sectionId = reader.Value;
312 break;
313 case "sourceLineNumber":
314 sourceLineNumbers = SourceLineNumber.CreateFromEncoded(reader.Value);
315 break;
316 }
317 }
318
319 Row row = table.CreateRow(sourceLineNumbers);
320 row.Access = access;
321 row.Operation = operation;
322 row.Redundant = redundant;
323 row.SectionId = sectionId;
324
325 // loop through all the fields in a row
326 if (!empty)
327 {
328 bool done = false;
329 int field = 0;
330
331 // loop through all the fields in a row
332 while (!done && reader.Read())
333 {
334 switch (reader.NodeType)
335 {
336 case XmlNodeType.Element:
337 switch (reader.LocalName)
338 {
339 case "field":
340 if (row.Fields.Length <= field)
341 {
342 if (!reader.IsEmptyElement)
343 {
344 throw new XmlException();
345 }
346 }
347 else
348 {
349 row.fields[field].Read(reader);
350 }
351 ++field;
352 break;
353 default:
354 throw new XmlException();
355 }
356 break;
357 case XmlNodeType.EndElement:
358 done = true;
359 break;
360 }
361 }
362
363 if (!done)
364 {
365 throw new XmlException();
366 }
367 }
368
369 return row;
370 }
371
372 /// <summary>
373 /// Returns the row in a format usable in IDT files.
374 /// </summary>
375 /// <param name="keepAddedColumns">Whether to keep columns added in a transform.</param>
376 /// <returns>String with tab delimited field values.</returns>
377 internal string ToIdtDefinition(bool keepAddedColumns)
378 {
379 bool first = true;
380 StringBuilder sb = new StringBuilder();
381
382 foreach (Field field in this.fields)
383 {
384 // Conditionally keep columns added in a transform; otherwise,
385 // break because columns can only be added at the end.
386 if (field.Column.Added && !keepAddedColumns)
387 {
388 break;
389 }
390
391 if (first)
392 {
393 first = false;
394 }
395 else
396 {
397 sb.Append('\t');
398 }
399
400 sb.Append(field.ToIdtValue());
401 }
402 sb.Append("\r\n");
403
404 return sb.ToString();
405 }
406
407 /// <summary>
408 /// Gets the modularized version of the field data.
409 /// </summary>
410 /// <param name="field">The field to modularize.</param>
411 /// <param name="modularizationGuid">String containing the GUID of the Merge Module to append the the field value, if appropriate.</param>
412 /// <param name="suppressModularizationIdentifiers">Optional collection of identifiers that should not be modularized.</param>
413 /// <remarks>moduleGuid is expected to be null when not being used to compile a Merge Module.</remarks>
414 /// <returns>The modularized version of the field data.</returns>
415 internal string GetModularizedValue(Field field, string modularizationGuid, ISet<string> suppressModularizationIdentifiers)
416 {
417 Debug.Assert(null != field.Data && 0 < ((string)field.Data).Length);
418 string fieldData = Convert.ToString(field.Data, CultureInfo.InvariantCulture);
419
420 if (null != modularizationGuid && ColumnModularizeType.None != field.Column.ModularizeType && !(WindowsInstallerStandard.IsStandardAction(fieldData) || WindowsInstallerStandard.IsStandardProperty(fieldData)))
421 {
422 StringBuilder sb;
423 int start;
424 ColumnModularizeType modularizeType = field.Column.ModularizeType;
425
426 // special logic for the ControlEvent table's Argument column
427 // this column requires different modularization methods depending upon the value of the Event column
428 if (ColumnModularizeType.ControlEventArgument == field.Column.ModularizeType)
429 {
430 switch (this[2].ToString())
431 {
432 case "CheckExistingTargetPath": // redirectable property name
433 case "CheckTargetPath":
434 case "DoAction": // custom action name
435 case "NewDialog": // dialog name
436 case "SelectionBrowse":
437 case "SetTargetPath":
438 case "SpawnDialog":
439 case "SpawnWaitDialog":
440 if (Common.IsIdentifier(fieldData))
441 {
442 modularizeType = ColumnModularizeType.Column;
443 }
444 else
445 {
446 modularizeType = ColumnModularizeType.Property;
447 }
448 break;
449 default: // formatted
450 modularizeType = ColumnModularizeType.Property;
451 break;
452 }
453 }
454 else if (ColumnModularizeType.ControlText == field.Column.ModularizeType)
455 {
456 // icons are stored in the Binary table, so they get column-type modularization
457 if (("Bitmap" == this[2].ToString() || "Icon" == this[2].ToString()) && Common.IsIdentifier(fieldData))
458 {
459 modularizeType = ColumnModularizeType.Column;
460 }
461 else
462 {
463 modularizeType = ColumnModularizeType.Property;
464 }
465 }
466
467 switch (modularizeType)
468 {
469 case ColumnModularizeType.Column:
470 // ensure the value is an identifier (otherwise it shouldn't be modularized this way)
471 if (!Common.IsIdentifier(fieldData))
472 {
473 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixDataStrings.EXP_CannotModularizeIllegalID, fieldData));
474 }
475
476 // if we're not supposed to suppress modularization of this identifier
477 if (null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(fieldData))
478 {
479 fieldData = String.Concat(fieldData, ".", modularizationGuid);
480 }
481 break;
482
483 case ColumnModularizeType.Property:
484 case ColumnModularizeType.Condition:
485 Regex regex;
486 if (ColumnModularizeType.Property == modularizeType)
487 {
488 regex = new Regex(@"\[(?<identifier>[#$!]?[a-zA-Z_][a-zA-Z0-9_\.]*)]", RegexOptions.Singleline | RegexOptions.ExplicitCapture);
489 }
490 else
491 {
492 Debug.Assert(ColumnModularizeType.Condition == modularizeType);
493
494 // This heinous looking regular expression is actually quite an elegant way
495 // to shred the entire condition into the identifiers that need to be
496 // modularized. Let's break it down piece by piece:
497 //
498 // 1. Look for the operators: NOT, EQV, XOR, OR, AND, IMP (plus a space). Note that the
499 // regular expression is case insensitive so we don't have to worry about
500 // all the permutations of these strings.
501 // 2. Look for quoted strings. Quoted strings are just text and are ignored
502 // outright.
503 // 3. Look for environment variables. These look like identifiers we might
504 // otherwise be interested in but start with a percent sign. Like quoted
505 // strings these enviroment variable references are ignored outright.
506 // 4. Match all identifiers that are things that need to be modularized. Note
507 // the special characters (!, $, ?, &) that denote Component and Feature states.
508 regex = new Regex(@"NOT\s|EQV\s|XOR\s|OR\s|AND\s|IMP\s|"".*?""|%[a-zA-Z_][a-zA-Z0-9_\.]*|(?<identifier>[!$\?&]?[a-zA-Z_][a-zA-Z0-9_\.]*)", RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
509
510 // less performant version of the above with captures showing where everything lives
511 // regex = new Regex(@"(?<operator>NOT|EQV|XOR|OR|AND|IMP)|(?<string>"".*?"")|(?<environment>%[a-zA-Z_][a-zA-Z0-9_\.]*)|(?<identifier>[!$\?&]?[a-zA-Z_][a-zA-Z0-9_\.]*)",RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
512 }
513
514 MatchCollection matches = regex.Matches(fieldData);
515
516 sb = new StringBuilder(fieldData);
517
518 // notice how this code walks backward through the list
519 // because it modifies the string as we through it
520 for (int i = matches.Count - 1; 0 <= i; i--)
521 {
522 Group group = matches[i].Groups["identifier"];
523 if (group.Success)
524 {
525 string identifier = group.Value;
526 if (!WindowsInstallerStandard.IsStandardProperty(identifier) && (null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(identifier)))
527 {
528 sb.Insert(group.Index + group.Length, '.');
529 sb.Insert(group.Index + group.Length + 1, modularizationGuid);
530 }
531 }
532 }
533
534 fieldData = sb.ToString();
535 break;
536
537 case ColumnModularizeType.CompanionFile:
538 // if we're not supposed to ignore this identifier and the value does not start with
539 // a digit, we must have a companion file so modularize it
540 if ((null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(fieldData)) &&
541 0 < fieldData.Length && !Char.IsDigit(fieldData, 0))
542 {
543 fieldData = String.Concat(fieldData, ".", modularizationGuid);
544 }
545 break;
546
547 case ColumnModularizeType.Icon:
548 if (null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(fieldData))
549 {
550 start = fieldData.LastIndexOf(".", StringComparison.Ordinal);
551 if (-1 == start)
552 {
553 fieldData = String.Concat(fieldData, ".", modularizationGuid);
554 }
555 else
556 {
557 fieldData = String.Concat(fieldData.Substring(0, start), ".", modularizationGuid, fieldData.Substring(start));
558 }
559 }
560 break;
561
562 case ColumnModularizeType.SemicolonDelimited:
563 string[] keys = fieldData.Split(';');
564 for (int i = 0; i < keys.Length; ++i)
565 {
566 keys[i] = String.Concat(keys[i], ".", modularizationGuid);
567 }
568 fieldData = String.Join(";", keys);
569 break;
570 }
571 }
572
573 return fieldData;
574 }
575
576 /// <summary>
577 /// Persists a row in an XML format.
578 /// </summary>
579 /// <param name="writer">XmlWriter where the Row should persist itself as XML.</param>
580 [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Changing the way this string normalizes would result " +
581 "in a change to the way intermediate files are generated, potentially causing extra churn in patches on an MSI built from an older version of WiX. " +
582 "Furthermore, there is no security hole here, as the strings won't need to make a round trip")]
583 internal void Write(XmlWriter writer)
584 {
585 writer.WriteStartElement("row", Intermediate.XmlNamespaceUri);
586
587 if (AccessModifier.Public != this.Access)
588 {
589 writer.WriteAttributeString("access", this.Access.ToString().ToLowerInvariant());
590 }
591
592 if (RowOperation.None != this.Operation)
593 {
594 writer.WriteAttributeString("op", this.Operation.ToString().ToLowerInvariant());
595 }
596
597 if (this.Redundant)
598 {
599 writer.WriteAttributeString("redundant", "yes");
600 }
601
602 if (null != this.SectionId)
603 {
604 writer.WriteAttributeString("sectionId", this.SectionId);
605 }
606
607 if (null != this.SourceLineNumbers)
608 {
609 writer.WriteAttributeString("sourceLineNumber", this.SourceLineNumbers.GetEncoded());
610 }
611
612 for (int i = 0; i < this.fields.Length; ++i)
613 {
614 this.fields[i].Write(writer);
615 }
616
617 writer.WriteEndElement();
618 }
619 }
620}
diff --git a/src/WixToolset.Data.WindowsInstaller/RowDictionary.cs b/src/WixToolset.Data.WindowsInstaller/RowDictionary.cs
new file mode 100644
index 00000000..a0cc5302
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/RowDictionary.cs
@@ -0,0 +1,84 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Collections.Generic;
7
8 /// <summary>
9 /// A dictionary of rows. Unlike the <see cref="RowIndexedCollection"/> this
10 /// will throw when multiple rows with the same key are added.
11 /// </summary>
12 public sealed class RowDictionary<T> : Dictionary<string, T> where T : Row
13 {
14 /// <summary>
15 /// Creates an empty <see cref="RowDictionary"/>.
16 /// </summary>
17 public RowDictionary()
18 : base(StringComparer.InvariantCulture)
19 {
20 }
21
22 /// <summary>
23 /// Creates and populates a <see cref="RowDictionary"/> with the rows from the given enumerator.
24 /// </summary>
25 /// <param name="Rows">Rows to add.</param>
26 public RowDictionary(IEnumerable<T> rows)
27 : this()
28 {
29 foreach (T row in rows)
30 {
31 this.Add(row);
32 }
33 }
34
35 /// <summary>
36 /// Creates and populates a <see cref="RowDictionary"/> with the rows from the given <see cref="Table"/>.
37 /// </summary>
38 /// <param name="table">The table to index.</param>
39 /// <remarks>
40 /// Rows added to the index are not automatically added to the given <paramref name="table"/>.
41 /// </remarks>
42 public RowDictionary(Table table)
43 : this()
44 {
45 if (null != table)
46 {
47 foreach (T row in table.Rows)
48 {
49 this.Add(row);
50 }
51 }
52 }
53
54 /// <summary>
55 /// Adds a row to the dictionary using the row key.
56 /// </summary>
57 /// <param name="row">Row to add to the dictionary.</param>
58 public void Add(T row)
59 {
60 this.Add(row.GetKey(), row);
61 }
62
63 /// <summary>
64 /// Gets the row by integer key.
65 /// </summary>
66 /// <param name="key">Integer key to look up.</param>
67 /// <returns>Row or null if key is not found.</returns>
68 public T Get(int key)
69 {
70 return this.Get(key.ToString());
71 }
72
73 /// <summary>
74 /// Gets the row by string key.
75 /// </summary>
76 /// <param name="key">String key to look up.</param>
77 /// <returns>Row or null if key is not found.</returns>
78 public T Get(string key)
79 {
80 T result;
81 return this.TryGetValue(key, out result) ? result : null;
82 }
83 }
84}
diff --git a/src/WixToolset.Data.WindowsInstaller/RowIndexedList.cs b/src/WixToolset.Data.WindowsInstaller/RowIndexedList.cs
new file mode 100644
index 00000000..27c43a81
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/RowIndexedList.cs
@@ -0,0 +1,301 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Collections.Generic;
7
8 /// <summary>
9 /// A list of rows indexed by their primary key. Unlike a <see cref="RowDictionary"/>
10 /// this indexed list will track rows in their added order and will allow rows with
11 /// duplicate keys to be added to the list, although only the first row will be indexed.
12 /// </summary>
13 public sealed class RowIndexedList<T> : IList<T> where T : Row
14 {
15 private Dictionary<string, T> index;
16 private List<T> rows;
17 private List<T> duplicates;
18
19 /// <summary>
20 /// Creates an empty <see cref="RowIndexedList"/>.
21 /// </summary>
22 public RowIndexedList()
23 {
24 this.index = new Dictionary<string, T>(StringComparer.InvariantCulture);
25 this.rows = new List<T>();
26 this.duplicates = new List<T>();
27 }
28
29 /// <summary>
30 /// Creates and populates a <see cref="RowDictionary"/> with the rows from the given enumerator.
31 /// </summary>
32 /// <param name="rows">Rows to index.</param>
33 public RowIndexedList(IEnumerable<T> rows)
34 : this()
35 {
36 foreach (T row in rows)
37 {
38 this.Add(row);
39 }
40 }
41
42 /// <summary>
43 /// Creates and populates a <see cref="RowDictionary"/> with the rows from the given <see cref="Table"/>.
44 /// </summary>
45 /// <param name="table">The table to index.</param>
46 /// <remarks>
47 /// Rows added to the index are not automatically added to the given <paramref name="table"/>.
48 /// </remarks>
49 public RowIndexedList(Table table)
50 : this()
51 {
52 if (null != table)
53 {
54 foreach (T row in table.Rows)
55 {
56 this.Add(row);
57 }
58 }
59 }
60
61 /// <summary>
62 /// Gets the duplicates in the list.
63 /// </summary>
64 public IEnumerable<T> Duplicates { get { return this.duplicates; } }
65
66 /// <summary>
67 /// Gets the row by integer key.
68 /// </summary>
69 /// <param name="key">Integer key to look up.</param>
70 /// <returns>Row or null if key is not found.</returns>
71 public T Get(int key)
72 {
73 return this.Get(key.ToString());
74 }
75
76 /// <summary>
77 /// Gets the row by string key.
78 /// </summary>
79 /// <param name="key">String key to look up.</param>
80 /// <returns>Row or null if key is not found.</returns>
81 public T Get(string key)
82 {
83 T result;
84 return this.TryGet(key, out result) ? result : null;
85 }
86
87 /// <summary>
88 /// Gets the row by string key if it exists.
89 /// </summary>
90 /// <param name="key">Key of row to get.</param>
91 /// <param name="row">Row found.</param>
92 /// <returns>True if key was found otherwise false.</returns>
93 public bool TryGet(string key, out T row)
94 {
95 return this.index.TryGetValue(key, out row);
96 }
97
98 /// <summary>
99 /// Tries to add a row as long as it would not create a duplicate.
100 /// </summary>
101 /// <param name="row">Row to add.</param>
102 /// <returns>True if the row as added otherwise false.</returns>
103 public bool TryAdd(T row)
104 {
105 try
106 {
107 this.index.Add(row.GetKey(), row);
108 }
109 catch (ArgumentException) // if the key already exists, bail.
110 {
111 return false;
112 }
113
114 this.rows.Add(row);
115 return true;
116 }
117
118 /// <summary>
119 /// Adds a row to the list. If a row with the same key is already index, the row is
120 /// is not in the index but will still be part of the list and added to the duplicates
121 /// list.
122 /// </summary>
123 /// <param name="row"></param>
124 public void Add(T row)
125 {
126 this.rows.Add(row);
127 try
128 {
129 this.index.Add(row.GetKey(), row);
130 }
131 catch (ArgumentException) // if the key already exists, we have a duplicate.
132 {
133 this.duplicates.Add(row);
134 }
135 }
136
137 /// <summary>
138 /// Gets the index of a row.
139 /// </summary>
140 /// <param name="row">Iterates through the list of rows to find the index of a particular row.</param>
141 /// <returns>Index of row or -1 if not found.</returns>
142 public int IndexOf(T row)
143 {
144 return this.rows.IndexOf(row);
145 }
146
147 /// <summary>
148 /// Inserts a row at a particular index of the list.
149 /// </summary>
150 /// <param name="index">Index to insert the row after.</param>
151 /// <param name="row">Row to insert.</param>
152 public void Insert(int index, T row)
153 {
154 this.rows.Insert(index, row);
155 try
156 {
157 this.index.Add(row.GetKey(), row);
158 }
159 catch (ArgumentException) // if the key already exists, we have a duplicate.
160 {
161 this.duplicates.Add(row);
162 }
163 }
164
165 /// <summary>
166 /// Removes a row from a particular index.
167 /// </summary>
168 /// <param name="index">Index to remove the row at.</param>
169 public void RemoveAt(int index)
170 {
171 T row = this.rows[index];
172
173 this.rows.RemoveAt(index);
174
175 T indexRow;
176 if (this.index.TryGetValue(row.GetKey(), out indexRow) && indexRow == row)
177 {
178 this.index.Remove(row.GetKey());
179 }
180 else // only try to remove from duplicates if the row was not indexed (if it was indexed, it wasn't a dupe).
181 {
182 this.duplicates.Remove(row);
183 }
184 }
185
186 /// <summary>
187 /// Gets or sets a row at the specified index.
188 /// </summary>
189 /// <param name="index">Index to get the row.</param>
190 /// <returns>Row at specified index.</returns>
191 public T this[int index]
192 {
193 get
194 {
195 return this.rows[index];
196 }
197 set
198 {
199 this.rows[index] = value;
200 try
201 {
202 this.index.Add(value.GetKey(), value);
203 }
204 catch (ArgumentException) // if the key already exists, we have a duplicate.
205 {
206 this.duplicates.Add(value);
207 }
208 }
209 }
210
211 /// <summary>
212 /// Empties the list and it's index.
213 /// </summary>
214 public void Clear()
215 {
216 this.index.Clear();
217 this.rows.Clear();
218 this.duplicates.Clear();
219 }
220
221 /// <summary>
222 /// Searches the list for a row without using the index.
223 /// </summary>
224 /// <param name="row">Row to look for in the list.</param>
225 /// <returns>True if the row is in the list, otherwise false.</returns>
226 public bool Contains(T row)
227 {
228 return this.rows.Contains(row);
229 }
230
231 /// <summary>
232 /// Copies the rows of the list to an array.
233 /// </summary>
234 /// <param name="array">Array to copy the list into.</param>
235 /// <param name="arrayIndex">Index to start copying at.</param>
236 public void CopyTo(T[] array, int arrayIndex)
237 {
238 this.rows.CopyTo(array, arrayIndex);
239 }
240
241 /// <summary>
242 /// Number of rows in the list.
243 /// </summary>
244 public int Count
245 {
246 get { return this.rows.Count; }
247 }
248
249 /// <summary>
250 /// Indicates whether the list is read-only. Always false.
251 /// </summary>
252 public bool IsReadOnly
253 {
254 get { return false; }
255 }
256
257 /// <summary>
258 /// Removes a row from the list. Indexed rows will be removed but the colleciton will NOT
259 /// promote duplicates to the index automatically. The duplicate would also need to be removed
260 /// and re-added to be indexed.
261 /// </summary>
262 /// <param name="row"></param>
263 /// <returns></returns>
264 public bool Remove(T row)
265 {
266 bool removed = this.rows.Remove(row);
267 if (removed)
268 {
269 T indexRow;
270 if (this.index.TryGetValue(row.GetKey(), out indexRow) && indexRow == row)
271 {
272 this.index.Remove(row.GetKey());
273 }
274 else // only try to remove from duplicates if the row was not indexed (if it was indexed, it wasn't a dupe).
275 {
276 this.duplicates.Remove(row);
277 }
278 }
279
280 return removed;
281 }
282
283 /// <summary>
284 /// Gets an enumerator over the whole list.
285 /// </summary>
286 /// <returns>List enumerator.</returns>
287 public IEnumerator<T> GetEnumerator()
288 {
289 return this.rows.GetEnumerator();
290 }
291
292 /// <summary>
293 /// Gets an untyped enumerator over the whole list.
294 /// </summary>
295 /// <returns>Untyped list enumerator.</returns>
296 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
297 {
298 return this.rows.GetEnumerator();
299 }
300 }
301}
diff --git a/src/WixToolset.Data.WindowsInstaller/RowOperation.cs b/src/WixToolset.Data.WindowsInstaller/RowOperation.cs
new file mode 100644
index 00000000..30dadd4e
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/RowOperation.cs
@@ -0,0 +1,30 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 /// <summary>
6 /// The row transform operations.
7 /// </summary>
8 public enum RowOperation
9 {
10 /// <summary>
11 /// No operation.
12 /// </summary>
13 None,
14
15 /// <summary>
16 /// Added row.
17 /// </summary>
18 Add,
19
20 /// <summary>
21 /// Deleted row.
22 /// </summary>
23 Delete,
24
25 /// <summary>
26 /// Modified row.
27 /// </summary>
28 Modify
29 }
30}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/BBControlRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/BBControlRow.cs
new file mode 100644
index 00000000..d0f08662
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/BBControlRow.cs
@@ -0,0 +1,113 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System.Diagnostics.CodeAnalysis;
6
7 /// <summary>
8 /// Specialization of a row for the Control table.
9 /// </summary>
10 public sealed class BBControlRow : Row
11 {
12 /// <summary>
13 /// Creates a Control row that belongs to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="table">Table this Control row belongs to and should get its column definitions from.</param>
17 public BBControlRow(SourceLineNumber sourceLineNumbers, Table table) :
18 base(sourceLineNumbers, table)
19 {
20 }
21
22 /// <summary>
23 /// Gets or sets the dialog of the Control row.
24 /// </summary>
25 /// <value>Primary key of the Control row.</value>
26 public string Billboard
27 {
28 get { return (string)this.Fields[0].Data; }
29 set { this.Fields[0].Data = value; }
30 }
31
32 /// <summary>
33 /// Gets or sets the identifier for this Control row.
34 /// </summary>
35 /// <value>Identifier for this Control row.</value>
36 public string BBControl
37 {
38 get { return (string)this.Fields[1].Data; }
39 set { this.Fields[1].Data = value; }
40 }
41
42 /// <summary>
43 /// Gets or sets the type of the BBControl.
44 /// </summary>
45 /// <value>Name of the BBControl.</value>
46 [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")]
47 public string Type
48 {
49 get { return this.Fields[2].AsString(); }
50 set { this.Fields[2].Data = value; }
51 }
52
53 /// <summary>
54 /// Gets or sets the X location of the BBControl.
55 /// </summary>
56 /// <value>X location of the BBControl.</value>
57 public string X
58 {
59 get { return this.Fields[3].AsString(); }
60 set { this.Fields[3].Data = value; }
61 }
62
63 /// <summary>
64 /// Gets or sets the Y location of the BBControl.
65 /// </summary>
66 /// <value>Y location of the BBControl.</value>
67 public string Y
68 {
69 get { return this.Fields[4].AsString(); }
70 set { this.Fields[4].Data = value; }
71 }
72
73 /// <summary>
74 /// Gets or sets the width of the BBControl.
75 /// </summary>
76 /// <value>Width of the BBControl.</value>
77 public string Width
78 {
79 get { return this.Fields[5].AsString(); }
80 set { this.Fields[5].Data = value; }
81 }
82
83 /// <summary>
84 /// Gets or sets the height of the BBControl.
85 /// </summary>
86 /// <value>Height of the BBControl.</value>
87 public string Height
88 {
89 get { return this.Fields[6].AsString(); }
90 set { this.Fields[6].Data = value; }
91 }
92
93 /// <summary>
94 /// Gets or sets the attributes for the BBControl.
95 /// </summary>
96 /// <value>Attributes for the BBControl.</value>
97 public int Attributes
98 {
99 get { return (int)this.Fields[7].Data; }
100 set { this.Fields[7].Data = value; }
101 }
102
103 /// <summary>
104 /// Gets or sets the text of the BBControl.
105 /// </summary>
106 /// <value>Text of the BBControl.</value>
107 public string Text
108 {
109 get { return (string)this.Fields[8].Data; }
110 set { this.Fields[8].Data = value; }
111 }
112 }
113}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/ComponentRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/ComponentRow.cs
new file mode 100644
index 00000000..3ff10175
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/ComponentRow.cs
@@ -0,0 +1,245 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using WixToolset.Data.Msi;
7
8 /// <summary>
9 /// Specialization of a row for the Component table.
10 /// </summary>
11 public sealed class ComponentRow : Row
12 {
13 private string sourceFile;
14
15 /// <summary>
16 /// Creates a Control row that belongs to a table.
17 /// </summary>
18 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
19 /// <param name="table">Table this Component row belongs to and should get its column definitions from.</param>
20 public ComponentRow(SourceLineNumber sourceLineNumbers, Table table) :
21 base(sourceLineNumbers, table)
22 {
23 }
24
25 /// <summary>
26 /// Gets or sets the identifier for this Component row.
27 /// </summary>
28 /// <value>Identifier for this Component row.</value>
29 public string Component
30 {
31 get { return (string)this.Fields[0].Data; }
32 set { this.Fields[0].Data = value; }
33 }
34
35 /// <summary>
36 /// Gets or sets the ComponentId for this Component row.
37 /// </summary>
38 /// <value>guid for this Component row.</value>
39 public string Guid
40 {
41 get { return (string)this.Fields[1].Data; }
42 set { this.Fields[1].Data = value; }
43 }
44
45 /// <summary>
46 /// Gets or sets the Directory_ of the Component.
47 /// </summary>
48 /// <value>Directory of the Component.</value>
49 public string Directory
50 {
51 get { return (string)this.Fields[2].Data; }
52 set { this.Fields[2].Data = value; }
53 }
54
55 /// <summary>
56 /// Gets or sets the local only attribute of the Component.
57 /// </summary>
58 /// <value>Local only attribute of the component.</value>
59 public bool IsLocalOnly
60 {
61 get { return MsiInterop.MsidbComponentAttributesLocalOnly == ((int)this.Fields[3].Data & MsiInterop.MsidbComponentAttributesLocalOnly); }
62 set
63 {
64 if (value)
65 {
66 this.Fields[3].Data = (int)this.Fields[3].Data | MsiInterop.MsidbComponentAttributesLocalOnly;
67 }
68 else
69 {
70 this.Fields[3].Data = (int)this.Fields[3].Data & ~MsiInterop.MsidbComponentAttributesLocalOnly;
71 }
72 }
73 }
74
75 /// <summary>
76 /// Gets or sets the source only attribute of the Component.
77 /// </summary>
78 /// <value>Source only attribute of the component.</value>
79 public bool IsSourceOnly
80 {
81 get { return MsiInterop.MsidbComponentAttributesSourceOnly == ((int)this.Fields[3].Data & MsiInterop.MsidbComponentAttributesSourceOnly); }
82 set
83 {
84 if (value)
85 {
86 this.Fields[3].Data = (int)this.Fields[3].Data | MsiInterop.MsidbComponentAttributesSourceOnly;
87 }
88 else
89 {
90 this.Fields[3].Data = (int)this.Fields[3].Data & ~MsiInterop.MsidbComponentAttributesSourceOnly;
91 }
92 }
93 }
94
95 /// <summary>
96 /// Gets or sets the optional attribute of the Component.
97 /// </summary>
98 /// <value>Optional attribute of the component.</value>
99 public bool IsOptional
100 {
101 get { return MsiInterop.MsidbComponentAttributesOptional == ((int)this.Fields[3].Data & MsiInterop.MsidbComponentAttributesOptional); }
102 set
103 {
104 if (value)
105 {
106 this.Fields[3].Data = (int)this.Fields[3].Data | MsiInterop.MsidbComponentAttributesOptional;
107 }
108 else
109 {
110 this.Fields[3].Data = (int)this.Fields[3].Data & ~MsiInterop.MsidbComponentAttributesOptional;
111 }
112 }
113 }
114
115 /// <summary>
116 /// Gets or sets the registry key path attribute of the Component.
117 /// </summary>
118 /// <value>Registry key path attribute of the component.</value>
119 public bool IsRegistryKeyPath
120 {
121 get { return MsiInterop.MsidbComponentAttributesRegistryKeyPath == ((int)this.Fields[3].Data & MsiInterop.MsidbComponentAttributesRegistryKeyPath); }
122 set
123 {
124 if (value)
125 {
126 this.Fields[3].Data = (int)this.Fields[3].Data | MsiInterop.MsidbComponentAttributesRegistryKeyPath;
127 }
128 else
129 {
130 this.Fields[3].Data = (int)this.Fields[3].Data & ~MsiInterop.MsidbComponentAttributesRegistryKeyPath;
131 }
132 }
133 }
134
135 /// <summary>
136 /// Gets or sets the shared dll ref count attribute of the Component.
137 /// </summary>
138 /// <value>Shared dll ref countattribute of the component.</value>
139 public bool IsSharedDll
140 {
141 get { return MsiInterop.MsidbComponentAttributesSharedDllRefCount == ((int)this.Fields[3].Data & MsiInterop.MsidbComponentAttributesSharedDllRefCount); }
142 set
143 {
144 if (value)
145 {
146 this.Fields[3].Data = (int)this.Fields[3].Data | MsiInterop.MsidbComponentAttributesSharedDllRefCount;
147 }
148 else
149 {
150 this.Fields[3].Data = (int)this.Fields[3].Data & ~MsiInterop.MsidbComponentAttributesSharedDllRefCount;
151 }
152 }
153 }
154
155 /// <summary>
156 /// Gets or sets the permanent attribute of the Component.
157 /// </summary>
158 /// <value>Permanent attribute of the component.</value>
159 public bool IsPermanent
160 {
161 get { return MsiInterop.MsidbComponentAttributesPermanent == ((int)this.Fields[3].Data & MsiInterop.MsidbComponentAttributesPermanent); }
162 set
163 {
164 if (value)
165 {
166 this.Fields[3].Data = (int)this.Fields[3].Data | MsiInterop.MsidbComponentAttributesPermanent;
167 }
168 else
169 {
170 this.Fields[3].Data = (int)this.Fields[3].Data & ~MsiInterop.MsidbComponentAttributesPermanent;
171 }
172 }
173 }
174
175 /// <summary>
176 /// Gets or sets the ODBC data source key path attribute of the Component.
177 /// </summary>
178 /// <value>ODBC data source key path attribute of the component.</value>
179 public bool IsOdbcDataSourceKeyPath
180 {
181 get { return MsiInterop.MsidbComponentAttributesODBCDataSource == ((int)this.Fields[3].Data & MsiInterop.MsidbComponentAttributesODBCDataSource); }
182 set
183 {
184 if (value)
185 {
186 this.Fields[3].Data = (int)this.Fields[3].Data | MsiInterop.MsidbComponentAttributesODBCDataSource;
187 }
188 else
189 {
190 this.Fields[3].Data = (int)this.Fields[3].Data & ~MsiInterop.MsidbComponentAttributesODBCDataSource;
191 }
192 }
193 }
194
195 /// <summary>
196 /// Gets or sets the 64 bit attribute of the Component.
197 /// </summary>
198 /// <value>64-bitness of the component.</value>
199 public bool Is64Bit
200 {
201 get { return MsiInterop.MsidbComponentAttributes64bit == ((int)this.Fields[3].Data & MsiInterop.MsidbComponentAttributes64bit); }
202 set
203 {
204 if (value)
205 {
206 this.Fields[3].Data = (int)this.Fields[3].Data | MsiInterop.MsidbComponentAttributes64bit;
207 }
208 else
209 {
210 this.Fields[3].Data = (int)this.Fields[3].Data & ~MsiInterop.MsidbComponentAttributes64bit;
211 }
212 }
213 }
214
215 /// <summary>
216 /// Gets or sets the condition of the Component.
217 /// </summary>
218 /// <value>Condition of the Component.</value>
219 public string Condition
220 {
221 get { return (string)this.Fields[4].Data; }
222 set { this.Fields[4].Data = value; }
223 }
224
225 /// <summary>
226 /// Gets or sets the key path of the Component.
227 /// </summary>
228 /// <value>Key path of the Component.</value>
229 public string KeyPath
230 {
231 get { return (string)this.Fields[5].Data; }
232 set { this.Fields[5].Data = value; }
233 }
234
235 /// <summary>
236 /// Gets or sets the source location to the file to fill in the Text of the control.
237 /// </summary>
238 /// <value>Source location to the file to fill in the Text of the control.</value>
239 public string SourceFile
240 {
241 get { return this.sourceFile; }
242 set { this.sourceFile = value; }
243 }
244 }
245}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/ContainerType.cs b/src/WixToolset.Data.WindowsInstaller/Rows/ContainerType.cs
new file mode 100644
index 00000000..55a74235
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/ContainerType.cs
@@ -0,0 +1,13 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Types of bundle packages.
7 /// </summary>
8 public enum ContainerType
9 {
10 Attached,
11 Detached,
12 }
13}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/ControlRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/ControlRow.cs
new file mode 100644
index 00000000..8fa3f633
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/ControlRow.cs
@@ -0,0 +1,143 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System.Diagnostics.CodeAnalysis;
6
7 /// <summary>
8 /// Specialization of a row for the Control table.
9 /// </summary>
10 public sealed class ControlRow : Row
11 {
12 /// <summary>
13 /// Creates a Control row that belongs to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="table">Table this Control row belongs to and should get its column definitions from.</param>
17 public ControlRow(SourceLineNumber sourceLineNumbers, Table table) :
18 base(sourceLineNumbers, table)
19 {
20 }
21
22 /// <summary>
23 /// Gets or sets the dialog of the Control row.
24 /// </summary>
25 /// <value>Primary key of the Control row.</value>
26 public string Dialog
27 {
28 get { return (string)this.Fields[0].Data; }
29 set { this.Fields[0].Data = value; }
30 }
31
32 /// <summary>
33 /// Gets or sets the identifier for this Control row.
34 /// </summary>
35 /// <value>Identifier for this Control row.</value>
36 public string Control
37 {
38 get { return (string)this.Fields[1].Data; }
39 set { this.Fields[1].Data = value; }
40 }
41
42 /// <summary>
43 /// Gets or sets the type of the control.
44 /// </summary>
45 /// <value>Name of the control.</value>
46 [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")]
47 public string Type
48 {
49 get { return (string)this.Fields[2].Data; }
50 set { this.Fields[2].Data = value; }
51 }
52
53 /// <summary>
54 /// Gets or sets the X location of the control.
55 /// </summary>
56 /// <value>X location of the control.</value>
57 public string X
58 {
59 get { return this.Fields[3].AsString(); }
60 set { this.Fields[3].Data = value; }
61 }
62
63 /// <summary>
64 /// Gets or sets the Y location of the control.
65 /// </summary>
66 /// <value>Y location of the control.</value>
67 public string Y
68 {
69 get { return this.Fields[4].AsString(); }
70 set { this.Fields[4].Data = value; }
71 }
72
73 /// <summary>
74 /// Gets or sets the width of the control.
75 /// </summary>
76 /// <value>Width of the control.</value>
77 public string Width
78 {
79 get { return this.Fields[5].AsString(); }
80 set { this.Fields[5].Data = value; }
81 }
82
83 /// <summary>
84 /// Gets or sets the height of the control.
85 /// </summary>
86 /// <value>Height of the control.</value>
87 public string Height
88 {
89 get { return this.Fields[6].AsString(); }
90 set { this.Fields[6].Data = value; }
91 }
92
93 /// <summary>
94 /// Gets or sets the attributes for the control.
95 /// </summary>
96 /// <value>Attributes for the control.</value>
97 public int Attributes
98 {
99 get { return (int)this.Fields[7].Data; }
100 set { this.Fields[7].Data = value; }
101 }
102
103 /// <summary>
104 /// Gets or sets the Property associated with the control.
105 /// </summary>
106 /// <value>Property associated with the control.</value>
107 public string Property
108 {
109 get { return (string)this.Fields[8].Data; }
110 set { this.Fields[8].Data = value; }
111 }
112
113 /// <summary>
114 /// Gets or sets the text of the control.
115 /// </summary>
116 /// <value>Text of the control.</value>
117 public string Text
118 {
119 get { return (string)this.Fields[9].Data; }
120 set { this.Fields[9].Data = value; }
121 }
122
123 /// <summary>
124 /// Gets or sets the next control.
125 /// </summary>
126 /// <value>Next control.</value>
127 public string Next
128 {
129 get { return (string)this.Fields[10].Data; }
130 set { this.Fields[10].Data = value; }
131 }
132
133 /// <summary>
134 /// Gets or sets the help for the control.
135 /// </summary>
136 /// <value>Help for the control.</value>
137 public string Help
138 {
139 get { return (string)this.Fields[11].Data; }
140 set { this.Fields[11].Data = value; }
141 }
142 }
143}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/FileRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/FileRow.cs
new file mode 100644
index 00000000..de5d5652
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/FileRow.cs
@@ -0,0 +1,640 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.Diagnostics;
7 using System.Globalization;
8 using WixToolset.Data.Msi;
9
10 /// <summary>
11 /// Specialization of a row for the file table.
12 /// </summary>
13 public sealed class FileRow : Row //, IComparable
14 {
15 //private string assemblyApplication;
16 //private string assemblyManifest;
17 //private FileAssemblyType assemblyType;
18 //private string directory;
19 //private int diskId;
20 //private bool fromModule;
21 //private bool isGeneratedShortFileName;
22 //private int patchGroup;
23 //private string processorArchitecture;
24 //private string source;
25 //private Row hashRow;
26 //private List<Row> assemblyNameRows;
27 //private string[] previousSource;
28 //private string symbols;
29 //private string[] previousSymbols;
30 //private PatchAttributeType patchAttributes;
31 //private string retainOffsets;
32 //private string retainLengths;
33 //private string ignoreOffsets;
34 //private string ignoreLengths;
35 //private string[] previousRetainOffsets;
36 //private string[] previousRetainLengths;
37 //private string[] previousIgnoreOffsets;
38 //private string[] previousIgnoreLengths;
39 //private string patch;
40
41 /// <summary>
42 /// Creates a File row that belongs to a table.
43 /// </summary>
44 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
45 /// <param name="table">Table this File row belongs to and should get its column definitions from.</param>
46 public FileRow(SourceLineNumber sourceLineNumbers, Table table)
47 : base(sourceLineNumbers, table)
48 {
49 //this.assemblyType = FileAssemblyType.NotAnAssembly;
50 //this.previousSource = new string[1];
51 //this.previousSymbols = new string[1];
52 //this.previousRetainOffsets = new string[1];
53 //this.previousRetainLengths = new string[1];
54 //this.previousIgnoreOffsets = new string[1];
55 //this.previousIgnoreLengths = new string[1];
56 }
57
58 /// <summary>
59 /// Creates a File row that does not belong to a table.
60 /// </summary>
61 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
62 /// <param name="tableDefinition">TableDefinition this Media row belongs to and should get its column definitions from.</param>
63 public FileRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDefinition)
64 : base(sourceLineNumbers, tableDefinition)
65 {
66 //this.assemblyType = FileAssemblyType.NotAnAssembly;
67 //this.previousSource = new string[1];
68 //this.previousSymbols = new string[1];
69 //this.previousRetainOffsets = new string[1];
70 //this.previousRetainLengths = new string[1];
71 //this.previousIgnoreOffsets = new string[1];
72 //this.previousIgnoreLengths = new string[1];
73 }
74
75 /// <summary>
76 /// Gets or sets the primary key of the file row.
77 /// </summary>
78 /// <value>Primary key of the file row.</value>
79 public string File
80 {
81 get { return (string)this.Fields[0].Data; }
82 set { this.Fields[0].Data = value; }
83 }
84
85 /// <summary>
86 /// Gets or sets the component this file row belongs to.
87 /// </summary>
88 /// <value>Component this file row belongs to.</value>
89 public string Component
90 {
91 get { return (string)this.Fields[1].Data; }
92 set { this.Fields[1].Data = value; }
93 }
94
95 /// <summary>
96 /// Gets or sets the name of the file.
97 /// </summary>
98 /// <value>Name of the file.</value>
99 public string FileName
100 {
101 get { return (string)this.Fields[2].Data; }
102 set { this.Fields[2].Data = value; }
103 }
104
105 /// <summary>
106 /// Gets or sets the real filesystem name of the file (without a pipe). This is typically the long name of the file.
107 /// However, if no long name is available, falls back to the short name.
108 /// </summary>
109 /// <value>Long Name of the file - or if no long name is available, falls back to the short name.</value>
110 public string LongFileName
111 {
112 get
113 {
114 string fileName = this.FileName;
115 int index = fileName.IndexOf('|');
116
117 // If it doesn't contain a pipe, just return the whole string
118 if (-1 == index)
119 {
120 return fileName;
121 }
122 else // otherwise, extract the part of the string after the pipe
123 {
124 return fileName.Substring(index + 1);
125 }
126 }
127 }
128
129 /// <summary>
130 /// Gets or sets the size of the file.
131 /// </summary>
132 /// <value>Size of the file.</value>
133 public int FileSize
134 {
135 get { return (int)this.Fields[3].Data; }
136 set { this.Fields[3].Data = value; }
137 }
138
139 /// <summary>
140 /// Gets or sets the version of the file.
141 /// </summary>
142 /// <value>Version of the file.</value>
143 public string Version
144 {
145 get { return (string)this.Fields[4].Data; }
146 set { this.Fields[4].Data = value; }
147 }
148
149 /// <summary>
150 /// Gets or sets the LCID of the file.
151 /// </summary>
152 /// <value>LCID of the file.</value>
153 public string Language
154 {
155 get { return (string)this.Fields[5].Data; }
156 set { this.Fields[5].Data = value; }
157 }
158
159 /// <summary>
160 /// Gets or sets the attributes on a file.
161 /// </summary>
162 /// <value>Attributes on a file.</value>
163 public int Attributes
164 {
165 get { return Convert.ToInt32(this.Fields[6].Data, CultureInfo.InvariantCulture); }
166 set { this.Fields[6].Data = value; }
167 }
168
169 /// <summary>
170 /// Gets or sets whether this file should be compressed.
171 /// </summary>
172 /// <value>Whether this file should be compressed.</value>
173 public YesNoType Compressed
174 {
175 get
176 {
177 bool compressedFlag = (0 < (this.Attributes & MsiInterop.MsidbFileAttributesCompressed));
178 bool noncompressedFlag = (0 < (this.Attributes & MsiInterop.MsidbFileAttributesNoncompressed));
179
180 if (compressedFlag && noncompressedFlag)
181 {
182 throw new WixException(WixDataErrors.IllegalFileCompressionAttributes(this.SourceLineNumbers));
183 }
184 else if (compressedFlag)
185 {
186 return YesNoType.Yes;
187 }
188 else if (noncompressedFlag)
189 {
190 return YesNoType.No;
191 }
192 else
193 {
194 return YesNoType.NotSet;
195 }
196 }
197
198 set
199 {
200 if (YesNoType.Yes == value)
201 {
202 // these are mutually exclusive
203 this.Attributes |= MsiInterop.MsidbFileAttributesCompressed;
204 this.Attributes &= ~MsiInterop.MsidbFileAttributesNoncompressed;
205 }
206 else if (YesNoType.No == value)
207 {
208 // these are mutually exclusive
209 this.Attributes |= MsiInterop.MsidbFileAttributesNoncompressed;
210 this.Attributes &= ~MsiInterop.MsidbFileAttributesCompressed;
211 }
212 else // not specified
213 {
214 Debug.Assert(YesNoType.NotSet == value);
215
216 // clear any compression bits
217 this.Attributes &= ~MsiInterop.MsidbFileAttributesCompressed;
218 this.Attributes &= ~MsiInterop.MsidbFileAttributesNoncompressed;
219 }
220 }
221 }
222
223 /// <summary>
224 /// Gets or sets the sequence of the file row.
225 /// </summary>
226 /// <value>Sequence of the file row.</value>
227 public int Sequence
228 {
229 get { return (int)this.Fields[7].Data; }
230 set { this.Fields[7].Data = value; }
231 }
232
233 /////// <summary>
234 /////// Gets or sets the type of assembly of file row.
235 /////// </summary>
236 /////// <value>Assembly type for file row.</value>
237 ////public FileAssemblyType AssemblyType
238 ////{
239 //// get { return this.assemblyType; }
240 //// set { this.assemblyType = value; }
241 ////}
242
243 /////// <summary>
244 /////// Gets or sets the identifier for the assembly application.
245 /////// </summary>
246 /////// <value>Identifier for the assembly application.</value>
247 ////public string AssemblyApplication
248 ////{
249 //// get { return this.assemblyApplication; }
250 //// set { this.assemblyApplication = value; }
251 ////}
252
253 /////// <summary>
254 /////// Gets or sets the identifier for the assembly manifest.
255 /////// </summary>
256 /////// <value>Identifier for the assembly manifest.</value>
257 ////public string AssemblyManifest
258 ////{
259 //// get { return this.assemblyManifest; }
260 //// set { this.assemblyManifest = value; }
261 ////}
262
263 /////// <summary>
264 /////// Gets or sets the directory of the file.
265 /////// </summary>
266 /////// <value>Directory of the file.</value>
267 ////public string Directory
268 ////{
269 //// get { return this.directory; }
270 //// set { this.directory = value; }
271 ////}
272
273 /////// <summary>
274 /////// Gets or sets the disk id for this file.
275 /////// </summary>
276 /////// <value>Disk id for the file.</value>
277 ////public int DiskId
278 ////{
279 //// get { return this.diskId; }
280 //// set { this.diskId = value; }
281 ////}
282
283 /////// <summary>
284 /////// Gets or sets the source location to the file.
285 /////// </summary>
286 /////// <value>Source location to the file.</value>
287 ////public string Source
288 ////{
289 //// get { return this.source; }
290 //// set { this.source = value; }
291 ////}
292
293 /////// <summary>
294 /////// Gets or sets the source location to the previous file.
295 /////// </summary>
296 /////// <value>Source location to the previous file.</value>
297 ////public string PreviousSource
298 ////{
299 //// get { return this.previousSource[0]; }
300 //// set { this.previousSource[0] = value; }
301 ////}
302
303 /////// <summary>
304 /////// Gets the source location to the previous files.
305 /////// </summary>
306 /////// <value>Source location to the previous files.</value>
307 ////[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
308 ////public string[] PreviousSourceArray
309 ////{
310 //// get { return this.previousSource; }
311 ////}
312
313 /////// <summary>
314 /////// Gets or sets the architecture the file executes on.
315 /////// </summary>
316 /////// <value>Architecture the file executes on.</value>
317 ////public string ProcessorArchitecture
318 ////{
319 //// get { return this.processorArchitecture; }
320 //// set { this.processorArchitecture = value; }
321 ////}
322
323 /////// <summary>
324 /////// Gets of sets the patch group of a patch-added file.
325 /////// </summary>
326 /////// <value>The patch group of a patch-added file.</value>
327 ////public int PatchGroup
328 ////{
329 //// get { return this.patchGroup; }
330 //// set { this.patchGroup = value; }
331 ////}
332
333 /////// <summary>
334 /////// Gets or sets the patch header of the file.
335 /////// </summary>
336 /////// <value>Patch header of the file.</value>
337 ////public string Patch
338 ////{
339 //// get { return this.patch; }
340 //// set { this.patch = value; }
341 ////}
342
343 /////// <summary>
344 /////// Gets or sets the locations to find the file's symbols.
345 /////// </summary>
346 /////// <value>Symbol paths for the file.</value>
347 ////public string Symbols
348 ////{
349 //// get { return this.symbols; }
350 //// set { this.symbols = value; }
351 ////}
352
353 /////// <summary>
354 /////// Gets or sets the locations to find the file's previous symbols.
355 /////// </summary>
356 /////// <value>Symbol paths for the previous file.</value>
357 ////public string PreviousSymbols
358 ////{
359 //// get { return this.previousSymbols[0]; }
360 //// set { this.previousSymbols[0] = value; }
361 ////}
362
363 /////// <summary>
364 /////// Gets the locations to find the files' previous symbols.
365 /////// </summary>
366 /////// <value>Symbol paths for the previous files.</value>
367 ////[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
368 ////public string[] PreviousSymbolsArray
369 ////{
370 //// get { return this.previousSymbols; }
371 ////}
372
373 /////// <summary>
374 /////// Gets or sets the generated short file name attribute.
375 /////// </summary>
376 /////// <value>The generated short file name attribute.</value>
377 ////public bool IsGeneratedShortFileName
378 ////{
379 //// get { return this.isGeneratedShortFileName; }
380
381 //// set { this.isGeneratedShortFileName = value; }
382 ////}
383
384 /////// <summary>
385 /////// Gets or sets whether this row came from a merge module.
386 /////// </summary>
387 /////// <value>Whether this row came from a merge module.</value>
388 ////public bool FromModule
389 ////{
390 //// get { return this.fromModule; }
391 //// set { this.fromModule = value; }
392 ////}
393
394 /////// <summary>
395 /////// Gets or sets the MsiFileHash row created for this FileRow.
396 /////// </summary>
397 /////// <value>Row for MsiFileHash table.</value>
398 ////public Row HashRow
399 ////{
400 //// get { return this.hashRow; }
401 //// set { this.hashRow = value; }
402 ////}
403
404 /////// <summary>
405 /////// Gets or sets the set of MsiAssemblyName rows created for this FileRow.
406 /////// </summary>
407 /////// <value>RowCollection of MsiAssemblyName table.</value>
408 ////[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
409 ////public List<Row> AssemblyNameRows
410 ////{
411 //// get { return this.assemblyNameRows; }
412 //// set { this.assemblyNameRows = value; }
413 ////}
414
415 /////// <summary>
416 /////// Gets or sets the patching attributes to the file.
417 /////// </summary>
418 /////// <value>Patching attributes of the file.</value>
419 ////public PatchAttributeType PatchAttributes
420 ////{
421 //// get { return this.patchAttributes; }
422 //// set { this.patchAttributes = value; }
423 ////}
424
425 /////// <summary>
426 /////// Gets or sets the delta patch retain-length list for the file.
427 /////// </summary>
428 /////// <value>RetainLength list for the file.</value>
429 ////public string RetainLengths
430 ////{
431 //// get { return this.retainLengths; }
432 //// set { this.retainLengths = value; }
433 ////}
434
435 /////// <summary>
436 /////// Gets or sets the delta patch ignore-offset list for the file.
437 /////// </summary>
438 /////// <value>IgnoreOffset list for the file.</value>
439 ////public string IgnoreOffsets
440 ////{
441 //// get { return this.ignoreOffsets; }
442 //// set { this.ignoreOffsets = value; }
443 ////}
444
445 /////// <summary>
446 /////// Gets or sets the delta patch ignore-length list for the file.
447 /////// </summary>
448 /////// <value>IgnoreLength list for the file.</value>
449 ////public string IgnoreLengths
450 ////{
451 //// get { return this.ignoreLengths; }
452 //// set { this.ignoreLengths = value; }
453 ////}
454
455 /////// <summary>
456 /////// Gets or sets the delta patch retain-offset list for the file.
457 /////// </summary>
458 /////// <value>RetainOffset list for the file.</value>
459 ////public string RetainOffsets
460 ////{
461 //// get { return this.retainOffsets; }
462 //// set { this.retainOffsets = value; }
463 ////}
464
465 /////// <summary>
466 /////// Gets or sets the delta patch retain-length list for the previous file.
467 /////// </summary>
468 /////// <value>RetainLength list for the previous file.</value>
469 ////public string PreviousRetainLengths
470 ////{
471 //// get { return this.previousRetainLengths[0]; }
472 //// set { this.previousRetainLengths[0] = value; }
473 ////}
474
475 /////// <summary>
476 /////// Gets the delta patch retain-length list for the previous files.
477 /////// </summary>
478 /////// <value>RetainLength list for the previous files.</value>
479 ////[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
480 ////public string[] PreviousRetainLengthsArray
481 ////{
482 //// get { return this.previousRetainLengths; }
483 ////}
484
485 /////// <summary>
486 /////// Gets or sets the delta patch ignore-offset list for the previous file.
487 /////// </summary>
488 /////// <value>IgnoreOffset list for the previous file.</value>
489 ////public string PreviousIgnoreOffsets
490 ////{
491 //// get { return this.previousIgnoreOffsets[0]; }
492 //// set { this.previousIgnoreOffsets[0] = value; }
493 ////}
494
495 /////// <summary>
496 /////// Gets the delta patch ignore-offset list for the previous files.
497 /////// </summary>
498 /////// <value>IgnoreOffset list for the previous files.</value>
499 ////[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
500 ////public string[] PreviousIgnoreOffsetsArray
501 ////{
502 //// get { return this.previousIgnoreOffsets; }
503 ////}
504
505 /////// <summary>
506 /////// Gets or sets the delta patch ignore-length list for the previous file.
507 /////// </summary>
508 /////// <value>IgnoreLength list for the previous file.</value>
509 ////public string PreviousIgnoreLengths
510 ////{
511 //// get { return this.previousIgnoreLengths[0]; }
512 //// set { this.previousIgnoreLengths[0] = value; }
513 ////}
514
515 /////// <summary>
516 /////// Gets the delta patch ignore-length list for the previous files.
517 /////// </summary>
518 /////// <value>IgnoreLength list for the previous files.</value>
519 ////[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
520 ////public string[] PreviousIgnoreLengthsArray
521 ////{
522 //// get { return this.previousIgnoreLengths; }
523 ////}
524
525 /////// <summary>
526 /////// Gets or sets the delta patch retain-offset list for the previous file.
527 /////// </summary>
528 /////// <value>RetainOffset list for the previous file.</value>
529 ////public string PreviousRetainOffsets
530 ////{
531 //// get { return this.previousRetainOffsets[0]; }
532 //// set { this.previousRetainOffsets[0] = value; }
533 ////}
534
535 /////// <summary>
536 /////// Gets the delta patch retain-offset list for the previous files.
537 /////// </summary>
538 /////// <value>RetainOffset list for the previous files.</value>
539 ////[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
540 ////public string[] PreviousRetainOffsetsArray
541 ////{
542 //// get { return this.previousRetainOffsets; }
543 ////}
544
545 /////// <summary>
546 /////// Compares the current FileRow with another object of the same type.
547 /////// </summary>
548 /////// <param name="obj">An object to compare with this instance.</param>
549 /////// <returns>An integer that indicates the relative order of the comparands.</returns>
550 ////[SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.ArgumentException.#ctor(System.String)")]
551 ////[SuppressMessage("Microsoft.Globalization", "CA1309:UseOrdinalStringComparison")]
552 ////public int CompareTo(object obj)
553 ////{
554 //// if (this == obj)
555 //// {
556 //// return 0;
557 //// }
558
559 //// FileRow fileRow = obj as FileRow;
560 //// if (null == fileRow)
561 //// {
562 //// throw new ArgumentException(WixDataStrings.EXP_OtherObjectIsNotFileRow);
563 //// }
564
565 //// int compared = this.DiskId - fileRow.DiskId;
566 //// if (0 == compared)
567 //// {
568 //// compared = this.patchGroup - fileRow.patchGroup;
569
570 //// if (0 == compared)
571 //// {
572 //// compared = String.Compare(this.File, fileRow.File, StringComparison.InvariantCulture);
573 //// }
574 //// }
575
576 //// return compared;
577 ////}
578
579 /////// <summary>
580 /////// Copies data from another FileRow object.
581 /////// </summary>
582 /////// <param name="src">An row to get data from.</param>
583 ////public void CopyFrom(FileRow src)
584 ////{
585 //// for (int i = 0; i < src.Fields.Length; i++)
586 //// {
587 //// this[i] = src[i];
588 //// }
589 //// this.assemblyManifest = src.assemblyManifest;
590 //// this.assemblyType = src.assemblyType;
591 //// this.directory = src.directory;
592 //// this.diskId = src.diskId;
593 //// this.fromModule = src.fromModule;
594 //// this.isGeneratedShortFileName = src.isGeneratedShortFileName;
595 //// this.patchGroup = src.patchGroup;
596 //// this.processorArchitecture = src.processorArchitecture;
597 //// this.source = src.source;
598 //// this.PreviousSource = src.PreviousSource;
599 //// this.Operation = src.Operation;
600 //// this.symbols = src.symbols;
601 //// this.PreviousSymbols = src.PreviousSymbols;
602 //// this.patchAttributes = src.patchAttributes;
603 //// this.retainOffsets = src.retainOffsets;
604 //// this.retainLengths = src.retainLengths;
605 //// this.ignoreOffsets = src.ignoreOffsets;
606 //// this.ignoreLengths = src.ignoreLengths;
607 //// this.PreviousRetainOffsets = src.PreviousRetainOffsets;
608 //// this.PreviousRetainLengths = src.PreviousRetainLengths;
609 //// this.PreviousIgnoreOffsets = src.PreviousIgnoreOffsets;
610 //// this.PreviousIgnoreLengths = src.PreviousIgnoreLengths;
611 ////}
612
613 /////// <summary>
614 /////// Appends previous data from another FileRow object.
615 /////// </summary>
616 /////// <param name="src">An row to get data from.</param>
617 ////public void AppendPreviousDataFrom(FileRow src)
618 ////{
619 //// AppendStringToArray(ref this.previousSource, src.previousSource[0]);
620 //// AppendStringToArray(ref this.previousSymbols, src.previousSymbols[0]);
621 //// AppendStringToArray(ref this.previousRetainOffsets, src.previousRetainOffsets[0]);
622 //// AppendStringToArray(ref this.previousRetainLengths, src.previousRetainLengths[0]);
623 //// AppendStringToArray(ref this.previousIgnoreOffsets, src.previousIgnoreOffsets[0]);
624 //// AppendStringToArray(ref this.previousIgnoreLengths, src.previousIgnoreLengths[0]);
625 ////}
626
627 /////// <summary>
628 /////// Helper method for AppendPreviousDataFrom.
629 /////// </summary>
630 /////// <param name="source">Destination array.</param>
631 /////// <param name="destination">Source string.</param>
632 ////private static void AppendStringToArray(ref string[] destination, string source)
633 ////{
634 //// string[] result = new string[destination.Length + 1];
635 //// destination.CopyTo(result, 0);
636 //// result[destination.Length] = source;
637 //// destination = result;
638 ////}
639 }
640}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/MediaRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/MediaRow.cs
new file mode 100644
index 00000000..f387a8d2
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/MediaRow.cs
@@ -0,0 +1,80 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the Media table.
7 /// </summary>
8 public sealed class MediaRow : Row
9 {
10 /// <summary>
11 /// Creates a Media row that belongs to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="table">Table this Media row belongs to and should get its column definitions from.</param>
15 public MediaRow(SourceLineNumber sourceLineNumbers, Table table)
16 : base(sourceLineNumbers, table)
17 {
18 }
19
20 /// <summary>
21 /// Gets or sets the disk id for this media row.
22 /// </summary>
23 /// <value>Disk id.</value>
24 public int DiskId
25 {
26 get { return (int)this.Fields[0].Data; }
27 set { this.Fields[0].Data = value; }
28 }
29
30 /// <summary>
31 /// Gets or sets the last sequence number for this media row.
32 /// </summary>
33 /// <value>Last sequence number.</value>
34 public int LastSequence
35 {
36 get { return (int)this.Fields[1].Data; }
37 set { this.Fields[1].Data = value; }
38 }
39
40 /// <summary>
41 /// Gets or sets the disk prompt for this media row.
42 /// </summary>
43 /// <value>Disk prompt.</value>
44 public string DiskPrompt
45 {
46 get { return (string)this.Fields[2].Data; }
47 set { this.Fields[2].Data = value; }
48 }
49
50 /// <summary>
51 /// Gets or sets the cabinet name for this media row.
52 /// </summary>
53 /// <value>Cabinet name.</value>
54 public string Cabinet
55 {
56 get { return (string)this.Fields[3].Data; }
57 set { this.Fields[3].Data = value; }
58 }
59
60 /// <summary>
61 /// Gets or sets the volume label for this media row.
62 /// </summary>
63 /// <value>Volume label.</value>
64 public string VolumeLabel
65 {
66 get { return (string)this.Fields[4].Data; }
67 set { this.Fields[4].Data = value; }
68 }
69
70 /// <summary>
71 /// Gets or sets the source for this media row.
72 /// </summary>
73 /// <value>Source.</value>
74 public string Source
75 {
76 get { return (string)this.Fields[5].Data; }
77 set { this.Fields[5].Data = value; }
78 }
79 }
80}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/PropertyRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/PropertyRow.cs
new file mode 100644
index 00000000..558df760
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/PropertyRow.cs
@@ -0,0 +1,42 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6
7 /// <summary>
8 /// Specialization of a row for the upgrade table.
9 /// </summary>
10 public sealed class PropertyRow : Row
11 {
12 /// <summary>
13 /// Creates an Upgrade row that belongs to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="table">Table this Upgrade row belongs to and should get its column definitions from.</param>
17 public PropertyRow(SourceLineNumber sourceLineNumbers, Table table) :
18 base(sourceLineNumbers, table)
19 {
20 }
21
22 /// <summary>
23 /// Gets and sets the upgrade code for the row.
24 /// </summary>
25 /// <value>Property identifier for the row.</value>
26 public string Property
27 {
28 get { return (string)this.Fields[0].Data; }
29 set { this.Fields[0].Data = value; }
30 }
31
32 /// <summary>
33 /// Gets and sets the value for the row.
34 /// </summary>
35 /// <value>Property value for the row.</value>
36 public string Value
37 {
38 get { return (string)this.Fields[1].Data; }
39 set { this.Fields[1].Data = value; }
40 }
41 }
42}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/SummaryInfoRowCollection.cs b/src/WixToolset.Data.WindowsInstaller/Rows/SummaryInfoRowCollection.cs
new file mode 100644
index 00000000..bc931f15
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/SummaryInfoRowCollection.cs
@@ -0,0 +1,42 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.Collections;
7 using System.Collections.ObjectModel;
8
9 /// <summary>
10 /// Indexed container class for summary information rows.
11 /// </summary>
12 public sealed class SummaryInfoRowCollection : KeyedCollection<int, Row>
13 {
14 /// <summary>
15 /// Creates the keyed collection from existing rows in a table.
16 /// </summary>
17 /// <param name="table">The summary information table to index.</param>
18 public SummaryInfoRowCollection(Table table)
19 {
20 if (0 != String.CompareOrdinal("_SummaryInformation", table.Name))
21 {
22 string message = string.Format(WixDataStrings.EXP_UnsupportedTable, table.Name);
23 throw new ArgumentException(message, "table");
24 }
25
26 foreach (Row row in table.Rows)
27 {
28 this.Add(row);
29 }
30 }
31
32 /// <summary>
33 /// Gets the summary property ID for the <paramref name="row"/>.
34 /// </summary>
35 /// <param name="row">The row to index.</param>
36 /// <returns>The summary property ID for the <paramref name="row"/>.
37 protected override int GetKeyForItem(Row row)
38 {
39 return (int)row[0];
40 }
41 }
42}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/SymbolPathType.cs b/src/WixToolset.Data.WindowsInstaller/Rows/SymbolPathType.cs
new file mode 100644
index 00000000..964e1caa
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/SymbolPathType.cs
@@ -0,0 +1,17 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// The types that the WixDeltaPatchSymbolPaths table can hold.
7 /// </summary>
8 /// <remarks>The order of these values is important since WixDeltaPatchSymbolPaths are sorted by this type.</remarks>
9 public enum SymbolPathType
10 {
11 File,
12 Component,
13 Directory,
14 Media,
15 Product
16 };
17}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/UpgradeRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/UpgradeRow.cs
new file mode 100644
index 00000000..807a9f93
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/UpgradeRow.cs
@@ -0,0 +1,90 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the upgrade table.
7 /// </summary>
8 public sealed class UpgradeRow : Row
9 {
10 /// <summary>
11 /// Creates an Upgrade row that belongs to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="table">Table this Upgrade row belongs to and should get its column definitions from.</param>
15 public UpgradeRow(SourceLineNumber sourceLineNumbers, Table table) :
16 base(sourceLineNumbers, table)
17 {
18 }
19
20 /// <summary>
21 /// Gets and sets the upgrade code for the row.
22 /// </summary>
23 /// <value>Upgrade code for the row.</value>
24 public string UpgradeCode
25 {
26 get { return (string)this.Fields[0].Data; }
27 set { this.Fields[0].Data = value; }
28 }
29
30 /// <summary>
31 /// Gets and sets the version minimum for the row.
32 /// </summary>
33 /// <value>Version minimum for the row.</value>
34 public string VersionMin
35 {
36 get { return (string)this.Fields[1].Data; }
37 set { this.Fields[1].Data = value; }
38 }
39
40 /// <summary>
41 /// Gets and sets the version maximum for the row.
42 /// </summary>
43 /// <value>Version maximum for the row.</value>
44 public string VersionMax
45 {
46 get { return (string)this.Fields[2].Data; }
47 set { this.Fields[2].Data = value; }
48 }
49
50 /// <summary>
51 /// Gets and sets the language for the row.
52 /// </summary>
53 /// <value>Language for the row.</value>
54 public string Language
55 {
56 get { return (string)this.Fields[3].Data; }
57 set { this.Fields[3].Data = value; }
58 }
59
60 /// <summary>
61 /// Gets and sets the attributes for the row.
62 /// </summary>
63 /// <value>Attributes for the row.</value>
64 public int Attributes
65 {
66 get { return (int)this.Fields[4].Data; }
67 set { this.Fields[4].Data = value; }
68 }
69
70 /// <summary>
71 /// Gets and sets the remove code for the row.
72 /// </summary>
73 /// <value>Remove code for the row.</value>
74 public string Remove
75 {
76 get { return (string)this.Fields[5].Data; }
77 set { this.Fields[5].Data = value; }
78 }
79
80 /// <summary>
81 /// Gets and sets the action property for the row.
82 /// </summary>
83 /// <value>Action property for the row.</value>
84 public string ActionProperty
85 {
86 get { return (string)this.Fields[6].Data; }
87 set { this.Fields[6].Data = value; }
88 }
89 }
90}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixActionRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixActionRow.cs
new file mode 100644
index 00000000..3009e59d
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixActionRow.cs
@@ -0,0 +1,374 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.Globalization;
9 using System.Xml;
10 using System.Xml.Schema;
11
12 /// <summary>
13 /// The Sequence tables that actions may belong to.
14 /// </summary>
15 public enum SequenceTable
16 {
17 /// <summary>AdminUISequence</summary>
18 AdminUISequence,
19
20 /// <summary>AdminExecuteSequence</summary>
21 AdminExecuteSequence,
22
23 /// <summary>AdvtExecuteSequence</summary>
24 AdvtExecuteSequence,
25
26 /// <summary>InstallUISequence</summary>
27 InstallUISequence,
28
29 /// <summary>InstallExecuteSequence</summary>
30 InstallExecuteSequence
31 }
32
33 /// <summary>
34 /// Specialization of a row for the sequence tables.
35 /// </summary>
36 public sealed class WixActionRow : Row, IComparable
37 {
38 private WixActionRowCollection previousActionRows;
39 private WixActionRowCollection nextActionRows;
40
41 /// <summary>
42 /// Instantiates an ActionRow that belongs to a table.
43 /// </summary>
44 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
45 /// <param name="table">Table this Action row belongs to and should get its column definitions from.</param>
46 public WixActionRow(SourceLineNumber sourceLineNumbers, Table table) :
47 base(sourceLineNumbers, table)
48 {
49 }
50
51 /// <summary>
52 /// Instantiates a standard ActionRow.
53 /// </summary>
54 /// <param name="sequenceTable">The sequence table of the standard action.</param>
55 /// <param name="action">The name of the standard action.</param>
56 /// <param name="condition">The condition of the standard action.</param>
57 /// <param name="sequence">The suggested sequence number of the standard action.</param>
58 private WixActionRow(SequenceTable sequenceTable, string action, string condition, int sequence) :
59 base(null, WindowsInstallerStandard.GetTableDefinitions()["WixAction"])
60 {
61 this.SequenceTable = sequenceTable;
62 this.Action = action;
63 this.Condition = condition;
64 this.Sequence = sequence;
65 this.Overridable = true; // all standard actions are overridable by default
66 }
67
68 /// <summary>
69 /// Instantiates an ActionRow by copying data from another ActionRow.
70 /// </summary>
71 /// <param name="source">The row the data is copied from.</param>
72 /// <remarks>The previous and next action collections are not copied.</remarks>
73 private WixActionRow(WixActionRow source)
74 : base(source)
75 {
76 }
77
78 /// <summary>
79 /// Gets or sets the name of the action.
80 /// </summary>
81 /// <value>The name of the action.</value>
82 public string Action
83 {
84 get { return (string)this.Fields[1].Data; }
85 set { this.Fields[1].Data = value; }
86 }
87
88 /// <summary>
89 /// Gets the name of the action this action should be scheduled after.
90 /// </summary>
91 /// <value>The name of the action this action should be scheduled after.</value>
92 public string After
93 {
94 get { return (string)this.Fields[5].Data; }
95 set { this.Fields[5].Data = value; }
96 }
97
98 /// <summary>
99 /// Gets the name of the action this action should be scheduled before.
100 /// </summary>
101 /// <value>The name of the action this action should be scheduled before.</value>
102 public string Before
103 {
104 get { return (string)this.Fields[4].Data; }
105 set { this.Fields[4].Data = value; }
106 }
107
108 /// <summary>
109 /// Gets or sets the condition of the action.
110 /// </summary>
111 /// <value>The condition of the action.</value>
112 public string Condition
113 {
114 get { return (string)this.Fields[2].Data; }
115 set { this.Fields[2].Data = value; }
116 }
117
118 /// <summary>
119 /// Gets or sets whether this action is overridable.
120 /// </summary>
121 /// <value>Whether this action is overridable.</value>
122 public bool Overridable
123 {
124 get { return (1 == Convert.ToInt32(this.Fields[6].Data, CultureInfo.InvariantCulture)); }
125 set { this.Fields[6].Data = (value ? 1 : 0); }
126 }
127
128 /// <summary>
129 /// Gets or sets the sequence number of this action.
130 /// </summary>
131 /// <value>The sequence number of this action.</value>
132 public int Sequence
133 {
134 get { return Convert.ToInt32(this.Fields[3].Data, CultureInfo.InvariantCulture); }
135 set { this.Fields[3].Data = value; }
136 }
137
138 /// <summary>
139 /// Gets of sets the sequence table of this action.
140 /// </summary>
141 /// <value>The sequence table of this action.</value>
142 public SequenceTable SequenceTable
143 {
144 get { return (SequenceTable)Enum.Parse(typeof(SequenceTable), (string)this.Fields[0].Data); }
145 set { this.Fields[0].Data = value.ToString(); }
146 }
147
148 /// <summary>
149 /// Gets the actions that should be scheduled after this action.
150 /// </summary>
151 /// <value>The actions that should be scheduled after this action.</value>
152 public WixActionRowCollection NextActionRows
153 {
154 get
155 {
156 if (null == this.nextActionRows)
157 {
158 this.nextActionRows = new WixActionRowCollection();
159 }
160
161 return this.nextActionRows;
162 }
163 }
164
165 /// <summary>
166 /// Gets the actions that should be scheduled before this action.
167 /// </summary>
168 /// <value>The actions that should be scheduled before this action.</value>
169 public WixActionRowCollection PreviousActionRows
170 {
171 get
172 {
173 if (null == this.previousActionRows)
174 {
175 this.previousActionRows = new WixActionRowCollection();
176 }
177
178 return this.previousActionRows;
179 }
180 }
181
182 /// <summary>
183 /// Creates a clone of the action row.
184 /// </summary>
185 /// <returns>A shallow copy of the source object.</returns>
186 /// <remarks>The previous and next action collections are not copied.</remarks>
187 public WixActionRow Clone()
188 {
189 return new WixActionRow(this);
190 }
191
192 /// <summary>
193 /// Compares the current instance with another object of the same type.
194 /// </summary>
195 /// <param name="obj">Other reference to compare this one to.</param>
196 /// <returns>Returns less than 0 for less than, 0 for equals, and greater than 0 for greater.</returns>
197 public int CompareTo(object obj)
198 {
199 WixActionRow otherActionRow = (WixActionRow)obj;
200
201 return this.Sequence.CompareTo(otherActionRow.Sequence);
202 }
203
204 /// <summary>
205 /// Parses ActionRows from the Xml reader.
206 /// </summary>
207 /// <param name="reader">Xml reader that contains serialized ActionRows.</param>
208 /// <returns>The parsed ActionRows.</returns>
209 internal static WixActionRow[] Parse(XmlReader reader)
210 {
211 Debug.Assert("action" == reader.LocalName);
212
213 string id = null;
214 string condition = null;
215 bool empty = reader.IsEmptyElement;
216 int sequence = int.MinValue;
217 int sequenceCount = 0;
218 SequenceTable[] sequenceTables = new SequenceTable[Enum.GetValues(typeof(SequenceTable)).Length];
219
220 while (reader.MoveToNextAttribute())
221 {
222 switch (reader.Name)
223 {
224 case "name":
225 id = reader.Value;
226 break;
227 case "AdminExecuteSequence":
228 if (reader.Value.Equals("yes"))
229 {
230 sequenceTables[sequenceCount] = SequenceTable.AdminExecuteSequence;
231 ++sequenceCount;
232 }
233 break;
234 case "AdminUISequence":
235 if (reader.Value.Equals("yes"))
236 {
237 sequenceTables[sequenceCount] = SequenceTable.AdminUISequence;
238 ++sequenceCount;
239 }
240 break;
241 case "AdvtExecuteSequence":
242 if (reader.Value.Equals("yes"))
243 {
244 sequenceTables[sequenceCount] = SequenceTable.AdvtExecuteSequence;
245 ++sequenceCount;
246 }
247 break;
248 case "condition":
249 condition = reader.Value;
250 break;
251 case "InstallExecuteSequence":
252 if (reader.Value.Equals("yes"))
253 {
254 sequenceTables[sequenceCount] = SequenceTable.InstallExecuteSequence;
255 ++sequenceCount;
256 }
257 break;
258 case "InstallUISequence":
259 if (reader.Value.Equals("yes"))
260 {
261 sequenceTables[sequenceCount] = SequenceTable.InstallUISequence;
262 ++sequenceCount;
263 }
264 break;
265 case "sequence":
266 sequence = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture);
267 break;
268 }
269 }
270
271 if (null == id)
272 {
273 throw new XmlException();
274 }
275
276 if (int.MinValue == sequence)
277 {
278 throw new XmlException();
279 }
280 else if (1 > sequence)
281 {
282 throw new XmlException();
283 }
284
285 if (0 == sequenceCount)
286 {
287 throw new XmlException();
288 }
289
290 if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
291 {
292 throw new XmlException();
293 }
294
295 // create the actions
296 WixActionRow[] actionRows = new WixActionRow[sequenceCount];
297 for (int i = 0; i < sequenceCount; i++)
298 {
299 WixActionRow actionRow = new WixActionRow(sequenceTables[i], id, condition, sequence);
300 actionRows[i] = actionRow;
301 }
302
303 return actionRows;
304 }
305
306 /// <summary>
307 /// Determines whether this ActionRow contains the specified ActionRow as a child in its dependency tree.
308 /// </summary>
309 /// <param name="actionRow">The possible child ActionRow.</param>
310 /// <returns>true if the ActionRow is a child of this ActionRow; false otherwise.</returns>
311 public bool ContainsChildActionRow(WixActionRow actionRow)
312 {
313 if (null != this.previousActionRows)
314 {
315 if (this.previousActionRows.Contains(actionRow.SequenceTable, actionRow.Action))
316 {
317 return true;
318 }
319 }
320
321 if (null != this.nextActionRows)
322 {
323 if (this.nextActionRows.Contains(actionRow.SequenceTable, actionRow.Action))
324 {
325 return true;
326 }
327 }
328
329 return false;
330 }
331
332 /// <summary>
333 /// Get all the actions scheduled before this one in a particular sequence table.
334 /// </summary>
335 /// <param name="sequenceTable">The sequence table.</param>
336 /// <param name="allPreviousActionRows">A RowCollection which will contain all the previous actions.</param>
337 public void GetAllPreviousActionRows(SequenceTable sequenceTable, IList<WixActionRow> allPreviousActionRows)
338 {
339 if (null != this.previousActionRows)
340 {
341 foreach (WixActionRow actionRow in this.previousActionRows)
342 {
343 if (sequenceTable == actionRow.SequenceTable)
344 {
345 actionRow.GetAllPreviousActionRows(sequenceTable, allPreviousActionRows);
346 allPreviousActionRows.Add(actionRow);
347 actionRow.GetAllNextActionRows(sequenceTable, allPreviousActionRows);
348 }
349 }
350 }
351 }
352
353 /// <summary>
354 /// Get all the actions scheduled after this one in a particular sequence table.
355 /// </summary>
356 /// <param name="sequenceTable">The sequence table.</param>
357 /// <param name="allNextActionRows">A RowCollection which will contain all the next actions.</param>
358 public void GetAllNextActionRows(SequenceTable sequenceTable, IList<WixActionRow> allNextActionRows)
359 {
360 if (null != this.nextActionRows)
361 {
362 foreach (WixActionRow actionRow in this.nextActionRows)
363 {
364 if (sequenceTable == actionRow.SequenceTable)
365 {
366 actionRow.GetAllPreviousActionRows(sequenceTable, allNextActionRows);
367 allNextActionRows.Add(actionRow);
368 actionRow.GetAllNextActionRows(sequenceTable, allNextActionRows);
369 }
370 }
371 }
372 }
373 }
374}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixActionRowCollection.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixActionRowCollection.cs
new file mode 100644
index 00000000..513a104f
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixActionRowCollection.cs
@@ -0,0 +1,222 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.Collections;
7 using System.Diagnostics;
8 using System.Xml;
9
10 /// <summary>
11 /// A collection of action rows sorted by their sequence table and action name.
12 /// </summary>
13 public sealed class WixActionRowCollection : ICollection
14 {
15 private SortedList collection;
16
17 /// <summary>
18 /// Creates a new action table object.
19 /// </summary>
20 public WixActionRowCollection()
21 {
22 this.collection = new SortedList();
23 }
24
25 /// <summary>
26 /// Gets the number of items in the collection.
27 /// </summary>
28 /// <value>Number of items in collection.</value>
29 public int Count
30 {
31 get { return this.collection.Count; }
32 }
33
34 /// <summary>
35 /// Gets if the collection has been synchronized.
36 /// </summary>
37 /// <value>True if the collection has been synchronized.</value>
38 public bool IsSynchronized
39 {
40 get { return this.collection.IsSynchronized; }
41 }
42
43 /// <summary>
44 /// Gets the object used to synchronize the collection.
45 /// </summary>
46 /// <value>Oject used the synchronize the collection.</value>
47 public object SyncRoot
48 {
49 get { return this; }
50 }
51
52 /// <summary>
53 /// Get an ActionRow by its sequence table and action name.
54 /// </summary>
55 /// <param name="sequenceTable">The sequence table of the ActionRow.</param>
56 /// <param name="action">The action name of the ActionRow.</param>
57 public WixActionRow this[SequenceTable sequenceTable, string action]
58 {
59 get { return (WixActionRow)this.collection[GetKey(sequenceTable, action)]; }
60 }
61
62 /// <summary>
63 /// Add an ActionRow to the collection.
64 /// </summary>
65 /// <param name="actionRow">The ActionRow to add.</param>
66 /// <param name="overwrite">true to overwrite an existing ActionRow; false otherwise.</param>
67 public void Add(WixActionRow actionRow, bool overwrite)
68 {
69 string key = GetKey(actionRow.SequenceTable, actionRow.Action);
70
71 if (overwrite)
72 {
73 this.collection[key] = actionRow;
74 }
75 else
76 {
77 this.collection.Add(key, actionRow);
78 }
79 }
80
81 /// <summary>
82 /// Add an ActionRow to the collection.
83 /// </summary>
84 /// <param name="actionRow">The ActionRow to add.</param>
85 public void Add(WixActionRow actionRow)
86 {
87 this.Add(actionRow, false);
88 }
89
90 /// <summary>
91 /// Determines if the collection contains an ActionRow with a specific sequence table and name.
92 /// </summary>
93 /// <param name="sequenceTable">The sequence table of the ActionRow.</param>
94 /// <param name="action">The action name of the ActionRow.</param>
95 /// <returns>true if the ActionRow was found; false otherwise.</returns>
96 public bool Contains(SequenceTable sequenceTable, string action)
97 {
98 return this.collection.Contains(GetKey(sequenceTable, action));
99 }
100
101 /// <summary>
102 /// Copies the collection into an array.
103 /// </summary>
104 /// <param name="array">Array to copy the collection into.</param>
105 /// <param name="index">Index to start copying from.</param>
106 public void CopyTo(System.Array array, int index)
107 {
108 this.collection.Values.CopyTo(array, index);
109 }
110
111 /// <summary>
112 /// Gets the enumerator for the collection.
113 /// </summary>
114 /// <returns>The enumerator for the collection.</returns>
115 public IEnumerator GetEnumerator()
116 {
117 return this.collection.Values.GetEnumerator();
118 }
119
120 /// <summary>
121 /// Remove an ActionRow from the collection.
122 /// </summary>
123 /// <param name="sequenceTable">The sequence table of the ActionRow.</param>
124 /// <param name="action">The action name of the ActionRow.</param>
125 public void Remove(SequenceTable sequenceTable, string action)
126 {
127 this.collection.Remove(GetKey(sequenceTable, action));
128 }
129
130 /// <summary>
131 /// Load an action table from an XmlReader.
132 /// </summary>
133 /// <param name="reader">Reader to get data from.</param>
134 /// <returns>The ActionRowCollection represented by the xml.</returns>
135 internal static WixActionRowCollection Load(XmlReader reader)
136 {
137 reader.MoveToContent();
138
139 return Parse(reader);
140 }
141
142 /// <summary>
143 /// Creates a new action table object and populates it from an Xml reader.
144 /// </summary>
145 /// <param name="reader">Reader to get data from.</param>
146 /// <returns>The parsed ActionTable.</returns>
147 private static WixActionRowCollection Parse(XmlReader reader)
148 {
149 if (!reader.LocalName.Equals("actions"))
150 {
151 throw new XmlException();
152 }
153
154 WixActionRowCollection actionRows = new WixActionRowCollection();
155 bool empty = reader.IsEmptyElement;
156
157 while (reader.MoveToNextAttribute())
158 {
159 }
160
161 if (!empty)
162 {
163 bool done = false;
164
165 // loop through all the fields in a row
166 while (!done && reader.Read())
167 {
168 switch (reader.NodeType)
169 {
170 case XmlNodeType.Element:
171 switch (reader.LocalName)
172 {
173 case "action":
174 WixActionRow[] parsedActionRows = WixActionRow.Parse(reader);
175
176 foreach (WixActionRow actionRow in parsedActionRows)
177 {
178 actionRows.Add(actionRow);
179 }
180 break;
181 default:
182 throw new XmlException();
183 }
184 break;
185 case XmlNodeType.EndElement:
186 done = true;
187 break;
188 }
189 }
190
191 if (!done)
192 {
193 throw new XmlException();
194 }
195 }
196
197 return actionRows;
198 }
199
200 /// <summary>
201 /// Get the key for storing an ActionRow.
202 /// </summary>
203 /// <param name="sequenceTable">The sequence table of the ActionRow.</param>
204 /// <param name="action">The action name of the ActionRow.</param>
205 /// <returns>The string key.</returns>
206 private static string GetKey(SequenceTable sequenceTable, string action)
207 {
208 return GetKey(sequenceTable.ToString(), action);
209 }
210
211 /// <summary>
212 /// Get the key for storing an ActionRow.
213 /// </summary>
214 /// <param name="sequenceTable">The sequence table of the ActionRow.</param>
215 /// <param name="action">The action name of the ActionRow.</param>
216 /// <returns>The string key.</returns>
217 private static string GetKey(string sequenceTable, string action)
218 {
219 return String.Concat(sequenceTable, '/', action);
220 }
221 }
222}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixApprovedExeForElevationRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixApprovedExeForElevationRow.cs
new file mode 100644
index 00000000..c10a39ab
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixApprovedExeForElevationRow.cs
@@ -0,0 +1,79 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5
6 /// <summary>
7 /// Specialization of a row for the WixApprovedExeForElevation table.
8 /// </summary>
9 public class WixApprovedExeForElevationRow : Row
10 {
11 /// <summary>
12 /// Creates an ApprovedExeForElevation row that does not belong to a table.
13 /// </summary>
14 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
15 /// <param name="tableDef">TableDefinition this ApprovedExeForElevation row belongs to and should get its column definitions from.</param>
16 public WixApprovedExeForElevationRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
17 base(sourceLineNumbers, tableDef)
18 {
19 }
20
21 /// <summary>
22 /// Creates an ApprovedExeForElevation row that belongs to a table.
23 /// </summary>
24 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
25 /// <param name="table">Table this ApprovedExeForElevation row belongs to and should get its column definitions from.</param>
26 public WixApprovedExeForElevationRow(SourceLineNumber sourceLineNumbers, Table table)
27 : base(sourceLineNumbers, table)
28 {
29 }
30
31 /// <summary>
32 /// Gets or sets the ApprovedExeForElevation identifier.
33 /// </summary>
34 /// <value>The ApprovedExeForElevation identifier.</value>
35 public string Id
36 {
37 get { return (string)this.Fields[0].Data; }
38 set { this.Fields[0].Data = value; }
39 }
40
41 /// <summary>
42 /// Gets or sets the Key path.
43 /// </summary>
44 /// <value>The Key path.</value>
45 public string Key
46 {
47 get { return (string)this.Fields[1].Data; }
48 set { this.Fields[1].Data = value; }
49 }
50
51 /// <summary>
52 /// Gets or sets the Value name.
53 /// </summary>
54 /// <value>The Value name.</value>
55 public string ValueName
56 {
57 get { return (string)this.Fields[2].Data; }
58 set { this.Fields[2].Data = value; }
59 }
60
61 /// <summary>
62 /// Gets or sets the attibutes.
63 /// </summary>
64 /// <value>The BundleApprovedExeForElevationAttributes.</value>
65 public BundleApprovedExeForElevationAttributes Attributes
66 {
67 get { return (BundleApprovedExeForElevationAttributes)this.Fields[3].Data; }
68 set { this.Fields[3].Data = (int)value; }
69 }
70
71 /// <summary>
72 /// Gets whether this row is 64-bit.
73 /// </summary>
74 public bool Win64
75 {
76 get { return BundleApprovedExeForElevationAttributes.Win64 == (this.Attributes & BundleApprovedExeForElevationAttributes.Win64); }
77 }
78 }
79}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleCatalogRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleCatalogRow.cs
new file mode 100644
index 00000000..05c1e597
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleCatalogRow.cs
@@ -0,0 +1,50 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the WixCatalog table.
7 /// </summary>
8 public sealed class WixBundleCatalogRow : Row
9 {
10 /// <summary>
11 /// Creates a Catalog row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this Catalog row belongs to and should get its column definitions from.</param>
15 public WixBundleCatalogRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a Catalog row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this Catalog row belongs to and should get its column definitions from.</param>
25 public WixBundleCatalogRow(SourceLineNumber sourceLineNumbers, Table table)
26 : base(sourceLineNumbers, table)
27 {
28 }
29
30 /// <summary>
31 /// Gets or sets the catalog identifier.
32 /// </summary>
33 /// <value>The catalog identifier.</value>
34 public string Id
35 {
36 get { return (string)this.Fields[0].Data; }
37 set { this.Fields[0].Data = value; }
38 }
39
40 /// <summary>
41 /// Gets or sets the payload identifier.
42 /// </summary>
43 /// <value>The payload identifier.</value>
44 public string Payload
45 {
46 get { return (string)this.Fields[1].Data; }
47 set { this.Fields[1].Data = value; }
48 }
49 }
50}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleContainerRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleContainerRow.cs
new file mode 100644
index 00000000..7b03dcc5
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleContainerRow.cs
@@ -0,0 +1,78 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the Container table.
7 /// </summary>
8 public class WixBundleContainerRow : Row
9 {
10 /// <summary>
11 /// Creates a ContainerRow row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this Media row belongs to and should get its column definitions from.</param>
15 public WixBundleContainerRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a ContainerRow row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this Media row belongs to and should get its column definitions from.</param>
25 public WixBundleContainerRow(SourceLineNumber sourceLineNumbers, Table table) :
26 base(sourceLineNumbers, table)
27 {
28 }
29
30 public string Id
31 {
32 get { return (string)this.Fields[0].Data; }
33 set { this.Fields[0].Data = value; }
34 }
35
36 public string Name
37 {
38 get { return (string)this.Fields[1].Data; }
39 set { this.Fields[1].Data = value; }
40 }
41
42 public ContainerType Type
43 {
44 get { return (ContainerType)this.Fields[2].Data; }
45 set { this.Fields[2].Data = (int)value; }
46 }
47
48 public string DownloadUrl
49 {
50 get { return (string)this.Fields[3].Data; }
51 set { this.Fields[3].Data = value; }
52 }
53
54 public long Size
55 {
56 get { return (long)this.Fields[4].Data; }
57 set { this.Fields[4].Data = value; }
58 }
59
60 public string Hash
61 {
62 get { return (string)this.Fields[5].Data; }
63 set { this.Fields[5].Data = value; }
64 }
65
66 public int AttachedContainerIndex
67 {
68 get { return (null == this.Fields[6].Data) ? -1 : (int)this.Fields[6].Data; }
69 set { this.Fields[6].Data = value; }
70 }
71
72 public string WorkingPath
73 {
74 get { return (string)this.Fields[7].Data; }
75 set { this.Fields[7].Data = value; }
76 }
77 }
78}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleExePackageRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleExePackageRow.cs
new file mode 100644
index 00000000..3bf06d49
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleExePackageRow.cs
@@ -0,0 +1,103 @@
1// 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.
2
3using WixToolset.Data.Tuples;
4
5namespace WixToolset.Data.Rows
6{
7 /// <summary>
8 /// Specialization of a row for the WixBundleExePackage table.
9 /// </summary>
10 public sealed class WixBundleExePackageRow : Row
11 {
12 /// <summary>
13 /// Creates a WixBundleExePackage row that does not belong to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="tableDef">TableDefinition this row belongs to and should get its column definitions from.</param>
17 public WixBundleExePackageRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
18 base(sourceLineNumbers, tableDef)
19 {
20 }
21
22 /// <summary>
23 /// Creates a WixBundleExePackageRow row that belongs to a table.
24 /// </summary>
25 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
26 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
27 public WixBundleExePackageRow(SourceLineNumber sourceLineNumbers, Table table) :
28 base(sourceLineNumbers, table)
29 {
30 }
31
32 /// <summary>
33 /// Gets or sets the foreign key identifier to the ChainPackage row.
34 /// </summary>
35 public string ChainPackageId
36 {
37 get { return (string)this.Fields[0].Data; }
38 set { this.Fields[0].Data = value; }
39 }
40
41 /// <summary>
42 /// Gets or sets the raw Exe attributes of a patch.
43 /// </summary>
44 public WixBundleExePackageAttributes Attributes
45 {
46 get { return (WixBundleExePackageAttributes)this.Fields[1].Data; }
47 set { this.Fields[1].Data = value; }
48 }
49
50 /// <summary>
51 /// Gets or sets the protcol for the executable package.
52 /// </summary>
53 public string DetectCondition
54 {
55 get { return (string)this.Fields[2].Data; }
56 set { this.Fields[2].Data = value; }
57 }
58
59 /// <summary>
60 /// Gets or sets the install command for the executable package.
61 /// </summary>
62 public string InstallCommand
63 {
64 get { return (string)this.Fields[3].Data; }
65 set { this.Fields[3].Data = value; }
66 }
67
68 /// <summary>
69 /// Gets or sets the repair command for the executable package.
70 /// </summary>
71 public string RepairCommand
72 {
73 get { return (string)this.Fields[4].Data; }
74 set { this.Fields[4].Data = value; }
75 }
76
77 /// <summary>
78 /// Gets or sets the uninstall command for the executable package.
79 /// </summary>
80 public string UninstallCommand
81 {
82 get { return (string)this.Fields[5].Data; }
83 set { this.Fields[5].Data = value; }
84 }
85
86 /// <summary>
87 /// Gets or sets the protcol for the executable package.
88 /// </summary>
89 public string ExeProtocol
90 {
91 get { return (string)this.Fields[6].Data; }
92 set { this.Fields[6].Data = value; }
93 }
94
95 /// <summary>
96 /// Gets whether the executable package is repairable.
97 /// </summary>
98 public bool Repairable
99 {
100 get { return 0 != (this.Attributes & WixBundleExePackageAttributes.Repairable); }
101 }
102 }
103}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiFeatureRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiFeatureRow.cs
new file mode 100644
index 00000000..551eae20
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiFeatureRow.cs
@@ -0,0 +1,93 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the MsiFeature table.
7 /// </summary>
8 public class WixBundleMsiFeatureRow : Row
9 {
10 /// <summary>
11 /// Creates a MsiFeatureRow row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this Media row belongs to and should get its column definitions from.</param>
15 public WixBundleMsiFeatureRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a MsiFeatureRow row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this Media row belongs to and should get its column definitions from.</param>
25 public WixBundleMsiFeatureRow(SourceLineNumber sourceLineNumbers, Table table) :
26 base(sourceLineNumbers, table)
27 {
28 }
29
30 /// <summary>
31 /// Gets or sets the foreign key identifier to the ChainPackage row.
32 /// </summary>
33 public string ChainPackageId
34 {
35 get { return (string)this.Fields[0].Data; }
36 set { this.Fields[0].Data = value; }
37 }
38
39 public string Name
40 {
41 get { return (string)this.Fields[1].Data; }
42 set { this.Fields[1].Data = value; }
43 }
44
45 public long Size
46 {
47 get { return (long)this.Fields[2].Data; }
48 set { this.Fields[2].Data = value; }
49 }
50
51 public string Parent
52 {
53 get { return (string)this.Fields[3].Data; }
54 set { this.Fields[3].Data = value; }
55 }
56
57 public string Title
58 {
59 get { return (string)this.Fields[4].Data; }
60 set { this.Fields[4].Data = value; }
61 }
62
63 public string Description
64 {
65 get { return (string)this.Fields[5].Data; }
66 set { this.Fields[5].Data = value; }
67 }
68
69 public int Display
70 {
71 get { return (int)this.Fields[6].Data; }
72 set { this.Fields[6].Data = value; }
73 }
74
75 public int Level
76 {
77 get { return (int)this.Fields[7].Data; }
78 set { this.Fields[7].Data = value; }
79 }
80
81 public string Directory
82 {
83 get { return (string)this.Fields[8].Data; }
84 set { this.Fields[8].Data = value; }
85 }
86
87 public int Attributes
88 {
89 get { return (int)this.Fields[9].Data; }
90 set { this.Fields[9].Data = value; }
91 }
92 }
93}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiPackageRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiPackageRow.cs
new file mode 100644
index 00000000..70d85e26
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiPackageRow.cs
@@ -0,0 +1,138 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.Globalization;
7 using WixToolset.Data.Tuples;
8
9 /// <summary>
10 /// Specialization of a row for the WixBundleMsiPackage table.
11 /// </summary>
12 public sealed class WixBundleMsiPackageRow : Row
13 {
14 /// <summary>
15 /// Creates a WixBundleMsiPackage row that does not belong to a table.
16 /// </summary>
17 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
18 /// <param name="tableDef">TableDefinition this row belongs to and should get its column definitions from.</param>
19 public WixBundleMsiPackageRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
20 base(sourceLineNumbers, tableDef)
21 {
22 }
23
24 /// <summary>
25 /// Creates a WixBundleMsiPackageRow row that belongs to a table.
26 /// </summary>
27 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
28 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
29 public WixBundleMsiPackageRow(SourceLineNumber sourceLineNumbers, Table table) :
30 base(sourceLineNumbers, table)
31 {
32 }
33
34 /// <summary>
35 /// Gets or sets the foreign key identifier to the ChainPackage row.
36 /// </summary>
37 public string ChainPackageId
38 {
39 get { return (string)this.Fields[0].Data; }
40 set { this.Fields[0].Data = value; }
41 }
42
43 /// <summary>
44 /// Gets or sets the raw MSI attributes of a package.
45 /// </summary>
46 public WixBundleMsiPackageAttributes Attributes
47 {
48 get { return (WixBundleMsiPackageAttributes)this.Fields[1].Data; }
49 set { this.Fields[1].Data = value; }
50 }
51
52 /// <summary>
53 /// Gets or sets the MSI package's product code.
54 /// </summary>
55 public string ProductCode
56 {
57 get { return (string)this.Fields[2].Data; }
58 set { this.Fields[2].Data = value; }
59 }
60
61 /// <summary>
62 /// Gets or sets the MSI package's upgrade code.
63 /// </summary>
64 public string UpgradeCode
65 {
66 get { return (string)this.Fields[3].Data; }
67 set { this.Fields[3].Data = value; }
68 }
69
70 /// <summary>
71 /// Gets or sets the product version of the MSI package.
72 /// </summary>
73 public string ProductVersion
74 {
75 get { return (string)this.Fields[4].Data; }
76 set { this.Fields[4].Data = value; }
77 }
78
79 /// <summary>
80 /// Gets or sets the language of the MSI package.
81 /// </summary>
82 public int ProductLanguage
83 {
84 get { return Convert.ToInt32(this.Fields[5].Data, CultureInfo.InvariantCulture); }
85 set { this.Fields[5].Data = value; }
86 }
87
88 /// <summary>
89 /// Gets or sets the product name of the MSI package.
90 /// </summary>
91 public string ProductName
92 {
93 get { return (string)this.Fields[6].Data; }
94 set { this.Fields[6].Data = value; }
95 }
96
97 /// <summary>
98 /// Gets or sets the MSI package's manufacturer.
99 /// </summary>
100 public string Manufacturer
101 {
102 get { return (string)this.Fields[7].Data; }
103 set { this.Fields[7].Data = value; }
104 }
105
106 /// <summary>
107 /// Gets the display internal UI of a package.
108 /// </summary>
109 public bool DisplayInternalUI
110 {
111 get { return 0 != (this.Attributes & WixBundleMsiPackageAttributes.DisplayInternalUI); }
112 }
113
114 /// <summary>
115 /// Gets the display internal UI of a package.
116 /// </summary>
117 public bool EnableFeatureSelection
118 {
119 get { return 0 != (this.Attributes & WixBundleMsiPackageAttributes.EnableFeatureSelection); }
120 }
121
122 /// <summary>
123 /// Gets the display internal UI of a package.
124 /// </summary>
125 public bool ForcePerMachine
126 {
127 get { return 0 != (this.Attributes & WixBundleMsiPackageAttributes.ForcePerMachine); }
128 }
129
130 /// <summary>
131 /// Gets the suppress loose file payload generation of a package.
132 /// </summary>
133 public bool SuppressLooseFilePayloadGeneration
134 {
135 get { return 0 != (this.Attributes & WixBundleMsiPackageAttributes.SuppressLooseFilePayloadGeneration); }
136 }
137 }
138}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiPropertyRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiPropertyRow.cs
new file mode 100644
index 00000000..524f7929
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsiPropertyRow.cs
@@ -0,0 +1,58 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the WixBundleMsiProperty table.
7 /// </summary>
8 public sealed class WixBundleMsiPropertyRow : Row
9 {
10 /// <summary>
11 /// Creates an WixBundleMsiProperty row that belongs to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="table">Table this WixBundleMsiProperty row belongs to and should get its column definitions from.</param>
15 public WixBundleMsiPropertyRow(SourceLineNumber sourceLineNumbers, Table table) :
16 base(sourceLineNumbers, table)
17 {
18 }
19
20 /// <summary>
21 /// Gets or sets the foreign key identifier to the ChainPackage row.
22 /// </summary>
23 public string ChainPackageId
24 {
25 get { return (string)this.Fields[0].Data; }
26 set { this.Fields[0].Data = value; }
27 }
28
29 /// <summary>
30 /// Gets and sets the property identity.
31 /// </summary>
32 public string Name
33 {
34 get { return (string)this.Fields[1].Data; }
35 set { this.Fields[1].Data = value; }
36 }
37
38 /// <summary>
39 /// Gets and sets the value for the row.
40 /// </summary>
41 /// <value>MsiProperty value for the row.</value>
42 public string Value
43 {
44 get { return (string)this.Fields[2].Data; }
45 set { this.Fields[2].Data = value; }
46 }
47
48 /// <summary>
49 /// Gets and sets the condition for the row.
50 /// </summary>
51 /// <value>MsiProperty condition for the row.</value>
52 public string Condition
53 {
54 get { return (string)this.Fields[3].Data; }
55 set { this.Fields[3].Data = value; }
56 }
57 }
58}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMspPackageRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMspPackageRow.cs
new file mode 100644
index 00000000..053fc915
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMspPackageRow.cs
@@ -0,0 +1,101 @@
1// 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.
2
3using WixToolset.Data.Tuples;
4
5namespace WixToolset.Data.Rows
6{
7 /// <summary>
8 /// Specialization of a row for the ChainMspPackage table.
9 /// </summary>
10 public sealed class WixBundleMspPackageRow : Row
11 {
12 /// <summary>
13 /// Creates a ChainMspPackage row that does not belong to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="tableDef">TableDefinition this row belongs to and should get its column definitions from.</param>
17 public WixBundleMspPackageRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
18 base(sourceLineNumbers, tableDef)
19 {
20 }
21
22 /// <summary>
23 /// Creates a WixBundleMspPackage row that belongs to a table.
24 /// </summary>
25 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
26 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
27 public WixBundleMspPackageRow(SourceLineNumber sourceLineNumbers, Table table) :
28 base(sourceLineNumbers, table)
29 {
30 }
31
32 /// <summary>
33 /// Gets or sets the foreign key identifier to the ChainPackage row.
34 /// </summary>
35 public string ChainPackageId
36 {
37 get { return (string)this.Fields[0].Data; }
38 set { this.Fields[0].Data = value; }
39 }
40
41 /// <summary>
42 /// Gets or sets the raw MSP attributes of a patch.
43 /// </summary>
44 public WixBundleMspPackageAttributes Attributes
45 {
46 get { return (WixBundleMspPackageAttributes)this.Fields[1].Data; }
47 set { this.Fields[1].Data = value; }
48 }
49
50 /// <summary>
51 /// Gets or sets the patch code.
52 /// </summary>
53 public string PatchCode
54 {
55 get { return (string)this.Fields[2].Data; }
56 set { this.Fields[2].Data = value; }
57 }
58
59 /// <summary>
60 /// Gets or sets the patch's manufacturer.
61 /// </summary>
62 public string Manufacturer
63 {
64 get { return (string)this.Fields[3].Data; }
65 set { this.Fields[3].Data = value; }
66 }
67
68 /// <summary>
69 /// Gets or sets the patch's xml.
70 /// </summary>
71 public string PatchXml
72 {
73 get { return (string)this.Fields[4].Data; }
74 set { this.Fields[4].Data = value; }
75 }
76
77 /// <summary>
78 /// Gets the display internal UI of a patch.
79 /// </summary>
80 public bool DisplayInternalUI
81 {
82 get { return 0 != (this.Attributes & WixBundleMspPackageAttributes.DisplayInternalUI); }
83 }
84
85 /// <summary>
86 /// Gets whether to slipstream the patch.
87 /// </summary>
88 public bool Slipstream
89 {
90 get { return 0 != (this.Attributes & WixBundleMspPackageAttributes.Slipstream); }
91 }
92
93 /// <summary>
94 /// Gets whether the patch targets an unspecified number of packages.
95 /// </summary>
96 public bool TargetUnspecified
97 {
98 get { return 0 != (this.Attributes & WixBundleMspPackageAttributes.TargetUnspecified); }
99 }
100 }
101}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsuPackageRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsuPackageRow.cs
new file mode 100644
index 00000000..0df635c2
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleMsuPackageRow.cs
@@ -0,0 +1,57 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the WixBundleMsuPackage table.
7 /// </summary>
8 public sealed class WixBundleMsuPackageRow : Row
9 {
10 /// <summary>
11 /// Creates a WixBundleMsuPackage row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this row belongs to and should get its column definitions from.</param>
15 public WixBundleMsuPackageRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a WixBundleMsuPackage row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
25 public WixBundleMsuPackageRow(SourceLineNumber sourceLineNumbers, Table table) :
26 base(sourceLineNumbers, table)
27 {
28 }
29
30 /// <summary>
31 /// Gets or sets the foreign key identifier to the ChainPackage row.
32 /// </summary>
33 public string ChainPackageId
34 {
35 get { return (string)this.Fields[0].Data; }
36 set { this.Fields[0].Data = value; }
37 }
38
39 /// <summary>
40 /// Gets or sets the detection condition the package.
41 /// </summary>
42 public string DetectCondition
43 {
44 get { return (string)this.Fields[1].Data; }
45 set { this.Fields[1].Data = value; }
46 }
47
48 /// <summary>
49 /// Gets or sets the KB of the package.
50 /// </summary>
51 public string MsuKB
52 {
53 get { return (string)this.Fields[2].Data; }
54 set { this.Fields[2].Data = value; }
55 }
56 }
57}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageCommandLineRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageCommandLineRow.cs
new file mode 100644
index 00000000..eba647d5
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageCommandLineRow.cs
@@ -0,0 +1,82 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6
7 /// <summary>
8 /// Specialization of a row for the WixBundlePackageCommandLine table.
9 /// </summary>
10 public class WixBundlePackageCommandLineRow : Row
11 {
12 /// <summary>
13 /// Creates a WixBundlePackageCommandLineRow row that does not belong to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="tableDef">TableDefinition this WixBundlePackageCommandLineRow row belongs to and should get its column definitions from.</param>
17 public WixBundlePackageCommandLineRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
18 base(sourceLineNumbers, tableDef)
19 {
20 }
21
22 /// <summary>
23 /// Creates an WixBundlePackageCommandLineRow row that belongs to a table.
24 /// </summary>
25 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
26 /// <param name="table">Table this WixBundlePackageCommandLineRow row belongs to and should get its column definitions from.</param>
27 public WixBundlePackageCommandLineRow(SourceLineNumber sourceLineNumbers, Table table)
28 : base(sourceLineNumbers, table)
29 {
30 }
31
32 /// <summary>
33 /// Gets or sets the package identifier.
34 /// </summary>
35 /// <value>The package identifier.</value>
36 public string ChainPackageId
37 {
38 get { return (string)this.Fields[0].Data; }
39 set { this.Fields[0].Data = value; }
40 }
41
42 /// <summary>
43 /// Gets or sets the command-line argument for installation.
44 /// </summary>
45 /// <value>The command-line argument.</value>
46 public string InstallArgument
47 {
48 get { return (string)this.Fields[1].Data; }
49 set { this.Fields[1].Data = value; }
50 }
51
52 /// <summary>
53 /// Gets or sets the command-line argument for uninstallation.
54 /// </summary>
55 /// <value>The command-line argument.</value>
56 public string UninstallArgument
57 {
58 get { return (string)this.Fields[2].Data; }
59 set { this.Fields[2].Data = value; }
60 }
61
62 /// <summary>
63 /// Gets or sets the command-line argument for repair.
64 /// </summary>
65 /// <value>The command-line argument.</value>
66 public string RepairArgument
67 {
68 get { return (string)this.Fields[3].Data; }
69 set { this.Fields[3].Data = value; }
70 }
71
72 /// <summary>
73 /// Gets or sets the condition.
74 /// </summary>
75 /// <value>The condition.</value>
76 public string Condition
77 {
78 get { return (string)this.Fields[4].Data; }
79 set { this.Fields[4].Data = value; }
80 }
81 }
82}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageExitCodeRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageExitCodeRow.cs
new file mode 100644
index 00000000..2beed8da
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageExitCodeRow.cs
@@ -0,0 +1,53 @@
1// 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.
2
3using WixToolset.Data.Tuples;
4
5namespace WixToolset.Data.Rows
6{
7 /// <summary>
8 /// Specialization of a row for the ExitCode table.
9 /// </summary>
10 public class WixBundlePackageExitCodeRow : Row
11 {
12 /// <summary>
13 /// Creates a ExitCodeRow row that does not belong to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="tableDef">TableDefinition this Media row belongs to and should get its column definitions from.</param>
17 public WixBundlePackageExitCodeRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
18 base(sourceLineNumbers, tableDef)
19 {
20 }
21
22 /// <summary>
23 /// Creates a ExitCodeRow row that belongs to a table.
24 /// </summary>
25 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
26 /// <param name="table">Table this Media row belongs to and should get its column definitions from.</param>
27 public WixBundlePackageExitCodeRow(SourceLineNumber sourceLineNumbers, Table table) :
28 base(sourceLineNumbers, table)
29 {
30 }
31
32 /// <summary>
33 /// Gets or sets the foreign key identifier to the ChainPackage row.
34 /// </summary>
35 public string ChainPackageId
36 {
37 get { return (string)this.Fields[0].Data; }
38 set { this.Fields[0].Data = value; }
39 }
40
41 public int? Code
42 {
43 get { return (null == this.Fields[1].Data) ? (int?)null : (int?)this.Fields[1].Data; }
44 set { this.Fields[1].Data = value; }
45 }
46
47 public ExitCodeBehaviorType Behavior
48 {
49 get { return (ExitCodeBehaviorType)this.Fields[2].Data; }
50 set { this.Fields[2].Data = (int)value; }
51 }
52 }
53}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageRow.cs
new file mode 100644
index 00000000..973c43b9
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePackageRow.cs
@@ -0,0 +1,228 @@
1// 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.
2
3using WixToolset.Data.Tuples;
4
5namespace WixToolset.Data.Rows
6{
7 /// <summary>
8 /// Specialization of a row for the WixBundlePackage table.
9 /// </summary>
10 public sealed class WixBundlePackageRow : Row
11 {
12 /// <summary>
13 /// Creates a WixBundlePackage row that does not belong to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="tableDef">TableDefinition this row belongs to and should get its column definitions from.</param>
17 public WixBundlePackageRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
18 base(sourceLineNumbers, tableDef)
19 {
20 }
21
22 /// <summary>
23 /// Creates a WixBundlePackage row that belongs to a table.
24 /// </summary>
25 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
26 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
27 public WixBundlePackageRow(SourceLineNumber sourceLineNumbers, Table table) :
28 base(sourceLineNumbers, table)
29 {
30 }
31
32 /// <summary>
33 /// Gets or sets the foreign key to the WixChainItem.
34 /// </summary>
35 public string WixChainItemId
36 {
37 get { return (string)this.Fields[0].Data; }
38 set { this.Fields[0].Data = value; }
39 }
40
41 /// <summary>
42 /// Gets or sets the item type.
43 /// </summary>
44 public WixBundlePackageType Type
45 {
46 get { return (WixBundlePackageType)this.Fields[1].Data; }
47 set { this.Fields[1].Data = (int)value; }
48 }
49
50 /// <summary>
51 /// Gets or sets the indentifier of the package's payload.
52 /// </summary>
53 public string PackagePayload
54 {
55 get { return (string)this.Fields[2].Data; }
56 set { this.Fields[2].Data = value; }
57 }
58
59 /// <summary>
60 /// Gets or sets the raw attributes of a package.
61 /// </summary>
62 public WixBundlePackageAttributes Attributes
63 {
64 get { return (WixBundlePackageAttributes)this.Fields[3].Data; }
65 set { this.Fields[3].Data = value; }
66 }
67
68 /// <summary>
69 /// Gets or sets the install condition of the package.
70 /// </summary>
71 public string InstallCondition
72 {
73 get { return (string)this.Fields[4].Data; }
74 set { this.Fields[4].Data = value; }
75 }
76
77 /// <summary>
78 /// Gets or sets the language of the package.
79 /// </summary>
80 public YesNoAlwaysType Cache
81 {
82 get { return (null == this.Fields[5].Data) ? YesNoAlwaysType.NotSet : (YesNoAlwaysType)this.Fields[5].Data; }
83 set { this.Fields[5].Data = (int)value; }
84 }
85
86 /// <summary>
87 /// Gets or sets the indentifier of the package's cache.
88 /// </summary>
89 public string CacheId
90 {
91 get { return (string)this.Fields[6].Data; }
92 set { this.Fields[6].Data = value; }
93 }
94
95 /// <summary>
96 /// Gets or sets whether the package is vital.
97 /// </summary>
98 public YesNoType Vital
99 {
100 get { return (null == this.Fields[7].Data) ? YesNoType.NotSet : (YesNoType)this.Fields[7].Data; }
101 set { this.Fields[7].Data = (int)value; }
102 }
103
104 /// <summary>
105 /// Gets or sets whether the package is per-machine.
106 /// </summary>
107 public YesNoDefaultType PerMachine
108 {
109 get { return (null == this.Fields[8].Data) ? YesNoDefaultType.NotSet : (YesNoDefaultType)this.Fields[8].Data; }
110 set { this.Fields[8].Data = (int)value; }
111 }
112
113 /// <summary>
114 /// Gets or sets the variable that points to the log for the package.
115 /// </summary>
116 public string LogPathVariable
117 {
118 get { return (string)this.Fields[9].Data; }
119 set { this.Fields[9].Data = value; }
120 }
121
122 /// <summary>
123 /// Gets or sets the variable that points to the rollback log for the package.
124 /// </summary>
125 public string RollbackLogPathVariable
126 {
127 get { return (string)this.Fields[10].Data; }
128 set { this.Fields[10].Data = value; }
129 }
130
131 /// <summary>
132 /// Gets or sets the size of the package.
133 /// </summary>
134 public long Size
135 {
136 get { return (long)this.Fields[11].Data; }
137 set { this.Fields[11].Data = value; }
138 }
139
140 /// <summary>
141 /// Gets or sets the install size of the package.
142 /// </summary>
143 public long? InstallSize
144 {
145 get { return (long?)this.Fields[12].Data; }
146 set { this.Fields[12].Data = value; }
147 }
148
149 /// <summary>
150 /// Gets or sets the version of the package.
151 /// </summary>
152 public string Version
153 {
154 get { return (string)this.Fields[13].Data; }
155 set { this.Fields[13].Data = value; }
156 }
157
158 /// <summary>
159 /// Gets or sets the language of the package.
160 /// </summary>
161 public int Language
162 {
163 get { return (int)this.Fields[14].Data; }
164 set { this.Fields[14].Data = value; }
165 }
166
167 /// <summary>
168 /// Gets or sets the display name of the package.
169 /// </summary>
170 public string DisplayName
171 {
172 get { return (string)this.Fields[15].Data; }
173 set { this.Fields[15].Data = value; }
174 }
175
176 /// <summary>
177 /// Gets or sets the description of the package.
178 /// </summary>
179 public string Description
180 {
181 get { return (string)this.Fields[16].Data; }
182 set { this.Fields[16].Data = value; }
183 }
184
185 /// <summary>
186 /// Gets or sets the rollback boundary identifier for the package.
187 /// </summary>
188 public string RollbackBoundary
189 {
190 get { return (string)this.Fields[17].Data; }
191 set { this.Fields[17].Data = value; }
192 }
193
194 /// <summary>
195 /// Gets or sets the backward rollback boundary identifier for the package.
196 /// </summary>
197 public string RollbackBoundaryBackward
198 {
199 get { return (string)this.Fields[18].Data; }
200 set { this.Fields[18].Data = value; }
201 }
202
203 /// <summary>
204 /// Gets or sets whether the package is x64.
205 /// </summary>
206 public YesNoType x64
207 {
208 get { return (null == this.Fields[19].Data) ? YesNoType.NotSet : (YesNoType)this.Fields[19].Data; }
209 set { this.Fields[19].Data = (int)value; }
210 }
211
212 /// <summary>
213 /// Gets whether the package is permanent.
214 /// </summary>
215 public bool Permanent
216 {
217 get { return 0 != (this.Attributes & WixBundlePackageAttributes.Permanent); }
218 }
219
220 /// <summary>
221 /// Gets whether the package is visible.
222 /// </summary>
223 public bool Visible
224 {
225 get { return 0 != (this.Attributes & WixBundlePackageAttributes.Visible); }
226 }
227 }
228}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePatchTargetCodeRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePatchTargetCodeRow.cs
new file mode 100644
index 00000000..e25f4a55
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePatchTargetCodeRow.cs
@@ -0,0 +1,81 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Text;
8
9 /// <summary>
10 /// Attributes for the PatchTargetCode table.
11 /// </summary>
12 [Flags]
13 public enum WixBundlePatchTargetCodeAttributes : int
14 {
15 None = 0,
16
17 /// <summary>
18 /// The transform targets a specific ProductCode.
19 /// </summary>
20 TargetsProductCode = 1,
21
22 /// <summary>
23 /// The transform targets a specific UpgradeCode.
24 /// </summary>
25 TargetsUpgradeCode = 2,
26 }
27
28 /// <summary>
29 /// Specialization of a row for the PatchTargetCode table.
30 /// </summary>
31 public class WixBundlePatchTargetCodeRow : Row
32 {
33 /// <summary>
34 /// Creates a PatchTargetCodeRow row that does not belong to a table.
35 /// </summary>
36 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
37 /// <param name="tableDef">TableDefinition this PatchTargetCode row belongs to and should get its column definitions from.</param>
38 public WixBundlePatchTargetCodeRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
39 base(sourceLineNumbers, tableDef)
40 {
41 }
42
43 /// <summary>
44 /// Creates a PatchTargetCodeRow row that belongs to a table.
45 /// </summary>
46 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
47 /// <param name="table">Table this PatchTargetCode row belongs to and should get its column definitions from.</param>
48 public WixBundlePatchTargetCodeRow(SourceLineNumber sourceLineNumbers, Table table) :
49 base(sourceLineNumbers, table)
50 {
51 }
52
53 public string MspPackageId
54 {
55 get { return (string)this.Fields[0].Data; }
56 set { this.Fields[0].Data = value; }
57 }
58
59 public string TargetCode
60 {
61 get { return (string)this.Fields[1].Data; }
62 set { this.Fields[1].Data = value; }
63 }
64
65 public WixBundlePatchTargetCodeAttributes Attributes
66 {
67 get { return (WixBundlePatchTargetCodeAttributes)this.Fields[2].Data; }
68 set { this.Fields[2].Data = (int)value; }
69 }
70
71 public bool TargetsProductCode
72 {
73 get { return 0 != (WixBundlePatchTargetCodeAttributes.TargetsProductCode & this.Attributes); }
74 }
75
76 public bool TargetsUpgradeCode
77 {
78 get { return 0 != (WixBundlePatchTargetCodeAttributes.TargetsUpgradeCode & this.Attributes); }
79 }
80 }
81}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePayloadRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePayloadRow.cs
new file mode 100644
index 00000000..8aac8aa0
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundlePayloadRow.cs
@@ -0,0 +1,185 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.IO;
7
8 /// <summary>
9 /// Specialization of a row for the PayloadInfo table.
10 /// </summary>
11 public class WixBundlePayloadRow : Row
12 {
13 /// <summary>
14 /// Creates a PayloadRow row that does not belong to a table.
15 /// </summary>
16 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
17 /// <param name="tableDef">TableDefinition this Media row belongs to and should get its column definitions from.</param>
18 public WixBundlePayloadRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
19 base(sourceLineNumbers, tableDef)
20 {
21 }
22
23 /// <summary>
24 /// Creates a PayloadRow row that belongs to a table.
25 /// </summary>
26 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
27 /// <param name="table">Table this Media row belongs to and should get its column definitions from.</param>
28 public WixBundlePayloadRow(SourceLineNumber sourceLineNumbers, Table table) :
29 base(sourceLineNumbers, table)
30 {
31 }
32
33 public string Id
34 {
35 get { return (string)this.Fields[0].Data; }
36 set { this.Fields[0].Data = value; }
37 }
38
39 public string Name
40 {
41 get { return (string)this.Fields[1].Data; }
42 set { this.Fields[1].Data = value; }
43 }
44
45 public string SourceFile
46 {
47 get { return (string)this.Fields[2].Data; }
48 set { this.Fields[2].Data = value; }
49 }
50
51 public string DownloadUrl
52 {
53 get { return (string)this.Fields[3].Data; }
54 set { this.Fields[3].Data = value; }
55 }
56
57 public YesNoDefaultType Compressed
58 {
59 get { return (YesNoDefaultType)this.Fields[4].Data; }
60 set { this.Fields[4].Data = (int)value; }
61 }
62
63 public string UnresolvedSourceFile
64 {
65 get { return (string)this.Fields[5].Data; }
66 set { this.Fields[5].Data = value; }
67 }
68
69 public string DisplayName
70 {
71 get { return (string)this.Fields[6].Data; }
72 set { this.Fields[6].Data = value; }
73 }
74
75 public string Description
76 {
77 get { return (string)this.Fields[7].Data; }
78 set { this.Fields[7].Data = value; }
79 }
80
81 public bool EnableSignatureValidation
82 {
83 get { return (null != this.Fields[8].Data) && (1 == (int)this.Fields[8].Data); }
84 set { this.Fields[8].Data = value ? 1 : 0; }
85 }
86
87 public int FileSize
88 {
89 get { return (int)this.Fields[9].Data; }
90 set { this.Fields[9].Data = value; }
91 }
92
93 public string Version
94 {
95 get { return (string)this.Fields[10].Data; }
96 set { this.Fields[10].Data = value; }
97 }
98
99 public string Hash
100 {
101 get { return (string)this.Fields[11].Data; }
102 set { this.Fields[11].Data = value; }
103 }
104
105 public string PublicKey
106 {
107 get { return (string)this.Fields[12].Data; }
108 set { this.Fields[12].Data = value; }
109 }
110
111 public string Thumbprint
112 {
113 get { return (string)this.Fields[13].Data; }
114 set { this.Fields[13].Data = value; }
115 }
116
117 public string Catalog
118 {
119 get { return (string)this.Fields[14].Data; }
120 set { this.Fields[14].Data = value; }
121 }
122
123 public string Container
124 {
125 get { return (string)this.Fields[15].Data; }
126 set { this.Fields[15].Data = value; }
127 }
128
129 public string Package
130 {
131 get { return (string)this.Fields[16].Data; }
132 set { this.Fields[16].Data = value; }
133 }
134
135 public bool ContentFile
136 {
137 get { return (null != this.Fields[17].Data) && (1 == (int)this.Fields[17].Data); }
138 set { this.Fields[17].Data = value ? 1 : 0; }
139 }
140
141 public string EmbeddedId
142 {
143 get { return (string)this.Fields[18].Data; }
144 set { this.Fields[18].Data = value; }
145 }
146
147 public bool LayoutOnly
148 {
149 get { return (null != this.Fields[19].Data) && (1 == (int)this.Fields[19].Data); }
150 set { this.Fields[19].Data = value ? 1 : 0; }
151 }
152
153 public PackagingType Packaging
154 {
155 get
156 {
157 object data = this.Fields[20].Data;
158 return (null == data) ? PackagingType.Unknown : (PackagingType)data;
159 }
160
161 set
162 {
163 if (PackagingType.Unknown == value)
164 {
165 this.Fields[20].Data = null;
166 }
167 else
168 {
169 this.Fields[20].Data = (int)value;
170 }
171 }
172 }
173
174 public string ParentPackagePayload
175 {
176 get { return (string)this.Fields[21].Data; }
177 set { this.Fields[21].Data = value; }
178 }
179
180 public string FullFileName
181 {
182 get { return String.IsNullOrEmpty(this.SourceFile) ? String.Empty : Path.GetFullPath(this.SourceFile); }
183 }
184 }
185}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRelatedPackageRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRelatedPackageRow.cs
new file mode 100644
index 00000000..ea9ff99e
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRelatedPackageRow.cs
@@ -0,0 +1,87 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the RelatedPackage table.
7 /// </summary>
8 public class WixBundleRelatedPackageRow : Row
9 {
10 /// <summary>
11 /// Creates a RelatedPackageRow row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this Media row belongs to and should get its column definitions from.</param>
15 public WixBundleRelatedPackageRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a RelatedPackageRow row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this Media row belongs to and should get its column definitions from.</param>
25 public WixBundleRelatedPackageRow(SourceLineNumber sourceLineNumbers, Table table) :
26 base(sourceLineNumbers, table)
27 {
28 }
29
30 /// <summary>
31 /// Gets or sets the foreign key identifier to the ChainPackage row.
32 /// </summary>
33 public string ChainPackageId
34 {
35 get { return (string)this.Fields[0].Data; }
36 set { this.Fields[0].Data = value; }
37 }
38
39 public string Id
40 {
41 get { return (string)this.Fields[1].Data; }
42 set { this.Fields[1].Data = value; }
43 }
44
45 public string MinVersion
46 {
47 get { return (string)this.Fields[2].Data; }
48 set { this.Fields[2].Data = value; }
49 }
50
51 public string MaxVersion
52 {
53 get { return (string)this.Fields[3].Data; }
54 set { this.Fields[3].Data = value; }
55 }
56
57 public string Languages
58 {
59 get { return (string)this.Fields[4].Data; }
60 set { this.Fields[4].Data = value; }
61 }
62
63 public bool MinInclusive
64 {
65 get { return 1 == (int)this.Fields[5].Data; }
66 set { this.Fields[5].Data = value ? 1 : 0; }
67 }
68
69 public bool MaxInclusive
70 {
71 get { return 1 == (int)this.Fields[6].Data; }
72 set { this.Fields[6].Data = value ? 1 : 0; }
73 }
74
75 public bool LangInclusive
76 {
77 get { return 1 == (int)this.Fields[7].Data; }
78 set { this.Fields[7].Data = value ? 1 : 0; }
79 }
80
81 public bool OnlyDetect
82 {
83 get { return 1 == (int)this.Fields[8].Data; }
84 set { this.Fields[8].Data = value ? 1 : 0; }
85 }
86 }
87}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRollbackBoundaryRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRollbackBoundaryRow.cs
new file mode 100644
index 00000000..d0a994c0
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRollbackBoundaryRow.cs
@@ -0,0 +1,59 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the WixBundleRollbackBoundary table.
7 /// </summary>
8 public sealed class WixBundleRollbackBoundaryRow : Row
9 {
10 /// <summary>
11 /// Creates a WixBundleRollbackBoundary row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this row belongs to and should get its column definitions from.</param>
15 public WixBundleRollbackBoundaryRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a RollbackBoundaryRow row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
25 public WixBundleRollbackBoundaryRow(SourceLineNumber sourceLineNumbers, Table table) :
26 base(sourceLineNumbers, table)
27 {
28 }
29
30 /// <summary>
31 /// Gets or sets the foreign key identifier to the ChainPackage row.
32 /// </summary>
33 public string ChainPackageId
34 {
35 get { return (string)this.Fields[0].Data; }
36 set { this.Fields[0].Data = value; }
37 }
38
39 /// <summary>
40 /// Gets or sets whether the package is vital.
41 /// </summary>
42 /// <value>Vitality of the package.</value>
43 public YesNoType Vital
44 {
45 get { return (null == this.Fields[1].Data) ? YesNoType.NotSet : (YesNoType)this.Fields[1].Data; }
46 set { this.Fields[1].Data = (int)value; }
47 }
48
49 /// <summary>
50 /// Gets or sets whether the rollback-boundary should be installed as an MSI transaction.
51 /// </summary>
52 /// <value>Vitality of the package.</value>
53 public YesNoType Transaction
54 {
55 get { return (null == this.Fields[2].Data) ? YesNoType.NotSet : (YesNoType)this.Fields[2].Data; }
56 set { this.Fields[2].Data = (int)value; }
57 }
58 }
59}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRow.cs
new file mode 100644
index 00000000..4c96d6cc
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleRow.cs
@@ -0,0 +1,228 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6
7 /// <summary>
8 /// Bundle info for binding Bundles.
9 /// </summary>
10 public class WixBundleRow : Row
11 {
12 /// <summary>
13 /// Creates a WixBundleRow row that does not belong to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="tableDef">TableDefinition this WixBundleRow row belongs to and should get its column definitions from.</param>
17 public WixBundleRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
18 base(sourceLineNumbers, tableDef)
19 {
20 }
21
22 /// <summary>
23 /// Creates a WixBundleRow row that belongs to a table.
24 /// </summary>
25 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
26 /// <param name="table">Table this WixBundleRow row belongs to and should get its column definitions from.</param>
27 public WixBundleRow(SourceLineNumber sourceLineNumbers, Table table) :
28 base(sourceLineNumbers, table)
29 {
30 }
31
32 public string Version
33 {
34 get { return (string)this.Fields[0].Data; }
35 set { this.Fields[0].Data = value; }
36 }
37
38 public string Copyright
39 {
40 get { return (string)this.Fields[1].Data; }
41 set { this.Fields[1].Data = value; }
42 }
43
44 public string Name
45 {
46 get { return (string)this.Fields[2].Data; }
47 set { this.Fields[2].Data = value; }
48 }
49
50 public string AboutUrl
51 {
52 get { return (string)this.Fields[3].Data; }
53 set { this.Fields[3].Data = value; }
54 }
55
56 public int DisableModify
57 {
58 get { return (null == this.Fields[4].Data) ? 0 : (int)this.Fields[4].Data; }
59 set { this.Fields[4].Data = value; }
60 }
61
62 public bool DisableRemove
63 {
64 get { return (null != this.Fields[5].Data && 0 != (int)this.Fields[5].Data); }
65 set { this.Fields[5].Data = value ? 1 : 0; }
66 }
67
68 // There is no 6. It used to be DisableRepair.
69
70 public string HelpTelephone
71 {
72 get { return (string)this.Fields[7].Data; }
73 set { this.Fields[7].Data = value; }
74 }
75
76 public string HelpLink
77 {
78 get { return (string)this.Fields[8].Data; }
79 set { this.Fields[8].Data = value; }
80 }
81
82 public string Publisher
83 {
84 get { return (string)this.Fields[9].Data; }
85 set { this.Fields[9].Data = value; }
86 }
87
88 public string UpdateUrl
89 {
90 get { return (string)this.Fields[10].Data; }
91 set { this.Fields[10].Data = value; }
92 }
93
94 public YesNoDefaultType Compressed
95 {
96 get { return (null == this.Fields[11].Data) ? YesNoDefaultType.Default : (0 == (int)this.Fields[11].Data) ? YesNoDefaultType.No : YesNoDefaultType.Yes; }
97 set { this.Fields[11].Data = (int)value; }
98 }
99
100 public PackagingType DefaultPackagingType
101 {
102 get { return (YesNoDefaultType.No == this.Compressed) ? PackagingType.External : PackagingType.Embedded; }
103 }
104
105 public string LogPathPrefixExtension
106 {
107 get { return (string)this.Fields[12].Data ?? String.Empty; }
108 set { this.Fields[12].Data = value; }
109 }
110
111 public string LogPathVariable
112 {
113 get
114 {
115 string[] logVariableAndPrefixExtension = this.LogPathPrefixExtension.Split(':');
116 return logVariableAndPrefixExtension[0];
117 }
118 }
119
120 public string LogPrefix
121 {
122 get
123 {
124 string[] logVariableAndPrefixExtension = this.LogPathPrefixExtension.Split(':');
125 if (2 > logVariableAndPrefixExtension.Length)
126 {
127 return String.Empty;
128 }
129 string logPrefixAndExtension = logVariableAndPrefixExtension[1];
130 int extensionIndex = logPrefixAndExtension.LastIndexOf('.');
131 return logPrefixAndExtension.Substring(0, extensionIndex);
132 }
133 }
134
135 public string LogExtension
136 {
137 get
138 {
139 string[] logVariableAndPrefixExtension = this.LogPathPrefixExtension.Split(':');
140 if (2 > logVariableAndPrefixExtension.Length)
141 {
142 return String.Empty;
143 }
144 string logPrefixAndExtension = logVariableAndPrefixExtension[1];
145 int extensionIndex = logPrefixAndExtension.LastIndexOf('.');
146 return logPrefixAndExtension.Substring(extensionIndex + 1);
147 }
148 }
149
150 public string IconPath
151 {
152 get { return (string)this.Fields[13].Data; }
153 set { this.Fields[13].Data = value; }
154 }
155
156 public string SplashScreenBitmapPath
157 {
158 get { return (string)this.Fields[14].Data; }
159 set { this.Fields[14].Data = value; }
160 }
161
162 public string Condition
163 {
164 get { return (string)this.Fields[15].Data; }
165 set { this.Fields[15].Data = value; }
166 }
167
168 public string Tag
169 {
170 get { return (string)this.Fields[16].Data; }
171 set { this.Fields[16].Data = value; }
172 }
173
174 public Platform Platform
175 {
176 get { return (Platform)Enum.Parse(typeof(Platform), (string)this.Fields[17].Data); }
177 set { this.Fields[17].Data = value.ToString(); }
178 }
179
180 public string ParentName
181 {
182 get { return (string)this.Fields[18].Data; }
183 set { this.Fields[18].Data = value; }
184 }
185
186 public string UpgradeCode
187 {
188 get { return (string)this.Fields[19].Data; }
189 set { this.Fields[19].Data = value; }
190 }
191
192 public Guid BundleId
193 {
194 get
195 {
196 if (null == this.Fields[20].Data)
197 {
198 this.Fields[20].Data = Guid.NewGuid().ToString("B");
199 }
200
201 return new Guid((string)this.Fields[20].Data);
202 }
203
204 set { this.Fields[20].Data = value.ToString(); }
205 }
206
207 public string ProviderKey
208 {
209 get
210 {
211 if (null == this.Fields[21].Data)
212 {
213 this.Fields[21].Data = this.BundleId.ToString("B");
214 }
215
216 return (string)this.Fields[21].Data;
217 }
218
219 set { this.Fields[21].Data = value; }
220 }
221
222 public bool PerMachine
223 {
224 get { return (null != this.Fields[22].Data && 0 != (int)this.Fields[22].Data); }
225 set { this.Fields[22].Data = value ? 1 : 0; }
226 }
227 }
228}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleSlipstreamMspRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleSlipstreamMspRow.cs
new file mode 100644
index 00000000..d11b23ef
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleSlipstreamMspRow.cs
@@ -0,0 +1,48 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the SlipstreamMsp table.
7 /// </summary>
8 public class WixBundleSlipstreamMspRow : Row
9 {
10 /// <summary>
11 /// Creates a SlipstreamMspRow row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this Media row belongs to and should get its column definitions from.</param>
15 public WixBundleSlipstreamMspRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a SlipstreamMspRow row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this Media row belongs to and should get its column definitions from.</param>
25 public WixBundleSlipstreamMspRow(SourceLineNumber sourceLineNumbers, Table table) :
26 base(sourceLineNumbers, table)
27 {
28 }
29
30 /// <summary>
31 /// Gets or sets the foreign key identifier to the ChainPackage row.
32 /// </summary>
33 public string ChainPackageId
34 {
35 get { return (string)this.Fields[0].Data; }
36 set { this.Fields[0].Data = value; }
37 }
38
39 /// <summary>
40 /// Gets or sets the foreign key identifier to the ChainPackage row for the MSP package.
41 /// </summary>
42 public string MspPackageId
43 {
44 get { return (string)this.Fields[1].Data; }
45 set { this.Fields[1].Data = value; }
46 }
47 }
48}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleUpdateRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleUpdateRow.cs
new file mode 100644
index 00000000..e0150685
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleUpdateRow.cs
@@ -0,0 +1,38 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6
7 /// <summary>
8 /// Bundle update info for binding Bundles.
9 /// </summary>
10 public class WixBundleUpdateRow : Row
11 {
12 /// <summary>
13 /// Creates a WixBundleUpdateRow row that does not belong to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="tableDef">TableDefinition this WixBundleUpdateRow row belongs to and should get its column definitions from.</param>
17 public WixBundleUpdateRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
18 base(sourceLineNumbers, tableDef)
19 {
20 }
21
22 /// <summary>
23 /// Creates a WixBundleUpdateRow row that belongs to a table.
24 /// </summary>
25 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
26 /// <param name="table">Table this WixBundleUpdateRow row belongs to and should get its column definitions from.</param>
27 public WixBundleUpdateRow(SourceLineNumber sourceLineNumbers, Table table) :
28 base(sourceLineNumbers, table)
29 {
30 }
31
32 public string Location
33 {
34 get { return (string)this.Fields[0].Data; }
35 set { this.Fields[0].Data = value; }
36 }
37 }
38}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleVariableRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleVariableRow.cs
new file mode 100644
index 00000000..e7ff1a4d
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixBundleVariableRow.cs
@@ -0,0 +1,80 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the Variable table.
7 /// </summary>
8 public sealed class WixBundleVariableRow : Row
9 {
10 /// <summary>
11 /// Creates a Variable row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this Media row belongs to and should get its column definitions from.</param>
15 public WixBundleVariableRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a Variable row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this Media row belongs to and should get its column definitions from.</param>
25 public WixBundleVariableRow(SourceLineNumber sourceLineNumbers, Table table)
26 : base(sourceLineNumbers, table)
27 {
28 }
29
30 /// <summary>
31 /// Gets or sets the variable identifier.
32 /// </summary>
33 /// <value>The variable identifier.</value>
34 public string Id
35 {
36 get { return (string)this.Fields[0].Data; }
37 set { this.Fields[0].Data = value; }
38 }
39
40 /// <summary>
41 /// Gets or sets the variable's value.
42 /// </summary>
43 /// <value>The variable's value.</value>
44 public string Value
45 {
46 get { return (string)this.Fields[1].Data; }
47 set { this.Fields[1].Data = value; }
48 }
49
50 /// <summary>
51 /// Gets or sets the variable's type.
52 /// </summary>
53 /// <value>The variable's type.</value>
54 public string Type
55 {
56 get { return (string)this.Fields[2].Data; }
57 set { this.Fields[2].Data = value; }
58 }
59
60 /// <summary>
61 /// Gets or sets whether this variable is hidden.
62 /// </summary>
63 /// <value>Whether this variable is hidden.</value>
64 public bool Hidden
65 {
66 get { return (null == this.Fields[3].Data || 0 == ((int)this.Fields[3].Data)) ? false : true; }
67 set { this.Fields[3].Data = value ? 1 : 0; }
68 }
69
70 /// <summary>
71 /// Gets or sets whether this variable is persisted.
72 /// </summary>
73 /// <value>Whether this variable is persisted.</value>
74 public bool Persisted
75 {
76 get { return (null == this.Fields[4].Data || 0 == ((int)this.Fields[4].Data)) ? false : true; }
77 set { this.Fields[4].Data = value ? 1 : 0; }
78 }
79 }
80}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixChainItemRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixChainItemRow.cs
new file mode 100644
index 00000000..12538d71
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixChainItemRow.cs
@@ -0,0 +1,39 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the WixChainItem table.
7 /// </summary>
8 public sealed class WixChainItemRow : Row
9 {
10 /// <summary>
11 /// Creates a WixChainItem row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this ChainItem row belongs to and should get its column definitions from.</param>
15 public WixChainItemRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a WixChainItem row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this ChainItem row belongs to and should get its column definitions from.</param>
25 public WixChainItemRow(SourceLineNumber sourceLineNumbers, Table table)
26 : base(sourceLineNumbers, table)
27 {
28 }
29
30 /// <summary>
31 /// Gets or sets the WixChainItem identifier.
32 /// </summary>
33 public string Id
34 {
35 get { return (string)this.Fields[0].Data; }
36 set { this.Fields[0].Data = value; }
37 }
38 }
39}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixChainRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixChainRow.cs
new file mode 100644
index 00000000..54fff72c
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixChainRow.cs
@@ -0,0 +1,65 @@
1// 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.
2
3using WixToolset.Data.Tuples;
4
5namespace WixToolset.Data.Rows
6{
7 /// <summary>
8 /// Specialization of a row for the WixChain table.
9 /// </summary>
10 public sealed class WixChainRow : Row
11 {
12 /// <summary>
13 /// Creates a WixChain row that does not belong to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="tableDef">TableDefinition this row belongs to and should get its column definitions from.</param>
17 public WixChainRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
18 base(sourceLineNumbers, tableDef)
19 {
20 }
21
22 /// <summary>
23 /// Creates a WixChainRow row that belongs to a table.
24 /// </summary>
25 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
26 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
27 public WixChainRow(SourceLineNumber sourceLineNumbers, Table table) :
28 base(sourceLineNumbers, table)
29 {
30 }
31
32 /// <summary>
33 /// Gets or sets the raw chain attributes.
34 /// </summary>
35 public WixChainAttributes Attributes
36 {
37 get { return (WixChainAttributes)this.Fields[0].Data; }
38 set { this.Fields[0].Data = value; }
39 }
40
41 /// <summary>
42 /// Gets the disable rollback state of a chain.
43 /// </summary>
44 public bool DisableRollback
45 {
46 get { return 0 != (this.Attributes & WixChainAttributes.DisableRollback); }
47 }
48
49 /// <summary>
50 /// Gets disable system restore state of a chain.
51 /// </summary>
52 public bool DisableSystemRestore
53 {
54 get { return 0 != (this.Attributes & WixChainAttributes.DisableSystemRestore); }
55 }
56
57 /// <summary>
58 /// Gets parallel cache of a chain.
59 /// </summary>
60 public bool ParallelCache
61 {
62 get { return 0 != (this.Attributes & WixChainAttributes.ParallelCache); }
63 }
64 }
65}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixComplexReferenceRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixComplexReferenceRow.cs
new file mode 100644
index 00000000..40ca4592
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixComplexReferenceRow.cs
@@ -0,0 +1,204 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.Diagnostics;
7 using System.Diagnostics.CodeAnalysis;
8 using System.Xml;
9
10 /// <summary>
11 /// Specialization of a row for the WixComplexReference table.
12 /// </summary>
13 public sealed class WixComplexReferenceRow : Row, IComparable
14 {
15 /// <summary>
16 /// Creates a WixComplexReferenceRow row that belongs to a table.
17 /// </summary>
18 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
19 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
20 public WixComplexReferenceRow(SourceLineNumber sourceLineNumbers, Table table)
21 : base(sourceLineNumbers, table)
22 {
23 }
24
25 /// <summary>
26 /// Gets the parent type of the complex reference.
27 /// </summary>
28 /// <value>Parent type of the complex reference.</value>
29 public ComplexReferenceParentType ParentType
30 {
31 get { return (ComplexReferenceParentType)Enum.ToObject(typeof(ComplexReferenceParentType), (int)this.Fields[1].Data); }
32 set { this.Fields[1].Data = (int)value; }
33 }
34
35 /// <summary>
36 /// Gets or sets the parent identifier of the complex reference.
37 /// </summary>
38 /// <value>Parent identifier of the complex reference.</value>
39 public string ParentId
40 {
41 get { return (string)this.Fields[0].Data; }
42 set { this.Fields[0].Data = value; }
43 }
44
45 /// <summary>
46 /// Gets the parent language of the complex reference.
47 /// </summary>
48 /// <value>Parent language of the complex reference.</value>
49 public string ParentLanguage
50 {
51 get { return (string)this.Fields[2].Data; }
52 set { this.Fields[2].Data = value; }
53 }
54
55 /// <summary>
56 /// Gets the child type of the complex reference.
57 /// </summary>
58 /// <value>Child type of the complex reference.</value>
59 public ComplexReferenceChildType ChildType
60 {
61 get { return (ComplexReferenceChildType)Enum.ToObject(typeof(ComplexReferenceChildType), (int)this.Fields[4].Data); }
62 set { this.Fields[4].Data = (int)value; }
63 }
64
65 /// <summary>
66 /// Gets the child identifier of the complex reference.
67 /// </summary>
68 /// <value>Child identifier of the complex reference.</value>
69 public string ChildId
70 {
71 get { return (string)this.Fields[3].Data; }
72 set { this.Fields[3].Data = value; }
73 }
74
75 /// <summary>
76 /// Gets if this is the primary complex reference.
77 /// </summary>
78 /// <value>true if primary complex reference.</value>
79 public bool IsPrimary
80 {
81 get
82 {
83 return (0x1 == ((int)this.Fields[5].Data & 0x1));
84 }
85
86 set
87 {
88 if (null == this.Fields[5].Data)
89 {
90 this.Fields[5].Data = 0;
91 }
92
93 if (value)
94 {
95 this.Fields[5].Data = (int)this.Fields[5].Data | 0x1;
96 }
97 else
98 {
99 this.Fields[5].Data = (int)this.Fields[5].Data & ~0x1;
100 }
101 }
102 }
103
104 /// <summary>
105 /// Determines if two complex references are equivalent.
106 /// </summary>
107 /// <param name="obj">Complex reference to compare.</param>
108 /// <returns>True if complex references are equivalent.</returns>
109 public override bool Equals(object obj)
110 {
111 return 0 == this.CompareTo(obj);
112 }
113
114 /// <summary>
115 /// Gets the hash code for the complex reference.
116 /// </summary>
117 /// <returns>Hash code for the complex reference.</returns>
118 public override int GetHashCode()
119 {
120 return this.ChildType.GetHashCode() ^ this.ChildId.GetHashCode() ^ this.ParentType.GetHashCode() ^ this.ParentLanguage.GetHashCode() ^ this.ParentId.GetHashCode() ^ this.IsPrimary.GetHashCode();
121 }
122
123 /// <summary>
124 /// Compares two complex references.
125 /// </summary>
126 /// <param name="obj">Complex reference to compare to.</param>
127 /// <returns>Zero if the objects are equivalent, negative number if the provided object is less, positive if greater.</returns>
128 public int CompareTo(object obj)
129 {
130 int comparison = this.CompareToWithoutConsideringPrimary(obj);
131 if (0 == comparison)
132 {
133 comparison = ((WixComplexReferenceRow)obj).IsPrimary.CompareTo(this.IsPrimary); // Note: the order of these is purposely switched to ensure that "Yes" is lower than "No" and "NotSet"
134 }
135 return comparison;
136 }
137
138 /// <summary>
139 /// Compares two complex references without considering the primary bit.
140 /// </summary>
141 /// <param name="obj">Complex reference to compare to.</param>
142 /// <returns>Zero if the objects are equivalent, negative number if the provided object is less, positive if greater.</returns>
143 [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.ArgumentException.#ctor(System.String,System.String)")]
144 public int CompareToWithoutConsideringPrimary(object obj)
145 {
146 var other = obj as WixComplexReferenceRow ?? throw new ArgumentNullException(nameof(obj));
147
148 int comparison = this.ChildType - other.ChildType;
149 if (0 == comparison)
150 {
151 comparison = String.Compare(this.ChildId, other.ChildId, StringComparison.Ordinal);
152 if (0 == comparison)
153 {
154 comparison = this.ParentType - other.ParentType;
155 if (0 == comparison)
156 {
157 string thisParentLanguage = null == this.ParentLanguage ? String.Empty : this.ParentLanguage;
158 string otherParentLanguage = null == other.ParentLanguage ? String.Empty : other.ParentLanguage;
159 comparison = String.Compare(thisParentLanguage, otherParentLanguage, StringComparison.Ordinal);
160 if (0 == comparison)
161 {
162 comparison = String.Compare(this.ParentId, other.ParentId, StringComparison.Ordinal);
163 }
164 }
165 }
166 }
167
168 return comparison;
169 }
170
171 /// <summary>
172 /// Creates a shallow copy of the ComplexReference.
173 /// </summary>
174 /// <returns>A shallow copy of the ComplexReference.</returns>
175 public WixComplexReferenceRow Clone()
176 {
177 WixComplexReferenceRow wixComplexReferenceRow = new WixComplexReferenceRow(this.SourceLineNumbers, this.Table);
178 wixComplexReferenceRow.ParentType = this.ParentType;
179 wixComplexReferenceRow.ParentId = this.ParentId;
180 wixComplexReferenceRow.ParentLanguage = this.ParentLanguage;
181 wixComplexReferenceRow.ChildType = this.ChildType;
182 wixComplexReferenceRow.ChildId = this.ChildId;
183 wixComplexReferenceRow.IsPrimary = this.IsPrimary;
184
185 return wixComplexReferenceRow;
186 }
187
188 /// <summary>
189 /// Changes all of the parent references to point to the passed in parent reference.
190 /// </summary>
191 /// <param name="parent">New parent complex reference.</param>
192 public void Reparent(WixComplexReferenceRow parent)
193 {
194 this.ParentId = parent.ParentId;
195 this.ParentLanguage = parent.ParentLanguage;
196 this.ParentType = parent.ParentType;
197
198 if (!this.IsPrimary)
199 {
200 this.IsPrimary = parent.IsPrimary;
201 }
202 }
203 }
204}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixDeltaPatchFileRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixDeltaPatchFileRow.cs
new file mode 100644
index 00000000..000779d9
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixDeltaPatchFileRow.cs
@@ -0,0 +1,142 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the WixDeltaPatchFile table.
7 /// </summary>
8 public sealed class WixDeltaPatchFileRow : Row
9 {
10 /// <summary>
11 /// Creates a WixDeltaPatchFile row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this Media row belongs to and should get its column definitions from.</param>
15 public WixDeltaPatchFileRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a WixDeltaPatchFile row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this File row belongs to and should get its column definitions from.</param>
25 public WixDeltaPatchFileRow(SourceLineNumber sourceLineNumbers, Table table) :
26 base(sourceLineNumbers, table)
27 {
28 }
29
30 /// <summary>
31 /// Gets or sets the primary key of the file row.
32 /// </summary>
33 /// <value>Primary key of the file row.</value>
34 public string File
35 {
36 get { return (string)this.Fields[0].Data; }
37 set { this.Fields[0].Data = value; }
38 }
39
40 /// <summary>
41 /// Gets or sets the delta patch retain-length list for the file.
42 /// </summary>
43 /// <value>RetainLength list for the file.</value>
44 public string RetainLengths
45 {
46 get { return (string)this.Fields[1].Data; }
47 set { this.Fields[1].Data = value; }
48 }
49
50 /// <summary>
51 /// Gets or sets the previous delta patch retain-length list for the file.
52 /// </summary>
53 /// <value>Previous RetainLength list for the file.</value>
54 public string PreviousRetainLengths
55 {
56 get { return this.Fields[1].PreviousData; }
57 set { this.Fields[1].PreviousData = value; }
58 }
59
60 /// <summary>
61 /// Gets or sets the delta patch ignore-offset list for the file.
62 /// </summary>
63 /// <value>IgnoreOffset list for the file.</value>
64 public string IgnoreOffsets
65 {
66 get { return (string)this.Fields[2].Data; }
67 set { this.Fields[2].Data = value; }
68 }
69
70 /// <summary>
71 /// Gets or sets the previous delta patch ignore-offset list for the file.
72 /// </summary>
73 /// <value>Previous IgnoreOffset list for the file.</value>
74 public string PreviousIgnoreOffsets
75 {
76 get { return this.Fields[2].PreviousData; }
77 set { this.Fields[2].PreviousData = value; }
78 }
79
80 /// <summary>
81 /// Gets or sets the delta patch ignore-length list for the file.
82 /// </summary>
83 /// <value>IgnoreLength list for the file.</value>
84 public string IgnoreLengths
85 {
86 get { return (string)this.Fields[3].Data; }
87 set { this.Fields[3].Data = value; }
88 }
89
90 /// <summary>
91 /// Gets or sets the previous delta patch ignore-length list for the file.
92 /// </summary>
93 /// <value>Previous IgnoreLength list for the file.</value>
94 public string PreviousIgnoreLengths
95 {
96 get { return this.Fields[3].PreviousData; }
97 set { this.Fields[3].PreviousData = value; }
98 }
99
100 /// <summary>
101 /// Gets or sets the delta patch retain-offset list for the file.
102 /// </summary>
103 /// <value>RetainOffset list for the file.</value>
104 public string RetainOffsets
105 {
106 get { return (string)this.Fields[4].Data; }
107 set { this.Fields[4].Data = value; }
108 }
109
110 /// <summary>
111 /// Gets or sets the previous delta patch retain-offset list for the file.
112 /// </summary>
113 /// <value>PreviousRetainOffset list for the file.</value>
114 public string PreviousRetainOffsets
115 {
116 get { return this.Fields[4].PreviousData; }
117 set { this.Fields[4].PreviousData = value; }
118 }
119
120 /// <summary>
121 /// Gets or sets the symbol paths for the file.
122 /// </summary>
123 /// <value>SymbolPath list for the file.</value>
124 /// <remarks>This is set during binding.</remarks>
125 public string Symbols
126 {
127 get { return (string)this.Fields[5].Data; }
128 set { this.Fields[5].Data = value; }
129 }
130
131 /// <summary>
132 /// Gets or sets the previous symbol paths for the file.
133 /// </summary>
134 /// <value>PreviousSymbolPath list for the file.</value>
135 /// <remarks>This is set during binding.</remarks>
136 public string PreviousSymbols
137 {
138 get { return (string)this.Fields[5].PreviousData; }
139 set { this.Fields[5].PreviousData = value; }
140 }
141 }
142}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixDeltaPatchSymbolPathsRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixDeltaPatchSymbolPathsRow.cs
new file mode 100644
index 00000000..b6c0b840
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixDeltaPatchSymbolPathsRow.cs
@@ -0,0 +1,58 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the WixDeltaPatchSymbolPaths table.
7 /// </summary>
8 public sealed class WixDeltaPatchSymbolPathsRow : Row
9 {
10 /// <summary>
11 /// Creates a WixDeltaPatchSymbolPaths row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this row belongs to and should get its column definitions from.</param>
15 public WixDeltaPatchSymbolPathsRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a WixDeltaPatchSymbolPaths row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
25 public WixDeltaPatchSymbolPathsRow(SourceLineNumber sourceLineNumbers, Table table) :
26 base(sourceLineNumbers, table)
27 {
28 }
29
30 /// <summary>
31 /// Gets or sets the identifier the symbol paths apply to.
32 /// </summary>
33 /// <value>RetainLength list for the file.</value>
34 public string Id
35 {
36 get { return (string)this.Fields[0].Data; }
37 set { this.Fields[0].Data = value; }
38 }
39
40 /// <summary>
41 /// Gets or sets the type of the identifier.
42 /// </summary>
43 public SymbolPathType Type
44 {
45 get { return (SymbolPathType)this.Fields[1].AsInteger(); }
46 set { this.Fields[1].Data = value; }
47 }
48
49 /// <summary>
50 /// Gets or sets the delta patch symbol paths.
51 /// </summary>
52 public string SymbolPaths
53 {
54 get { return (string)this.Fields[2].Data; }
55 set { this.Fields[2].Data = value; }
56 }
57 }
58}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixFileRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixFileRow.cs
new file mode 100644
index 00000000..c006355a
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixFileRow.cs
@@ -0,0 +1,163 @@
1// 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.
2
3using WixToolset.Data.Tuples;
4
5namespace WixToolset.Data.Rows
6{
7 /// <summary>
8 /// Specialization of a row for the WixFile table.
9 /// </summary>
10 public sealed class WixFileRow : Row
11 {
12 /// <summary>
13 /// Creates a WixFile row that does not belong to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="tableDef">TableDefinition this row belongs to and should get its column definitions from.</param>
17 public WixFileRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
18 base(sourceLineNumbers, tableDef)
19 {
20 }
21
22 /// <summary>
23 /// Creates a WixFile row that belongs to a table.
24 /// </summary>
25 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
26 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
27 public WixFileRow(SourceLineNumber sourceLineNumbers, Table table) :
28 base(sourceLineNumbers, table)
29 {
30 }
31
32 /// <summary>
33 /// Gets or sets the primary key of the file row.
34 /// </summary>
35 /// <value>Primary key of the file row.</value>
36 public string File
37 {
38 get { return (string)this.Fields[0].Data; }
39 set { this.Fields[0].Data = value; }
40 }
41
42 /// <summary>
43 /// Gets or sets the assembly type of the file row.
44 /// </summary>
45 /// <value>Assembly type of the file row.</value>
46 public FileAssemblyType AssemblyType
47 {
48 get { return (null == this.Fields[1]) ? FileAssemblyType.NotAnAssembly : (FileAssemblyType)this.Fields[1].AsInteger(); }
49 set { this.Fields[1].Data = (int)value; }
50 }
51
52 /// <summary>
53 /// Gets or sets the identifier for the assembly manifest.
54 /// </summary>
55 /// <value>Identifier for the assembly manifest.</value>
56 public string AssemblyManifest
57 {
58 get { return (string)this.Fields[2].Data; }
59 set { this.Fields[2].Data = value; }
60 }
61
62 /// <summary>
63 /// Gets or sets the application for the assembly.
64 /// </summary>
65 /// <value>Application for the assembly.</value>
66 public string AssemblyApplication
67 {
68 get { return (string)this.Fields[3].Data; }
69 set { this.Fields[3].Data = value; }
70 }
71
72 /// <summary>
73 /// Gets or sets the directory of the file.
74 /// </summary>
75 /// <value>Directory of the file.</value>
76 public string Directory
77 {
78 get { return (string)this.Fields[4].Data; }
79 set { this.Fields[4].Data = value; }
80 }
81
82 /// <summary>
83 /// Gets or sets the disk id for this file.
84 /// </summary>
85 /// <value>Disk id for the file.</value>
86 public int DiskId
87 {
88 get { return (int)this.Fields[5].Data; }
89 set { this.Fields[5].Data = value; }
90 }
91
92 /// <summary>
93 /// Gets or sets the source location to the file.
94 /// </summary>
95 /// <value>Source location to the file.</value>
96 public string Source
97 {
98 get { return (string)this.Fields[6].Data; }
99 set { this.Fields[6].Data = value; }
100 }
101
102 /// <summary>
103 /// Gets or sets the source location to the file.
104 /// </summary>
105 /// <value>Source location to the file.</value>
106 public string PreviousSource
107 {
108 get { return (string)this.Fields[6].PreviousData; }
109 set { this.Fields[6].PreviousData = value; }
110 }
111
112 /// <summary>
113 /// Gets or sets the architecture the file executes on.
114 /// </summary>
115 /// <value>Architecture the file executes on.</value>
116 public string ProcessorArchitecture
117 {
118 get { return (string)this.Fields[7].Data; }
119 set { this.Fields[7].Data = value; }
120 }
121
122 /// <summary>
123 /// Gets or sets the patch group of a patch-added file.
124 /// </summary>
125 /// <value>The patch group of a patch-added file.</value>
126 public int PatchGroup
127 {
128 get { return (null == this.Fields[8].Data) ? 0 : (int)this.Fields[8].Data; }
129 set { this.Fields[8].Data = value; }
130 }
131
132 /// <summary>
133 /// Gets or sets the attributes on a file.
134 /// </summary>
135 /// <value>Attributes on a file.</value>
136 public int Attributes
137 {
138 get { return (int)this.Fields[9].Data; }
139 set { this.Fields[9].Data = value; }
140 }
141
142 /// <summary>
143 /// Gets or sets the patching attributes to the file.
144 /// </summary>
145 /// <value>Patching attributes of the file.</value>
146 public PatchAttributeType PatchAttributes
147 {
148 get { return (PatchAttributeType)this.Fields[10].AsInteger(); }
149 set { this.Fields[10].Data = (int)value; }
150 }
151
152 /// <summary>
153 /// Gets or sets the path to the delta patch header.
154 /// </summary>
155 /// <value>Patch header path.</value>
156 /// <remarks>Set by the binder only when doing delta patching.</remarks>
157 public string DeltaPatchHeaderSource
158 {
159 get { return (string)this.Fields[11].Data; }
160 set { this.Fields[11].Data = value; }
161 }
162 }
163}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixGroupRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixGroupRow.cs
new file mode 100644
index 00000000..d36338d1
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixGroupRow.cs
@@ -0,0 +1,62 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6
7 /// <summary>
8 /// Specialization of a row for the WixGroup table.
9 /// </summary>
10 public sealed class WixGroupRow : Row
11 {
12 /// <summary>
13 /// Creates a WixGroupRow row that belongs to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
17 public WixGroupRow(SourceLineNumber sourceLineNumbers, Table table)
18 : base(sourceLineNumbers, table)
19 {
20 }
21
22 /// <summary>
23 /// Gets or sets the parent identifier of the complex reference.
24 /// </summary>
25 /// <value>Parent identifier of the complex reference.</value>
26 public string ParentId
27 {
28 get { return (string)this.Fields[0].Data; }
29 set { this.Fields[0].Data = value; }
30 }
31
32 /// <summary>
33 /// Gets the parent type of the complex reference.
34 /// </summary>
35 /// <value>Parent type of the complex reference.</value>
36 public ComplexReferenceParentType ParentType
37 {
38 get { return (ComplexReferenceParentType)Enum.Parse(typeof(ComplexReferenceParentType), (string)this.Fields[1].Data); }
39 set { this.Fields[1].Data = value.ToString(); }
40 }
41
42 /// <summary>
43 /// Gets the child identifier of the complex reference.
44 /// </summary>
45 /// <value>Child identifier of the complex reference.</value>
46 public string ChildId
47 {
48 get { return (string)this.Fields[2].Data; }
49 set { this.Fields[2].Data = value; }
50 }
51
52 /// <summary>
53 /// Gets the child type of the complex reference.
54 /// </summary>
55 /// <value>Child type of the complex reference.</value>
56 public ComplexReferenceChildType ChildType
57 {
58 get { return (ComplexReferenceChildType)Enum.Parse(typeof(ComplexReferenceChildType), (string)this.Fields[3].Data); }
59 set { this.Fields[3].Data = value.ToString(); }
60 }
61 }
62}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixMediaRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixMediaRow.cs
new file mode 100644
index 00000000..c1b3e155
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixMediaRow.cs
@@ -0,0 +1,60 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the WixMedia table.
7 /// </summary>
8 public sealed class WixMediaRow : Row
9 {
10 /// <summary>
11 /// Creates a WixMedia row that does not belong to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="tableDef">TableDefinition this Media row belongs to and should get its column definitions from.</param>
15 public WixMediaRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
16 base(sourceLineNumbers, tableDef)
17 {
18 }
19
20 /// <summary>
21 /// Creates a WixMedia row that belongs to a table.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
24 /// <param name="table">Table this Media row belongs to and should get its column definitions from.</param>
25 public WixMediaRow(SourceLineNumber sourceLineNumbers, Table table) :
26 base(sourceLineNumbers, table)
27 {
28 }
29
30 /// <summary>
31 /// Gets or sets the disk id for this media.
32 /// </summary>
33 /// <value>Disk id for the media.</value>
34 public int DiskId
35 {
36 get { return (int)this.Fields[0].Data; }
37 set { this.Fields[0].Data = value; }
38 }
39
40 /// <summary>
41 /// Gets or sets the compression level for this media row.
42 /// </summary>
43 /// <value>Compression level.</value>
44 public CompressionLevel? CompressionLevel
45 {
46 get { return (CompressionLevel?)this.Fields[1].AsNullableInteger(); }
47 set { this.Fields[1].Data = value; }
48 }
49
50 /// <summary>
51 /// Gets or sets the layout location for this media row.
52 /// </summary>
53 /// <value>Layout location to the root of the media.</value>
54 public string Layout
55 {
56 get { return (string)this.Fields[2].Data; }
57 set { this.Fields[2].Data = value; }
58 }
59 }
60}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixMediaTemplateRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixMediaTemplateRow.cs
new file mode 100644
index 00000000..27c5ccce
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixMediaTemplateRow.cs
@@ -0,0 +1,81 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 /// <summary>
6 /// Specialization of a row for the MediaTemplate table.
7 /// </summary>
8 public sealed class WixMediaTemplateRow : Row
9 {
10 /// <summary>
11 /// Creates a MediaTemplate row that belongs to a table.
12 /// </summary>
13 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
14 /// <param name="table">Table this MediaTeplate row belongs to and should get its column definitions from.</param>
15 public WixMediaTemplateRow(SourceLineNumber sourceLineNumbers, Table table)
16 : base(sourceLineNumbers, table)
17 {
18 }
19
20 /// <summary>
21 /// Gets or sets the cabinet template name for this media template row.
22 /// </summary>
23 /// <value>Cabinet name.</value>
24 public string CabinetTemplate
25 {
26 get { return (string)this.Fields[0].Data; }
27 set { this.Fields[0].Data = value; }
28 }
29
30 /// <summary>
31 /// Gets or sets the compression level for this media template row.
32 /// </summary>
33 /// <value>Compression level.</value>
34 public CompressionLevel? CompressionLevel
35 {
36 get { return (CompressionLevel?)this.Fields[1].AsNullableInteger(); }
37 set { this.Fields[1].Data = value; }
38 }
39
40 /// <summary>
41 /// Gets or sets the disk prompt for this media template row.
42 /// </summary>
43 /// <value>Disk prompt.</value>
44 public string DiskPrompt
45 {
46 get { return (string)this.Fields[2].Data; }
47 set { this.Fields[2].Data = value; }
48 }
49
50
51 /// <summary>
52 /// Gets or sets the volume label for this media template row.
53 /// </summary>
54 /// <value>Volume label.</value>
55 public string VolumeLabel
56 {
57 get { return (string)this.Fields[3].Data; }
58 set { this.Fields[3].Data = value; }
59 }
60
61 /// <summary>
62 /// Gets or sets the maximum uncompressed media size for this media template row.
63 /// </summary>
64 /// <value>Disk id.</value>
65 public int MaximumUncompressedMediaSize
66 {
67 get { return (int)this.Fields[4].Data; }
68 set { this.Fields[4].Data = value; }
69 }
70
71 /// <summary>
72 /// Gets or sets the Maximum Cabinet Size For Large File Splitting for this media template row.
73 /// </summary>
74 /// <value>Disk id.</value>
75 public int MaximumCabinetSizeForLargeFileSplitting
76 {
77 get { return (int)this.Fields[5].Data; }
78 set { this.Fields[5].Data = value; }
79 }
80 }
81}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixMergeRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixMergeRow.cs
new file mode 100644
index 00000000..54f2125c
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixMergeRow.cs
@@ -0,0 +1,149 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.Globalization;
7 using System.Text;
8 using System.Xml;
9
10 /// <summary>
11 /// Specialization of a row for tracking merge statements.
12 /// </summary>
13 public sealed class WixMergeRow : Row
14 {
15 /// <summary>
16 /// Creates a Merge row that does not belong to a table.
17 /// </summary>
18 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
19 /// <param name="tableDef">TableDefinition this Merge row belongs to and should get its column definitions from.</param>
20 public WixMergeRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
21 base(sourceLineNumbers, tableDef)
22 {
23 }
24
25 /// <summary>Creates a Merge row that belongs to a table.</summary>
26 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
27 /// <param name="table">Table this Merge row belongs to and should get its column definitions from.</param>
28 public WixMergeRow(SourceLineNumber sourceLineNumbers, Table table) :
29 base(sourceLineNumbers, table)
30 {
31 }
32
33 /// <summary>
34 /// Gets and sets the id for a merge row.
35 /// </summary>
36 /// <value>Id for the row.</value>
37 public string Id
38 {
39 get { return (string)this.Fields[0].Data; }
40 set { this.Fields[0].Data = value; }
41 }
42
43 /// <summary>
44 /// Gets and sets the language for a merge row.
45 /// </summary>
46 /// <value>Language for the row.</value>
47 public string Language
48 {
49 get { return (string)this.Fields[1].Data; }
50 set { this.Fields[1].Data = value; }
51 }
52
53 /// <summary>
54 /// Gets and sets the directory for a merge row.
55 /// </summary>
56 /// <value>Direcotory for the row.</value>
57 public string Directory
58 {
59 get { return (string)this.Fields[2].Data; }
60 set { this.Fields[2].Data = value; }
61 }
62
63 /// <summary>
64 /// Gets and sets the path to the merge module for a merge row.
65 /// </summary>
66 /// <value>Source path for the row.</value>
67 public string SourceFile
68 {
69 get { return (string)this.Fields[3].Data; }
70 set { this.Fields[3].Data = value; }
71 }
72
73 /// <summary>
74 /// Gets and sets the disk id the merge module should be placed on for a merge row.
75 /// </summary>
76 /// <value>Disk identifier for row.</value>
77 public int DiskId
78 {
79 get { return (int)this.Fields[4].Data; }
80 set { this.Fields[4].Data = value; }
81 }
82
83 /// <summary>
84 /// Gets and sets the compression value for a merge row.
85 /// </summary>
86 /// <value>Compression for a merge row.</value>
87 public YesNoType FileCompression
88 {
89 get
90 {
91 if (null == this.Fields[5].Data)
92 {
93 return YesNoType.NotSet;
94 }
95 else if (1 == (int)this.Fields[5].Data)
96 {
97 return YesNoType.Yes;
98 }
99 else if (0 == (int)this.Fields[5].Data)
100 {
101 return YesNoType.No;
102 }
103 else
104 {
105 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixDataStrings.EXP_MergeTableFileCompressionColumnContainsInvalidValue, this.Fields[5].Data));
106 }
107 }
108 set
109 {
110 if (YesNoType.Yes == value)
111 {
112 this.Fields[5].Data = 1;
113 }
114 else if (YesNoType.No == value)
115 {
116 this.Fields[5].Data = 0;
117 }
118 else if (YesNoType.NotSet == value)
119 {
120 this.Fields[5].Data = null;
121 }
122 else
123 {
124 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixDataStrings.EXP_CannotSetMergeTableFileCompressionColumnToInvalidValue, value));
125 }
126 }
127 }
128
129 /// <summary>
130 /// Gets and sets the configuration data for a merge row.
131 /// </summary>
132 /// <value>Comma delimited string of "name=value" pairs.</value>
133 public string ConfigurationData
134 {
135 get { return (string)this.Fields[6].Data; }
136 set { this.Fields[6].Data = value; }
137 }
138
139 /// <summary>
140 /// Gets and sets the primary feature for a merge row.
141 /// </summary>
142 /// <value>The primary feature for a merge row.</value>
143 public string Feature
144 {
145 get { return (string)this.Fields[7].Data; }
146 set { this.Fields[7].Data = value; }
147 }
148 }
149}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixPayloadPropertiesRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixPayloadPropertiesRow.cs
new file mode 100644
index 00000000..2e5f53ad
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixPayloadPropertiesRow.cs
@@ -0,0 +1,81 @@
1//-------------------------------------------------------------------------------------------------
2// <copyright file="WixPayloadPropertiesRow.cs" company="Outercurve Foundation">
3// Copyright (c) 2004, Outercurve Foundation.
4// This software is released under Microsoft Reciprocal License (MS-RL).
5// The license and further copyright text can be found in the file
6// LICENSE.TXT at the root directory of the distribution.
7// </copyright>
8//-------------------------------------------------------------------------------------------------
9
10namespace WixToolset.Data.Rows
11{
12 using System;
13
14 /// <summary>
15 /// Specialization of a row for the WixPayloadProperties table.
16 /// </summary>
17 public class WixPayloadPropertiesRow : Row
18 {
19 /// <summary>
20 /// Creates a WixPayloadProperties row that does not belong to a table.
21 /// </summary>
22 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
23 /// <param name="tableDef">TableDefinition this WixPayloadProperties row belongs to and should get its column definitions from.</param>
24 public WixPayloadPropertiesRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
25 base(sourceLineNumbers, tableDef)
26 {
27 }
28
29 /// <summary>
30 /// Creates a WixPayloadProperties row that belongs to a table.
31 /// </summary>
32 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
33 /// <param name="table">Table this WixPayloadProperties row belongs to and should get its column definitions from.</param>
34 public WixPayloadPropertiesRow(SourceLineNumber sourceLineNumbers, Table table) :
35 base(sourceLineNumbers, table)
36 {
37 }
38
39 public string Id
40 {
41 get { return (string)this.Fields[0].Data; }
42 set { this.Fields[0].Data = value; }
43 }
44
45 public string Package
46 {
47 get { return (string)this.Fields[1].Data; }
48 set { this.Fields[1].Data = value; }
49 }
50
51 public string Container
52 {
53 get { return (string)this.Fields[2].Data; }
54 set { this.Fields[2].Data = value; }
55 }
56
57 public string Name
58 {
59 get { return (string)this.Fields[3].Data; }
60 set { this.Fields[3].Data = value; }
61 }
62
63 public string Size
64 {
65 get { return (string)this.Fields[4].Data; }
66 set { this.Fields[4].Data = value; }
67 }
68
69 public string DownloadUrl
70 {
71 get { return (string)this.Fields[5].Data; }
72 set { this.Fields[5].Data = value; }
73 }
74
75 public string LayoutOnly
76 {
77 get { return (string)this.Fields[6].Data; }
78 set { this.Fields[6].Data = value; }
79 }
80 }
81}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixPropertyRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixPropertyRow.cs
new file mode 100644
index 00000000..5285195c
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixPropertyRow.cs
@@ -0,0 +1,118 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.Globalization;
7
8 /// <summary>
9 /// Specialization of a row for the WixProperty table.
10 /// </summary>
11 public sealed class WixPropertyRow : Row
12 {
13 /// <summary>Creates a WixProperty row that belongs to a table.</summary>
14 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
15 /// <param name="table">Table this WixProperty row belongs to and should get its column definitions from.</param>
16 public WixPropertyRow(SourceLineNumber sourceLineNumbers, Table table) :
17 base(sourceLineNumbers, table)
18 {
19 }
20
21 /// <summary>
22 /// Gets and sets the id for this property row.
23 /// </summary>
24 /// <value>Id for the property.</value>
25 public string Id
26 {
27 get { return (string)this.Fields[0].Data; }
28 set { this.Fields[0].Data = value; }
29 }
30
31 /// <summary>
32 /// Gets and sets if this is an admin property row.
33 /// </summary>
34 /// <value>Flag if this is an admin property.</value>
35 public bool Admin
36 {
37 get
38 {
39 return (0x1 == (Convert.ToInt32(this.Fields[1].Data, CultureInfo.InvariantCulture) & 0x1));
40 }
41
42 set
43 {
44 if (null == this.Fields[1].Data)
45 {
46 this.Fields[1].Data = 0;
47 }
48
49 if (value)
50 {
51 this.Fields[1].Data = (int)this.Fields[1].Data | 0x1;
52 }
53 else
54 {
55 this.Fields[1].Data = (int)this.Fields[1].Data & ~0x1;
56 }
57 }
58 }
59
60 /// <summary>
61 /// Gets and sets if this is a hidden property row.
62 /// </summary>
63 /// <value>Flag if this is a hidden property.</value>
64 public bool Hidden
65 {
66 get
67 {
68 return (0x2 == (Convert.ToInt32(this.Fields[1].Data, CultureInfo.InvariantCulture) & 0x2));
69 }
70
71 set
72 {
73 if (null == this.Fields[1].Data)
74 {
75 this.Fields[1].Data = 0;
76 }
77
78 if (value)
79 {
80 this.Fields[1].Data = (int)this.Fields[1].Data | 0x2;
81 }
82 else
83 {
84 this.Fields[1].Data = (int)this.Fields[1].Data & ~0x2;
85 }
86 }
87 }
88
89 /// <summary>
90 /// Gets and sets if this is a secure property row.
91 /// </summary>
92 /// <value>Flag if this is a secure property.</value>
93 public bool Secure
94 {
95 get
96 {
97 return (0x4 == (Convert.ToInt32(this.Fields[1].Data, CultureInfo.InvariantCulture) & 0x4));
98 }
99
100 set
101 {
102 if (null == this.Fields[1].Data)
103 {
104 this.Fields[1].Data = 0;
105 }
106
107 if (value)
108 {
109 this.Fields[1].Data = (int)this.Fields[1].Data | 0x4;
110 }
111 else
112 {
113 this.Fields[1].Data = (int)this.Fields[1].Data & ~0x4;
114 }
115 }
116 }
117 }
118}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixRelatedBundleRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixRelatedBundleRow.cs
new file mode 100644
index 00000000..95fffde5
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixRelatedBundleRow.cs
@@ -0,0 +1,52 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using Serialize = WixToolset.Data.Serialize;
6
7 /// <summary>
8 /// Specialization of a row for the RelatedBundle table.
9 /// </summary>
10 public sealed class WixRelatedBundleRow : Row
11 {
12 /// <summary>
13 /// Creates a RelatedBundle row that does not belong to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="tableDef">TableDefinition this RelatedBundle row belongs to and should get its column definitions from.</param>
17 public WixRelatedBundleRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
18 base(sourceLineNumbers, tableDef)
19 {
20 }
21
22 /// <summary>
23 /// Creates a RelatedBundle row that belongs to a table.
24 /// </summary>
25 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
26 /// <param name="table">Table this RelatedBundle row belongs to and should get its column definitions from.</param>
27 public WixRelatedBundleRow(SourceLineNumber sourceLineNumbers, Table table)
28 : base(sourceLineNumbers, table)
29 {
30 }
31
32 /// <summary>
33 /// Gets or sets the related bundle identifier.
34 /// </summary>
35 /// <value>The related bundle identifier.</value>
36 public string Id
37 {
38 get { return (string)this.Fields[0].Data; }
39 set { this.Fields[0].Data = value; }
40 }
41
42 /// <summary>
43 /// Gets or sets the related bundle action.
44 /// </summary>
45 /// <value>The related bundle action.</value>
46 public Serialize.RelatedBundle.ActionType Action
47 {
48 get { return (Serialize.RelatedBundle.ActionType)this.Fields[1].Data; }
49 set { this.Fields[1].Data = (int)value; }
50 }
51 }
52}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixSimpleReferenceRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixSimpleReferenceRow.cs
new file mode 100644
index 00000000..3a2cf8f1
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixSimpleReferenceRow.cs
@@ -0,0 +1,63 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.Diagnostics;
7 using System.Xml;
8
9 /// <summary>
10 /// Specialization of a row for the WixSimpleReference table.
11 /// </summary>
12 public sealed class WixSimpleReferenceRow : Row
13 {
14 /// <summary>
15 /// Creates a WixSimpleReferenceRow that belongs to a table.
16 /// </summary>
17 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
18 /// <param name="table">Table this row belongs to and should get its column definitions from.</param>
19 public WixSimpleReferenceRow(SourceLineNumber sourceLineNumbers, Table table)
20 : base(sourceLineNumbers, table)
21 {
22 }
23
24 /// <summary>
25 /// Creates a WixSimpleReferenceRow that belongs to a table.
26 /// </summary>
27 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
28 /// <param name="tableDefinitions">Table definitions for this row.</param>
29 public WixSimpleReferenceRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDefinitions)
30 : base(sourceLineNumbers, tableDefinitions)
31 {
32 }
33
34 /// <summary>
35 /// Gets or sets the primary keys of the simple reference.
36 /// </summary>
37 /// <value>The primary keys of the simple reference.</value>
38 public string PrimaryKeys
39 {
40 get { return (string)this.Fields[1].Data; }
41 set { this.Fields[1].Data = value; }
42 }
43
44 /// <summary>
45 /// Gets the symbolic name.
46 /// </summary>
47 /// <value>Symbolic name.</value>
48 public string SymbolicName
49 {
50 get { return String.Concat(this.TableName, ":", this.PrimaryKeys); }
51 }
52
53 /// <summary>
54 /// Gets or sets the table name of the simple reference.
55 /// </summary>
56 /// <value>The table name of the simple reference.</value>
57 public string TableName
58 {
59 get { return (string)this.Fields[0].Data; }
60 set { this.Fields[0].Data = value; }
61 }
62 }
63}
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixUpdateRegistrationRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixUpdateRegistrationRow.cs
new file mode 100644
index 00000000..8d86f970
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixUpdateRegistrationRow.cs
@@ -0,0 +1,62 @@
1// 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.
2
3namespace WixToolset.Data.Rows
4{
5 using System;
6
7 /// <summary>
8 /// Update registration information for Binding.
9 /// </summary>
10 public class WixUpdateRegistrationRow : Row
11 {
12 /// <summary>
13 /// Creates a WixUpdateRegistrationRow row that does not belong to a table.
14 /// </summary>
15 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
16 /// <param name="tableDef">TableDefinition this WixUpdateRegistrationRow row belongs to and should get its column definitions from.</param>
17 public WixUpdateRegistrationRow(SourceLineNumber sourceLineNumbers, TableDefinition tableDef) :
18 base(sourceLineNumbers, tableDef)
19 {
20 }
21
22 /// <summary>
23 /// Creates a WixUpdateRegistrationRow row that belongs to a table.
24 /// </summary>
25 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
26 /// <param name="table">Table this WixUpdateRegistrationRow row belongs to and should get its column definitions from.</param>
27 public WixUpdateRegistrationRow(SourceLineNumber sourceLineNumbers, Table table) :
28 base(sourceLineNumbers, table)
29 {
30 }
31
32 public string Manufacturer
33 {
34 get { return (string)this.Fields[0].Data; }
35 set { this.Fields[0].Data = value; }
36 }
37
38 public string Department
39 {
40 get { return (string)this.Fields[1].Data; }
41 set { this.Fields[1].Data = value; }
42 }
43
44 public string ProductFamily
45 {
46 get { return (string)this.Fields[2].Data; }
47 set { this.Fields[2].Data = value; }
48 }
49
50 public string Name
51 {
52 get { return (string)this.Fields[3].Data; }
53 set { this.Fields[3].Data = value; }
54 }
55
56 public string Classification
57 {
58 get { return (string)this.Fields[4].Data; }
59 set { this.Fields[4].Data = value; }
60 }
61 }
62}
diff --git a/src/WixToolset.Data.WindowsInstaller/SubStorage.cs b/src/WixToolset.Data.WindowsInstaller/SubStorage.cs
new file mode 100644
index 00000000..e136bfe9
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/SubStorage.cs
@@ -0,0 +1,109 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System.Xml;
6
7 /// <summary>
8 /// Substorage inside an output.
9 /// </summary>
10 public sealed class SubStorage
11 {
12 /// <summary>
13 /// Instantiate a new substorage.
14 /// </summary>
15 /// <param name="name">The substorage name.</param>
16 /// <param name="data">The substorage data.</param>
17 public SubStorage(string name, Output data)
18 {
19 this.Name = name;
20 this.Data = data;
21 }
22
23 /// <summary>
24 /// Gets the substorage name.
25 /// </summary>
26 /// <value>The substorage name.</value>
27 public string Name { get; private set; }
28
29 /// <summary>
30 /// Gets the substorage data.
31 /// </summary>
32 /// <value>The substorage data.</value>
33 public Output Data { get; private set; }
34
35 /// <summary>
36 /// Creates a SubStorage from the XmlReader.
37 /// </summary>
38 /// <param name="reader">Reader to get data from.</param>
39 /// <returns>New SubStorage object.</returns>
40 internal static SubStorage Read(XmlReader reader)
41 {
42 if (!reader.LocalName.Equals("subStorage" == reader.LocalName))
43 {
44 throw new XmlException();
45 }
46
47 Output data = null;
48 bool empty = reader.IsEmptyElement;
49 string name = null;
50
51 while (reader.MoveToNextAttribute())
52 {
53 switch (reader.LocalName)
54 {
55 case "name":
56 name = reader.Value;
57 break;
58 }
59 }
60
61 if (!empty)
62 {
63 bool done = false;
64
65 while (!done && reader.Read())
66 {
67 switch (reader.NodeType)
68 {
69 case XmlNodeType.Element:
70 switch (reader.LocalName)
71 {
72 case "wixOutput":
73 data = Output.Read(reader, true);
74 break;
75 default:
76 throw new XmlException();
77 }
78 break;
79 case XmlNodeType.EndElement:
80 done = true;
81 break;
82 }
83 }
84
85 if (!done)
86 {
87 throw new XmlException();
88 }
89 }
90
91 return new SubStorage(name, data);
92 }
93
94 /// <summary>
95 /// Persists a SubStorage in an XML format.
96 /// </summary>
97 /// <param name="writer">XmlWriter where the SubStorage should persist itself as XML.</param>
98 internal void Write(XmlWriter writer)
99 {
100 writer.WriteStartElement("subStorage", Output.XmlNamespaceUri);
101
102 writer.WriteAttributeString("name", this.Name);
103
104 this.Data.Write(writer);
105
106 writer.WriteEndElement();
107 }
108 }
109}
diff --git a/src/WixToolset.Data.WindowsInstaller/Table.cs b/src/WixToolset.Data.WindowsInstaller/Table.cs
new file mode 100644
index 00000000..4c0df0ad
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Table.cs
@@ -0,0 +1,435 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.Diagnostics.CodeAnalysis;
9 using System.Globalization;
10 using System.IO;
11 using System.Text;
12 using System.Xml;
13 using WixToolset.Data.Rows;
14
15 /// <summary>
16 /// Object that represents a table in a database.
17 /// </summary>
18 public sealed class Table
19 {
20 /// <summary>
21 /// Creates a table in a section.
22 /// </summary>
23 /// <param name="section">Section to add table to.</param>
24 /// <param name="tableDefinition">Definition of the table.</param>
25 public Table(TableDefinition tableDefinition)
26 {
27 this.Definition = tableDefinition;
28 this.Rows = new List<Row>();
29 }
30
31 /// <summary>
32 /// Gets the table definition.
33 /// </summary>
34 /// <value>Definition of the table.</value>
35 public TableDefinition Definition { get; private set; }
36
37 /// <summary>
38 /// Gets the name of the table.
39 /// </summary>
40 /// <value>Name of the table.</value>
41 public string Name
42 {
43 get { return this.Definition.Name; }
44 }
45
46 /// <summary>
47 /// Gets or sets the table transform operation.
48 /// </summary>
49 /// <value>The table transform operation.</value>
50 public TableOperation Operation { get; set; }
51
52 /// <summary>
53 /// Gets the rows contained in the table.
54 /// </summary>
55 /// <value>Rows contained in the table.</value>
56 public IList<Row> Rows { get; private set; }
57
58 /// <summary>
59 /// Creates a new row in the table.
60 /// </summary>
61 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
62 /// <param name="add">Specifies whether to only create the row or add it to the table automatically.</param>
63 /// <returns>Row created in table.</returns>
64 public Row CreateRow(SourceLineNumber sourceLineNumbers, bool add = true)
65 {
66 Row row;
67
68 switch (this.Name)
69 {
70 case "BBControl":
71 row = new BBControlRow(sourceLineNumbers, this);
72 break;
73 case "WixBundlePackage":
74 row = new WixBundlePackageRow(sourceLineNumbers, this);
75 break;
76 case "WixBundleExePackage":
77 row = new WixBundleExePackageRow(sourceLineNumbers, this);
78 break;
79 case "WixBundleMsiPackage":
80 row = new WixBundleMsiPackageRow(sourceLineNumbers, this);
81 break;
82 case "WixBundleMspPackage":
83 row = new WixBundleMspPackageRow(sourceLineNumbers, this);
84 break;
85 case "WixBundleMsuPackage":
86 row = new WixBundleMsuPackageRow(sourceLineNumbers, this);
87 break;
88 case "Component":
89 row = new ComponentRow(sourceLineNumbers, this);
90 break;
91 case "WixBundleContainer":
92 row = new WixBundleContainerRow(sourceLineNumbers, this);
93 break;
94 case "Control":
95 row = new ControlRow(sourceLineNumbers, this);
96 break;
97 case "File":
98 row = new FileRow(sourceLineNumbers, this);
99 break;
100 case "WixBundleMsiFeature":
101 row = new WixBundleMsiFeatureRow(sourceLineNumbers, this);
102 break;
103 case "WixBundleMsiProperty":
104 row = new WixBundleMsiPropertyRow(sourceLineNumbers, this);
105 break;
106 case "Media":
107 row = new MediaRow(sourceLineNumbers, this);
108 break;
109 case "WixBundlePayload":
110 row = new WixBundlePayloadRow(sourceLineNumbers, this);
111 break;
112 case "Property":
113 row = new PropertyRow(sourceLineNumbers, this);
114 break;
115 case "WixRelatedBundle":
116 row = new WixRelatedBundleRow(sourceLineNumbers, this);
117 break;
118 case "WixBundleRelatedPackage":
119 row = new WixBundleRelatedPackageRow(sourceLineNumbers, this);
120 break;
121 case "WixBundleRollbackBoundary":
122 row = new WixBundleRollbackBoundaryRow(sourceLineNumbers, this);
123 break;
124 case "Upgrade":
125 row = new UpgradeRow(sourceLineNumbers, this);
126 break;
127 case "WixBundleVariable":
128 row = new WixBundleVariableRow(sourceLineNumbers, this);
129 break;
130 case "WixAction":
131 row = new WixActionRow(sourceLineNumbers, this);
132 break;
133 case "WixApprovedExeForElevation":
134 row = new WixApprovedExeForElevationRow(sourceLineNumbers, this);
135 break;
136 case "WixBundle":
137 row = new WixBundleRow(sourceLineNumbers, this);
138 break;
139 case "WixBundlePackageExitCode":
140 row = new WixBundlePackageExitCodeRow(sourceLineNumbers, this);
141 break;
142 case "WixBundlePatchTargetCode":
143 row = new WixBundlePatchTargetCodeRow(sourceLineNumbers, this);
144 break;
145 case "WixBundleSlipstreamMsp":
146 row = new WixBundleSlipstreamMspRow(sourceLineNumbers, this);
147 break;
148 case "WixBundleUpdate":
149 row = new WixBundleUpdateRow(sourceLineNumbers, this);
150 break;
151 case "WixBundleCatalog":
152 row = new WixBundleCatalogRow(sourceLineNumbers, this);
153 break;
154 case "WixChain":
155 row = new WixChainRow(sourceLineNumbers, this);
156 break;
157 case "WixChainItem":
158 row = new WixChainItemRow(sourceLineNumbers, this);
159 break;
160 case "WixBundlePackageCommandLine":
161 row = new WixBundlePackageCommandLineRow(sourceLineNumbers, this);
162 break;
163 case "WixComplexReference":
164 row = new WixComplexReferenceRow(sourceLineNumbers, this);
165 break;
166 case "WixDeltaPatchFile":
167 row = new WixDeltaPatchFileRow(sourceLineNumbers, this);
168 break;
169 case "WixDeltaPatchSymbolPaths":
170 row = new WixDeltaPatchSymbolPathsRow(sourceLineNumbers, this);
171 break;
172 case "WixFile":
173 row = new WixFileRow(sourceLineNumbers, this);
174 break;
175 case "WixGroup":
176 row = new WixGroupRow(sourceLineNumbers, this);
177 break;
178 case "WixMedia":
179 row = new WixMediaRow(sourceLineNumbers, this);
180 break;
181 case "WixMediaTemplate":
182 row = new WixMediaTemplateRow(sourceLineNumbers, this);
183 break;
184 case "WixMerge":
185 row = new WixMergeRow(sourceLineNumbers, this);
186 break;
187 case "WixPayloadProperties":
188 row = new WixPayloadPropertiesRow(sourceLineNumbers, this);
189 break;
190 case "WixProperty":
191 row = new WixPropertyRow(sourceLineNumbers, this);
192 break;
193 case "WixSimpleReference":
194 row = new WixSimpleReferenceRow(sourceLineNumbers, this);
195 break;
196 case "WixUpdateRegistration":
197 row = new WixUpdateRegistrationRow(sourceLineNumbers, this);
198 break;
199
200 default:
201 row = new Row(sourceLineNumbers, this);
202 break;
203 }
204
205 if (add)
206 {
207 this.Rows.Add(row);
208 }
209
210 return row;
211 }
212
213 /// <summary>
214 /// Parse a table from the xml.
215 /// </summary>
216 /// <param name="reader">XmlReader where the intermediate is persisted.</param>
217 /// <param name="section">Section to populate with persisted data.</param>
218 /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param>
219 /// <returns>The parsed table.</returns>
220 internal static Table Read(XmlReader reader, TableDefinitionCollection tableDefinitions)
221 {
222 Debug.Assert("table" == reader.LocalName);
223
224 bool empty = reader.IsEmptyElement;
225 TableOperation operation = TableOperation.None;
226 string name = null;
227
228 while (reader.MoveToNextAttribute())
229 {
230 switch (reader.LocalName)
231 {
232 case "name":
233 name = reader.Value;
234 break;
235 case "op":
236 switch (reader.Value)
237 {
238 case "add":
239 operation = TableOperation.Add;
240 break;
241 case "drop":
242 operation = TableOperation.Drop;
243 break;
244 default:
245 throw new XmlException();
246 }
247 break;
248 }
249 }
250
251 if (null == name)
252 {
253 throw new XmlException();
254 }
255
256 TableDefinition tableDefinition = tableDefinitions[name];
257 Table table = new Table(tableDefinition);
258 table.Operation = operation;
259
260 if (!empty)
261 {
262 bool done = false;
263
264 // loop through all the rows in a table
265 while (!done && reader.Read())
266 {
267 switch (reader.NodeType)
268 {
269 case XmlNodeType.Element:
270 switch (reader.LocalName)
271 {
272 case "row":
273 Row.Read(reader, table);
274 break;
275 default:
276 throw new XmlException();
277 }
278 break;
279 case XmlNodeType.EndElement:
280 done = true;
281 break;
282 }
283 }
284
285 if (!done)
286 {
287 throw new XmlException();
288 }
289 }
290
291 return table;
292 }
293
294 /// <summary>
295 /// Modularize the table.
296 /// </summary>
297 /// <param name="modularizationGuid">String containing the GUID of the Merge Module, if appropriate.</param>
298 /// <param name="suppressModularizationIdentifiers">Optional collection of identifiers that should not be modularized.</param>
299 public void Modularize(string modularizationGuid, ISet<string> suppressModularizationIdentifiers)
300 {
301 List<int> modularizedColumns = new List<int>();
302
303 // find the modularized columns
304 for (int i = 0; i < this.Definition.Columns.Count; i++)
305 {
306 if (ColumnModularizeType.None != this.Definition.Columns[i].ModularizeType)
307 {
308 modularizedColumns.Add(i);
309 }
310 }
311
312 if (0 < modularizedColumns.Count)
313 {
314 foreach (Row row in this.Rows)
315 {
316 foreach (int modularizedColumn in modularizedColumns)
317 {
318 Field field = row.Fields[modularizedColumn];
319
320 if (null != field.Data)
321 {
322 field.Data = row.GetModularizedValue(field, modularizationGuid, suppressModularizationIdentifiers);
323 }
324 }
325 }
326 }
327 }
328
329 /// <summary>
330 /// Persists a row in an XML format.
331 /// </summary>
332 /// <param name="writer">XmlWriter where the Row should persist itself as XML.</param>
333 [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Changing the way this string normalizes would result " +
334 "in a change to the way the intermediate files are generated, potentially causing extra churn in patches on an MSI built from an older version of WiX. " +
335 "Furthermore, there is no security hole here, as the strings won't need to make a round trip")]
336 internal void Write(XmlWriter writer)
337 {
338 if (null == writer)
339 {
340 throw new ArgumentNullException("writer");
341 }
342
343 writer.WriteStartElement("table", Intermediate.XmlNamespaceUri);
344 writer.WriteAttributeString("name", this.Name);
345
346 if (TableOperation.None != this.Operation)
347 {
348 writer.WriteAttributeString("op", this.Operation.ToString().ToLowerInvariant());
349 }
350
351 foreach (Row row in this.Rows)
352 {
353 row.Write(writer);
354 }
355
356 writer.WriteEndElement();
357 }
358
359 /// <summary>
360 /// Writes the table in IDT format to the provided stream.
361 /// </summary>
362 /// <param name="writer">Stream to write the table to.</param>
363 /// <param name="keepAddedColumns">Whether to keep columns added in a transform.</param>
364 public void ToIdtDefinition(StreamWriter writer, bool keepAddedColumns)
365 {
366 if (this.Definition.Unreal)
367 {
368 return;
369 }
370
371 if (TableDefinition.MaxColumnsInRealTable < this.Definition.Columns.Count)
372 {
373 throw new WixException(WixDataErrors.TooManyColumnsInRealTable(this.Definition.Name, this.Definition.Columns.Count, TableDefinition.MaxColumnsInRealTable));
374 }
375
376 // Tack on the table header, and flush before we start writing bytes directly to the stream.
377 writer.Write(this.Definition.ToIdtDefinition(keepAddedColumns));
378 writer.Flush();
379
380 using (var binary = new BinaryWriter(writer.BaseStream, writer.Encoding, true))
381 {
382 // Create an encoding that replaces characters with question marks, and doesn't throw. We'll
383 // use this in case of errors
384 Encoding convertEncoding = Encoding.GetEncoding(writer.Encoding.CodePage);
385
386 foreach (Row row in this.Rows)
387 {
388 if (row.Redundant)
389 {
390 continue;
391 }
392
393 string rowString = row.ToIdtDefinition(keepAddedColumns);
394 byte[] rowBytes;
395
396 try
397 {
398 // GetBytes will throw an exception if any character doesn't match our current encoding
399 rowBytes = writer.Encoding.GetBytes(rowString);
400 }
401 catch (EncoderFallbackException)
402 {
403 Messaging.Instance.OnMessage(WixDataErrors.InvalidStringForCodepage(row.SourceLineNumbers, Convert.ToString(writer.Encoding.WindowsCodePage, CultureInfo.InvariantCulture)));
404
405 rowBytes = convertEncoding.GetBytes(rowString);
406 }
407
408 binary.Write(rowBytes, 0, rowBytes.Length);
409 }
410 }
411 }
412
413 /// <summary>
414 /// Validates the rows of this OutputTable and throws if it collides on
415 /// primary keys.
416 /// </summary>
417 public void ValidateRows()
418 {
419 Dictionary<string, SourceLineNumber> primaryKeys = new Dictionary<string, SourceLineNumber>();
420
421 foreach (Row row in this.Rows)
422 {
423 string primaryKey = row.GetPrimaryKey();
424
425 SourceLineNumber collisionSourceLineNumber;
426 if (primaryKeys.TryGetValue(primaryKey, out collisionSourceLineNumber))
427 {
428 throw new WixException(WixDataErrors.DuplicatePrimaryKey(collisionSourceLineNumber, primaryKey, this.Definition.Name));
429 }
430
431 primaryKeys.Add(primaryKey, row.SourceLineNumbers);
432 }
433 }
434 }
435}
diff --git a/src/WixToolset.Data.WindowsInstaller/TableDefinition.cs b/src/WixToolset.Data.WindowsInstaller/TableDefinition.cs
new file mode 100644
index 00000000..40aaac84
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/TableDefinition.cs
@@ -0,0 +1,334 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Collections.ObjectModel;
8 using System.Text;
9 using System.Xml;
10
11 /// <summary>
12 /// Definition of a table in a database.
13 /// </summary>
14 public sealed class TableDefinition : IComparable<TableDefinition>
15 {
16 /// <summary>
17 /// Tracks the maximum number of columns supported in a real table.
18 /// This is a Windows Installer limitation.
19 /// </summary>
20 public const int MaxColumnsInRealTable = 32;
21
22 /// <summary>
23 /// Creates a table definition.
24 /// </summary>
25 /// <param name="name">Name of table to create.</param>
26 /// <param name="createSymbols">Flag if rows in this table create symbols.</param>
27 /// <param name="unreal">Flag if table is unreal.</param>
28 /// <param name="bootstrapperApplicationData">Flag if table is part of UX Manifest.</param>
29 public TableDefinition(string name, IList<ColumnDefinition> columns, bool createSymbols, bool unreal, bool bootstrapperApplicationData = false)
30 {
31 this.Name = name;
32 this.CreateSymbols = createSymbols;
33 this.Unreal = unreal;
34 this.BootstrapperApplicationData = bootstrapperApplicationData;
35
36 this.Columns = new ReadOnlyCollection<ColumnDefinition>(columns);
37 }
38
39 /// <summary>
40 /// Gets if rows in this table create symbols.
41 /// </summary>
42 /// <value>Flag if rows in this table create symbols.</value>
43 public bool CreateSymbols { get; private set; }
44
45 /// <summary>
46 /// Gets the name of the table.
47 /// </summary>
48 /// <value>Name of the table.</value>
49 public string Name { get; private set; }
50
51 /// <summary>
52 /// Gets if the table is unreal.
53 /// </summary>
54 /// <value>Flag if table is unreal.</value>
55 public bool Unreal { get; private set; }
56
57 /// <summary>
58 /// Gets if the table is a part of the bootstrapper application data manifest.
59 /// </summary>
60 /// <value>Flag if table is a part of the bootstrapper application data manifest.</value>
61 public bool BootstrapperApplicationData { get; private set; }
62
63 /// <summary>
64 /// Gets the collection of column definitions for this table.
65 /// </summary>
66 /// <value>Collection of column definitions for this table.</value>
67 public IList<ColumnDefinition> Columns { get; private set; }
68
69 /// <summary>
70 /// Gets the column definition in the table by index.
71 /// </summary>
72 /// <param name="columnIndex">Index of column to locate.</param>
73 /// <value>Column definition in the table by index.</value>
74 public ColumnDefinition this[int columnIndex]
75 {
76 get { return this.Columns[columnIndex]; }
77 }
78
79 /// <summary>
80 /// Gets the table definition in IDT format.
81 /// </summary>
82 /// <param name="keepAddedColumns">Whether to keep columns added in a transform.</param>
83 /// <returns>Table definition in IDT format.</returns>
84 public string ToIdtDefinition(bool keepAddedColumns)
85 {
86 bool first = true;
87 StringBuilder columnString = new StringBuilder();
88 StringBuilder dataString = new StringBuilder();
89 StringBuilder tableString = new StringBuilder();
90
91 tableString.Append(this.Name);
92 foreach (ColumnDefinition column in this.Columns)
93 {
94 // conditionally keep columns added in a transform; otherwise,
95 // break because columns can only be added at the end
96 if (column.Added && !keepAddedColumns)
97 {
98 break;
99 }
100
101 if (!first)
102 {
103 columnString.Append('\t');
104 dataString.Append('\t');
105 }
106
107 columnString.Append(column.Name);
108 dataString.Append(column.IdtType);
109
110 if (column.PrimaryKey)
111 {
112 tableString.AppendFormat("\t{0}", column.Name);
113 }
114
115 first = false;
116 }
117 columnString.Append("\r\n");
118 columnString.Append(dataString);
119 columnString.Append("\r\n");
120 columnString.Append(tableString);
121 columnString.Append("\r\n");
122
123 return columnString.ToString();
124 }
125
126 /// <summary>
127 /// Adds the validation rows to the _Validation table.
128 /// </summary>
129 /// <param name="validationTable">The _Validation table.</param>
130 public void AddValidationRows(Table validationTable)
131 {
132 foreach (ColumnDefinition columnDef in this.Columns)
133 {
134 Row row = validationTable.CreateRow(null);
135
136 row[0] = this.Name;
137
138 row[1] = columnDef.Name;
139
140 if (columnDef.Nullable)
141 {
142 row[2] = "Y";
143 }
144 else
145 {
146 row[2] = "N";
147 }
148
149 if (columnDef.IsMinValueSet)
150 {
151 row[3] = columnDef.MinValue;
152 }
153
154 if (columnDef.IsMaxValueSet)
155 {
156 row[4] = columnDef.MaxValue;
157 }
158
159 row[5] = columnDef.KeyTable;
160
161 if (columnDef.IsKeyColumnSet)
162 {
163 row[6] = columnDef.KeyColumn;
164 }
165
166 if (ColumnCategory.Unknown != columnDef.Category)
167 {
168 row[7] = columnDef.Category.ToString();
169 }
170
171 row[8] = columnDef.Possibilities;
172
173 row[9] = columnDef.Description;
174 }
175 }
176
177 /// <summary>
178 /// Compares this table definition to another table definition.
179 /// </summary>
180 /// <remarks>
181 /// Only Windows Installer traits are compared, allowing for updates to WiX-specific table definitions.
182 /// </remarks>
183 /// <param name="updated">The updated <see cref="TableDefinition"/> to compare with this target definition.</param>
184 /// <returns>0 if the tables' core properties are the same; otherwise, non-0.</returns>
185 public int CompareTo(TableDefinition updated)
186 {
187 // by definition, this object is greater than null
188 if (null == updated)
189 {
190 return 1;
191 }
192
193 // compare the table names
194 int ret = String.Compare(this.Name, updated.Name, StringComparison.Ordinal);
195
196 // compare the column count
197 if (0 == ret)
198 {
199 // transforms can only add columns
200 ret = Math.Min(0, updated.Columns.Count - this.Columns.Count);
201
202 // compare name, type, and length of each column
203 for (int i = 0; 0 == ret && this.Columns.Count > i; i++)
204 {
205 ColumnDefinition thisColumnDef = this.Columns[i];
206 ColumnDefinition updatedColumnDef = updated.Columns[i];
207
208 ret = thisColumnDef.CompareTo(updatedColumnDef);
209 }
210 }
211
212 return ret;
213 }
214
215 /// <summary>
216 /// Parses table definition from xml reader.
217 /// </summary>
218 /// <param name="reader">Reader to get data from.</param>
219 /// <returns>The TableDefintion represented by the Xml.</returns>
220 internal static TableDefinition Read(XmlReader reader)
221 {
222 bool empty = reader.IsEmptyElement;
223 bool createSymbols = false;
224 string name = null;
225 bool unreal = false;
226 bool bootstrapperApplicationData = false;
227
228 while (reader.MoveToNextAttribute())
229 {
230 switch (reader.LocalName)
231 {
232 case "createSymbols":
233 createSymbols = reader.Value.Equals("yes");
234 break;
235 case "name":
236 name = reader.Value;
237 break;
238 case "unreal":
239 unreal = reader.Value.Equals("yes");
240 break;
241 case "bootstrapperApplicationData":
242 bootstrapperApplicationData = reader.Value.Equals("yes");
243 break;
244 }
245 }
246
247 if (null == name)
248 {
249 throw new XmlException();
250 }
251
252 List<ColumnDefinition> columns = new List<ColumnDefinition>();
253 bool hasPrimaryKeyColumn = false;
254
255 // parse the child elements
256 if (!empty)
257 {
258 bool done = false;
259
260 while (!done && reader.Read())
261 {
262 switch (reader.NodeType)
263 {
264 case XmlNodeType.Element:
265 switch (reader.LocalName)
266 {
267 case "columnDefinition":
268 ColumnDefinition columnDefinition = ColumnDefinition.Read(reader);
269 columns.Add(columnDefinition);
270
271 if (columnDefinition.PrimaryKey)
272 {
273 hasPrimaryKeyColumn = true;
274 }
275 break;
276 default:
277 throw new XmlException();
278 }
279 break;
280 case XmlNodeType.EndElement:
281 done = true;
282 break;
283 }
284 }
285
286 if (!unreal && !bootstrapperApplicationData && !hasPrimaryKeyColumn)
287 {
288 throw new WixException(WixDataErrors.RealTableMissingPrimaryKeyColumn(SourceLineNumber.CreateFromUri(reader.BaseURI), name));
289 }
290
291 if (!done)
292 {
293 throw new XmlException();
294 }
295 }
296
297 TableDefinition tableDefinition = new TableDefinition(name, columns, createSymbols, unreal, bootstrapperApplicationData);
298 return tableDefinition;
299 }
300
301 /// <summary>
302 /// Persists an output in an XML format.
303 /// </summary>
304 /// <param name="writer">XmlWriter where the Output should persist itself as XML.</param>
305 internal void Write(XmlWriter writer)
306 {
307 writer.WriteStartElement("tableDefinition", TableDefinitionCollection.XmlNamespaceUri);
308
309 writer.WriteAttributeString("name", this.Name);
310
311 if (this.CreateSymbols)
312 {
313 writer.WriteAttributeString("createSymbols", "yes");
314 }
315
316 if (this.Unreal)
317 {
318 writer.WriteAttributeString("unreal", "yes");
319 }
320
321 if (this.BootstrapperApplicationData)
322 {
323 writer.WriteAttributeString("bootstrapperApplicationData", "yes");
324 }
325
326 foreach (ColumnDefinition columnDefinition in this.Columns)
327 {
328 columnDefinition.Write(writer);
329 }
330
331 writer.WriteEndElement();
332 }
333 }
334}
diff --git a/src/WixToolset.Data.WindowsInstaller/TableDefinitionCollection.cs b/src/WixToolset.Data.WindowsInstaller/TableDefinitionCollection.cs
new file mode 100644
index 00000000..553f0eaa
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/TableDefinitionCollection.cs
@@ -0,0 +1,229 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Collections;
7 using System.Collections.Generic;
8 using System.Linq;
9 using System.Xml;
10
11 /// <summary>
12 /// Collection for table definitions indexed by table name.
13 /// </summary>
14 public sealed class TableDefinitionCollection : ICollection<TableDefinition>
15 {
16 public const string XmlNamespaceUri = "http://wixtoolset.org/schemas/v4/wi/tables";
17
18 private Dictionary<string, TableDefinition> collection;
19
20 /// <summary>
21 /// Instantiate a new TableDefinitionCollection class.
22 /// </summary>
23 public TableDefinitionCollection()
24 {
25 this.collection = new Dictionary<string,TableDefinition>();
26 }
27
28 /// <summary>
29 /// Creates a shallow copy of the provided table definition collection.
30 /// </summary>
31 public TableDefinitionCollection(TableDefinitionCollection tableDefinitions)
32 {
33 this.collection = new Dictionary<string, TableDefinition>(tableDefinitions.collection);
34 }
35
36 /// <summary>
37 /// Gets the number of items in the collection.
38 /// </summary>
39 /// <value>Number of items in collection.</value>
40 public int Count
41 {
42 get { return this.collection.Count; }
43 }
44
45 /// <summary>
46 /// Table definition collections are never read-only.
47 /// </summary>
48 public bool IsReadOnly
49 {
50 get { return false; }
51 }
52
53 /// <summary>
54 /// Gets a table definition by name.
55 /// </summary>
56 /// <param name="tableName">Name of table to locate.</param>
57 public TableDefinition this[string tableName]
58 {
59 get
60 {
61 TableDefinition table;
62 if (!this.collection.TryGetValue(tableName, out table))
63 {
64 throw new WixMissingTableDefinitionException(WixDataErrors.MissingTableDefinition(tableName));
65 }
66
67 return table;
68 }
69 }
70
71 /// <summary>
72 /// Load a table definition collection from an XmlReader.
73 /// </summary>
74 /// <param name="reader">Reader to get data from.</param>
75 /// <param name="suppressSchema">Suppress xml schema validation while loading.</param>
76 /// <returns>The TableDefinitionCollection represented by the xml.</returns>
77 public static TableDefinitionCollection Load(XmlReader reader)
78 {
79 reader.MoveToContent();
80
81 return Read(reader);
82 }
83
84 /// <summary>
85 /// Adds a table definition to the collection.
86 /// </summary>
87 /// <param name="tableDefinition">Table definition to add to the collection.</param>
88 /// <value>Indexes by table definition name.</value>
89 public void Add(TableDefinition tableDefinition)
90 {
91 this.collection.Add(tableDefinition.Name, tableDefinition);
92 }
93
94 /// <summary>
95 /// Removes all table definitions from the collection.
96 /// </summary>
97 public void Clear()
98 {
99 this.collection.Clear();
100 }
101
102 /// <summary>
103 /// Checks if the collection contains a table name.
104 /// </summary>
105 /// <param name="tableName">The table to check in the collection.</param>
106 /// <returns>True if collection contains the table.</returns>
107 public bool Contains(string tableName)
108 {
109 return this.collection.ContainsKey(tableName);
110 }
111
112 /// <summary>
113 /// Checks if the collection contains a table.
114 /// </summary>
115 /// <param name="table">The table to check in the collection.</param>
116 /// <returns>True if collection contains the table.</returns>
117 public bool Contains(TableDefinition table)
118 {
119 return this.collection.ContainsKey(table.Name);
120 }
121
122 /// <summary>
123 /// Copies table definitions to an arry.
124 /// </summary>
125 /// <param name="array">Array to copy the table definitions to.</param>
126 /// <param name="index">Index in the array to start copying at.</param>
127 public void CopyTo(TableDefinition[] array, int index)
128 {
129 this.collection.Values.CopyTo(array, index);
130 }
131
132 /// <summary>
133 /// Removes a table definition from the collection.
134 /// </summary>
135 /// <param name="table">Table to remove from the collection.</param>
136 /// <returns>True if the table definition existed in the collection and was removed.</returns>
137 public bool Remove(TableDefinition table)
138 {
139 return this.collection.Remove(table.Name);
140 }
141
142 /// <summary>
143 /// Gets enumerator for the collection.
144 /// </summary>
145 /// <returns>Enumerator for the collection.</returns>
146 public IEnumerator<TableDefinition> GetEnumerator()
147 {
148 return this.collection.Values.GetEnumerator();
149 }
150
151 /// <summary>
152 /// Gets the untyped enumerator for the collection.
153 /// </summary>
154 /// <returns>Untyped enumerator for the collection.</returns>
155 IEnumerator IEnumerable.GetEnumerator()
156 {
157 return this.collection.Values.GetEnumerator();
158 }
159
160 /// <summary>
161 /// Loads a collection of table definitions from a XmlReader in memory.
162 /// </summary>
163 /// <param name="reader">Reader to get data from.</param>
164 /// <returns>The TableDefinitionCollection represented by the xml.</returns>
165 internal static TableDefinitionCollection Read(XmlReader reader)
166 {
167 if ("tableDefinitions" != reader.LocalName)
168 {
169 throw new XmlException();
170 }
171
172 bool empty = reader.IsEmptyElement;
173 TableDefinitionCollection tableDefinitionCollection = new TableDefinitionCollection();
174
175 while (reader.MoveToNextAttribute())
176 {
177 }
178
179 // parse the child elements
180 if (!empty)
181 {
182 bool done = false;
183
184 while (!done && reader.Read())
185 {
186 switch (reader.NodeType)
187 {
188 case XmlNodeType.Element:
189 switch (reader.LocalName)
190 {
191 case "tableDefinition":
192 tableDefinitionCollection.Add(TableDefinition.Read(reader));
193 break;
194 default:
195 throw new XmlException();
196 }
197 break;
198 case XmlNodeType.EndElement:
199 done = true;
200 break;
201 }
202 }
203
204 if (!done)
205 {
206 throw new XmlException();
207 }
208 }
209
210 return tableDefinitionCollection;
211 }
212
213 /// <summary>
214 /// Persists a TableDefinitionCollection in an XML format.
215 /// </summary>
216 /// <param name="writer">XmlWriter where the TableDefinitionCollection should persist itself as XML.</param>
217 internal void Write(XmlWriter writer)
218 {
219 writer.WriteStartElement("tableDefinitions", XmlNamespaceUri);
220
221 foreach (TableDefinition tableDefinition in this.collection.Values.OrderBy(t => t.Name))
222 {
223 tableDefinition.Write(writer);
224 }
225
226 writer.WriteEndElement();
227 }
228 }
229}
diff --git a/src/WixToolset.Data.WindowsInstaller/TableExtensions.cs b/src/WixToolset.Data.WindowsInstaller/TableExtensions.cs
new file mode 100644
index 00000000..1be64ffe
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/TableExtensions.cs
@@ -0,0 +1,23 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System.Collections.Generic;
6 using System.Linq;
7
8 /// <summary>
9 /// Methods that extend <see cref="Table"/>.
10 /// </summary>
11 public static class TableExtensions
12 {
13 /// <summary>
14 /// Gets the rows contained in the table as a particular row type.
15 /// </summary>
16 /// <param name="table">Table to get rows from.</param>
17 /// <remarks>If the <paramref name="table"/> is null, an empty enumerable will be returned.</remarks>
18 public static IEnumerable<T> RowsAs<T>(this Table table) where T : Row
19 {
20 return (null == table) ? Enumerable.Empty<T>() : table.Rows.Cast<T>();
21 }
22 }
23}
diff --git a/src/WixToolset.Data.WindowsInstaller/TableIndexedCollection.cs b/src/WixToolset.Data.WindowsInstaller/TableIndexedCollection.cs
new file mode 100644
index 00000000..9f85efff
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/TableIndexedCollection.cs
@@ -0,0 +1,153 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8
9 /// <summary>
10 /// Collection for tables.
11 /// </summary>
12 public sealed class TableIndexedCollection : ICollection<Table>
13 {
14 private Dictionary<string, Table> collection;
15
16 /// <summary>
17 /// Instantiate a new empty collection.
18 /// </summary>
19 public TableIndexedCollection()
20 {
21 this.collection = new Dictionary<string,Table>();
22 }
23
24 /// <summary>
25 /// Instantiate a new collection populated with a set of tables.
26 /// </summary>
27 /// <param name="tables">Set of tables.</param>
28 public TableIndexedCollection(IEnumerable<Table> tables)
29 {
30 this.collection = tables.ToDictionary(t => t.Name);
31 }
32
33 /// <summary>
34 /// Gets the number of items in the collection.
35 /// </summary>
36 /// <value>Number of items in collection.</value>
37 public int Count
38 {
39 get { return this.collection.Count; }
40 }
41
42 /// <summary>
43 /// Table indexed collection is never read only.
44 /// </summary>
45 public bool IsReadOnly
46 {
47 get { return false; }
48 }
49
50 /// <summary>
51 /// Adds a table to the collection.
52 /// </summary>
53 /// <param name="table">Table to add to the collection.</param>
54 /// <remarks>Indexes the table by name.</remarks>
55 public void Add(Table table)
56 {
57 this.collection.Add(table.Name, table);
58 }
59
60 /// <summary>
61 /// Clear the tables from the collection.
62 /// </summary>
63 public void Clear()
64 {
65 this.collection.Clear();
66 }
67
68 /// <summary>
69 /// Determines if a table is in the collection.
70 /// </summary>
71 /// <param name="table">Table to check if it is in the collection.</param>
72 /// <returns>True if the table name is in the collection, otherwise false.</returns>
73 public bool Contains(Table table)
74 {
75 return this.collection.ContainsKey(table.Name);
76 }
77
78 /// <summary>
79 /// Copies the collection into an array.
80 /// </summary>
81 /// <param name="array">Array to copy the collection into.</param>
82 /// <param name="arrayIndex">Index to start copying from.</param>
83 public void CopyTo(Table[] array, int arrayIndex)
84 {
85 this.collection.Values.CopyTo(array, arrayIndex);
86 }
87
88 /// <summary>
89 /// Remove a table from the collection by name.
90 /// </summary>
91 /// <param name="tableName">Table name to remove from the collection.</param>
92 public void Remove(string tableName)
93 {
94 this.collection.Remove(tableName);
95 }
96
97 /// <summary>
98 /// Remove a table from the collection.
99 /// </summary>
100 /// <param name="table">Table with matching name to remove from the collection.</param>
101 public bool Remove(Table table)
102 {
103 return this.collection.Remove(table.Name);
104 }
105
106 /// <summary>
107 /// Gets an enumerator over the whole collection.
108 /// </summary>
109 /// <returns>Collection enumerator.</returns>
110 public IEnumerator<Table> GetEnumerator()
111 {
112 return this.collection.Values.GetEnumerator();
113 }
114
115 /// <summary>
116 /// Gets an untyped enumerator over the whole collection.
117 /// </summary>
118 /// <returns>Untyped collection enumerator.</returns>
119 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
120 {
121 return this.collection.Values.GetEnumerator();
122 }
123
124 /// <summary>
125 /// Gets a table by name.
126 /// </summary>
127 /// <param name="tableName">Name of table to locate.</param>
128 public Table this[string tableName]
129 {
130 get
131 {
132 Table table;
133 return this.collection.TryGetValue(tableName, out table) ? table : null;
134 }
135
136 set
137 {
138 this.collection[tableName] = value;
139 }
140 }
141
142 /// <summary>
143 /// Tries to find a table by name.
144 /// </summary>
145 /// <param name="tableName">Table name to locate.</param>
146 /// <param name="table">Found table.</param>
147 /// <returns>True if table with table name was found, otherwise false.</returns>
148 public bool TryGetTable(string tableName, out Table table)
149 {
150 return this.collection.TryGetValue(tableName, out table);
151 }
152 }
153}
diff --git a/src/WixToolset.Data.WindowsInstaller/TableOperation.cs b/src/WixToolset.Data.WindowsInstaller/TableOperation.cs
new file mode 100644
index 00000000..8df44e73
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/TableOperation.cs
@@ -0,0 +1,25 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 /// <summary>
6 /// The table transform operations.
7 /// </summary>
8 public enum TableOperation
9 {
10 /// <summary>
11 /// No operation.
12 /// </summary>
13 None,
14
15 /// <summary>
16 /// Added table.
17 /// </summary>
18 Add,
19
20 /// <summary>
21 /// Dropped table.
22 /// </summary>
23 Drop,
24 }
25}
diff --git a/src/WixToolset.Data.WindowsInstaller/WindowsInstallerStandard.cs b/src/WixToolset.Data.WindowsInstaller/WindowsInstallerStandard.cs
new file mode 100644
index 00000000..ee4a5103
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/WindowsInstallerStandard.cs
@@ -0,0 +1,442 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System.Collections.Generic;
6 using System.Reflection;
7 using System.Xml;
8 using WixToolset.Data.Rows;
9
10 /// <summary>
11 /// Represents the Windows Installer standard objects.
12 /// </summary>
13 public static class WindowsInstallerStandard
14 {
15 private static readonly object lockObject = new object();
16
17 private static TableDefinitionCollection tableDefinitions;
18 private static WixActionRowCollection standardActions;
19
20 private static HashSet<string> standardActionNames;
21 private static HashSet<string> standardDirectories;
22 private static HashSet<string> standardProperties;
23
24 /// <summary>
25 /// Gets the table definitions stored in this assembly.
26 /// </summary>
27 /// <returns>Table definition collection for tables stored in this assembly.</returns>
28 public static TableDefinitionCollection GetTableDefinitions()
29 {
30 lock (lockObject)
31 {
32 if (null == WindowsInstallerStandard.tableDefinitions)
33 {
34 using (XmlReader reader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream("WixToolset.Data.WindowsInstaller.Data.tables.xml")))
35 {
36 tableDefinitions = TableDefinitionCollection.Load(reader);
37 }
38 }
39 }
40
41 return WindowsInstallerStandard.tableDefinitions;
42 }
43
44 /// <summary>
45 /// Gets the standard actions stored in this assembly.
46 /// </summary>
47 /// <returns>Collection of standard actions in this assembly.</returns>
48 public static WixActionRowCollection GetStandardActions()
49 {
50 lock (lockObject)
51 {
52 if (null == standardActions)
53 {
54 using (XmlReader reader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream("WixToolset.Data.WindowsInstaller.Data.actions.xml")))
55 {
56 standardActions = WixActionRowCollection.Load(reader);
57 }
58 }
59 }
60
61 return standardActions;
62 }
63
64 /// <summary>
65 /// Gets (and loads if not yet loaded) the list of standard MSI directories.
66 /// </summary>
67 /// <value>The list of standard MSI directories.</value>
68 public static HashSet<string> GetStandardDirectories()
69 {
70 lock (lockObject)
71 {
72 if (null == standardDirectories)
73 {
74 LoadStandardDirectories();
75 }
76 }
77
78 return standardDirectories;
79 }
80
81 /// <summary>
82 /// Find out if an action is a standard action.
83 /// </summary>
84 /// <param name="actionName">Name of the action.</param>
85 /// <returns>true if the action is standard, false otherwise.</returns>
86 public static bool IsStandardAction(string actionName)
87 {
88 lock (lockObject)
89 {
90 if (null == standardActionNames)
91 {
92 standardActionNames = new HashSet<string>();
93 standardActionNames.Add("AllocateRegistrySpace");
94 standardActionNames.Add("AppSearch");
95 standardActionNames.Add("BindImage");
96 standardActionNames.Add("CCPSearch");
97 standardActionNames.Add("CostFinalize");
98 standardActionNames.Add("CostInitialize");
99 standardActionNames.Add("CreateFolders");
100 standardActionNames.Add("CreateShortcuts");
101 standardActionNames.Add("DeleteServices");
102 standardActionNames.Add("DisableRollback");
103 standardActionNames.Add("DuplicateFiles");
104 standardActionNames.Add("ExecuteAction");
105 standardActionNames.Add("FileCost");
106 standardActionNames.Add("FindRelatedProducts");
107 standardActionNames.Add("ForceReboot");
108 standardActionNames.Add("InstallAdminPackage");
109 standardActionNames.Add("InstallExecute");
110 standardActionNames.Add("InstallExecuteAgain");
111 standardActionNames.Add("InstallFiles");
112 standardActionNames.Add("InstallFinalize");
113 standardActionNames.Add("InstallInitialize");
114 standardActionNames.Add("InstallODBC");
115 standardActionNames.Add("InstallServices");
116 standardActionNames.Add("InstallSFPCatalogFile");
117 standardActionNames.Add("InstallValidate");
118 standardActionNames.Add("IsolateComponents");
119 standardActionNames.Add("LaunchConditions");
120 standardActionNames.Add("MigrateFeatureStates");
121 standardActionNames.Add("MoveFiles");
122 standardActionNames.Add("MsiConfigureServices");
123 standardActionNames.Add("MsiPublishAssemblies");
124 standardActionNames.Add("MsiUnpublishAssemblies");
125 standardActionNames.Add("PatchFiles");
126 standardActionNames.Add("ProcessComponents");
127 standardActionNames.Add("PublishComponents");
128 standardActionNames.Add("PublishFeatures");
129 standardActionNames.Add("PublishProduct");
130 standardActionNames.Add("RegisterClassInfo");
131 standardActionNames.Add("RegisterComPlus");
132 standardActionNames.Add("RegisterExtensionInfo");
133 standardActionNames.Add("RegisterFonts");
134 standardActionNames.Add("RegisterMIMEInfo");
135 standardActionNames.Add("RegisterProduct");
136 standardActionNames.Add("RegisterProgIdInfo");
137 standardActionNames.Add("RegisterTypeLibraries");
138 standardActionNames.Add("RegisterUser");
139 standardActionNames.Add("RemoveDuplicateFiles");
140 standardActionNames.Add("RemoveEnvironmentStrings");
141 standardActionNames.Add("RemoveExistingProducts");
142 standardActionNames.Add("RemoveFiles");
143 standardActionNames.Add("RemoveFolders");
144 standardActionNames.Add("RemoveIniValues");
145 standardActionNames.Add("RemoveODBC");
146 standardActionNames.Add("RemoveRegistryValues");
147 standardActionNames.Add("RemoveShortcuts");
148 standardActionNames.Add("ResolveSource");
149 standardActionNames.Add("RMCCPSearch");
150 standardActionNames.Add("ScheduleReboot");
151 standardActionNames.Add("SelfRegModules");
152 standardActionNames.Add("SelfUnregModules");
153 standardActionNames.Add("SetODBCFolders");
154 standardActionNames.Add("StartServices");
155 standardActionNames.Add("StopServices");
156 standardActionNames.Add("UnpublishComponents");
157 standardActionNames.Add("UnpublishFeatures");
158 standardActionNames.Add("UnregisterClassInfo");
159 standardActionNames.Add("UnregisterComPlus");
160 standardActionNames.Add("UnregisterExtensionInfo");
161 standardActionNames.Add("UnregisterFonts");
162 standardActionNames.Add("UnregisterMIMEInfo");
163 standardActionNames.Add("UnregisterProgIdInfo");
164 standardActionNames.Add("UnregisterTypeLibraries");
165 standardActionNames.Add("ValidateProductID");
166 standardActionNames.Add("WriteEnvironmentStrings");
167 standardActionNames.Add("WriteIniValues");
168 standardActionNames.Add("WriteRegistryValues");
169 }
170 }
171
172 return standardActionNames.Contains(actionName);
173 }
174
175 /// <summary>
176 /// Find out if a directory is a standard directory.
177 /// </summary>
178 /// <param name="directoryName">Name of the directory.</param>
179 /// <returns>true if the directory is standard, false otherwise.</returns>
180 public static bool IsStandardDirectory(string directoryName)
181 {
182 lock (lockObject)
183 {
184 if (null == standardDirectories)
185 {
186 LoadStandardDirectories();
187 }
188 }
189
190 return standardDirectories.Contains(directoryName);
191 }
192
193 /// <summary>
194 /// Find out if a property is a standard property.
195 /// References:
196 /// Title: Property Reference [Windows Installer]:
197 /// URL: http://msdn.microsoft.com/library/en-us/msi/setup/property_reference.asp
198 /// </summary>
199 /// <param name="propertyName">Name of the property.</param>
200 /// <returns>true if a property is standard, false otherwise.</returns>
201 public static bool IsStandardProperty(string propertyName)
202 {
203 lock (lockObject)
204 {
205 if (null == standardProperties)
206 {
207 standardProperties = new HashSet<string>();
208 standardProperties.Add("~"); // REG_MULTI_SZ/NULL marker
209 standardProperties.Add("ACTION");
210 standardProperties.Add("ADDDEFAULT");
211 standardProperties.Add("ADDLOCAL");
212 standardProperties.Add("ADDDSOURCE");
213 standardProperties.Add("AdminProperties");
214 standardProperties.Add("AdminUser");
215 standardProperties.Add("ADVERTISE");
216 standardProperties.Add("AFTERREBOOT");
217 standardProperties.Add("AllowProductCodeMismatches");
218 standardProperties.Add("AllowProductVersionMajorMismatches");
219 standardProperties.Add("ALLUSERS");
220 standardProperties.Add("Alpha");
221 standardProperties.Add("ApiPatchingSymbolFlags");
222 standardProperties.Add("ARPAUTHORIZEDCDFPREFIX");
223 standardProperties.Add("ARPCOMMENTS");
224 standardProperties.Add("ARPCONTACT");
225 standardProperties.Add("ARPHELPLINK");
226 standardProperties.Add("ARPHELPTELEPHONE");
227 standardProperties.Add("ARPINSTALLLOCATION");
228 standardProperties.Add("ARPNOMODIFY");
229 standardProperties.Add("ARPNOREMOVE");
230 standardProperties.Add("ARPNOREPAIR");
231 standardProperties.Add("ARPPRODUCTIONICON");
232 standardProperties.Add("ARPREADME");
233 standardProperties.Add("ARPSIZE");
234 standardProperties.Add("ARPSYSTEMCOMPONENT");
235 standardProperties.Add("ARPULRINFOABOUT");
236 standardProperties.Add("ARPURLUPDATEINFO");
237 standardProperties.Add("AVAILABLEFREEREG");
238 standardProperties.Add("BorderSize");
239 standardProperties.Add("BorderTop");
240 standardProperties.Add("CaptionHeight");
241 standardProperties.Add("CCP_DRIVE");
242 standardProperties.Add("ColorBits");
243 standardProperties.Add("COMPADDLOCAL");
244 standardProperties.Add("COMPADDSOURCE");
245 standardProperties.Add("COMPANYNAME");
246 standardProperties.Add("ComputerName");
247 standardProperties.Add("CostingComplete");
248 standardProperties.Add("Date");
249 standardProperties.Add("DefaultUIFont");
250 standardProperties.Add("DISABLEADVTSHORTCUTS");
251 standardProperties.Add("DISABLEMEDIA");
252 standardProperties.Add("DISABLEROLLBACK");
253 standardProperties.Add("DiskPrompt");
254 standardProperties.Add("DontRemoveTempFolderWhenFinished");
255 standardProperties.Add("EnableUserControl");
256 standardProperties.Add("EXECUTEACTION");
257 standardProperties.Add("EXECUTEMODE");
258 standardProperties.Add("FASTOEM");
259 standardProperties.Add("FILEADDDEFAULT");
260 standardProperties.Add("FILEADDLOCAL");
261 standardProperties.Add("FILEADDSOURCE");
262 standardProperties.Add("IncludeWholeFilesOnly");
263 standardProperties.Add("Installed");
264 standardProperties.Add("INSTALLLEVEL");
265 standardProperties.Add("Intel");
266 standardProperties.Add("Intel64");
267 standardProperties.Add("IsAdminPackage");
268 standardProperties.Add("LeftUnit");
269 standardProperties.Add("LIMITUI");
270 standardProperties.Add("ListOfPatchGUIDsToReplace");
271 standardProperties.Add("ListOfTargetProductCode");
272 standardProperties.Add("LOGACTION");
273 standardProperties.Add("LogonUser");
274 standardProperties.Add("Manufacturer");
275 standardProperties.Add("MEDIAPACKAGEPATH");
276 standardProperties.Add("MediaSourceDir");
277 standardProperties.Add("MinimumRequiredMsiVersion");
278 standardProperties.Add("MsiAMD64");
279 standardProperties.Add("MSIAPRSETTINGSIDENTIFIER");
280 standardProperties.Add("MSICHECKCRCS");
281 standardProperties.Add("MSIDISABLERMRESTART");
282 standardProperties.Add("MSIENFORCEUPGRADECOMPONENTRULES");
283 standardProperties.Add("MSIFASTINSTALL");
284 standardProperties.Add("MsiFileToUseToCreatePatchTables");
285 standardProperties.Add("MsiHiddenProperties");
286 standardProperties.Add("MSIINSTALLPERUSER");
287 standardProperties.Add("MSIINSTANCEGUID");
288 standardProperties.Add("MsiLogFileLocation");
289 standardProperties.Add("MsiLogging");
290 standardProperties.Add("MsiNetAssemblySupport");
291 standardProperties.Add("MSINEWINSTANCE");
292 standardProperties.Add("MSINODISABLEMEDIA");
293 standardProperties.Add("MsiNTProductType");
294 standardProperties.Add("MsiNTSuiteBackOffice");
295 standardProperties.Add("MsiNTSuiteDataCenter");
296 standardProperties.Add("MsiNTSuiteEnterprise");
297 standardProperties.Add("MsiNTSuiteSmallBusiness");
298 standardProperties.Add("MsiNTSuiteSmallBusinessRestricted");
299 standardProperties.Add("MsiNTSuiteWebServer");
300 standardProperties.Add("MsiNTSuitePersonal");
301 standardProperties.Add("MsiPatchRemovalList");
302 standardProperties.Add("MSIPATCHREMOVE");
303 standardProperties.Add("MSIRESTARTMANAGERCONTROL");
304 standardProperties.Add("MsiRestartManagerSessionKey");
305 standardProperties.Add("MSIRMSHUTDOWN");
306 standardProperties.Add("MsiRunningElevated");
307 standardProperties.Add("MsiUIHideCancel");
308 standardProperties.Add("MsiUIProgressOnly");
309 standardProperties.Add("MsiUISourceResOnly");
310 standardProperties.Add("MsiSystemRebootPending");
311 standardProperties.Add("MsiWin32AssemblySupport");
312 standardProperties.Add("NOCOMPANYNAME");
313 standardProperties.Add("NOUSERNAME");
314 standardProperties.Add("OLEAdvtSupport");
315 standardProperties.Add("OptimizePatchSizeForLargeFiles");
316 standardProperties.Add("OriginalDatabase");
317 standardProperties.Add("OutOfDiskSpace");
318 standardProperties.Add("OutOfNoRbDiskSpace");
319 standardProperties.Add("ParentOriginalDatabase");
320 standardProperties.Add("ParentProductCode");
321 standardProperties.Add("PATCH");
322 standardProperties.Add("PATCH_CACHE_DIR");
323 standardProperties.Add("PATCH_CACHE_ENABLED");
324 standardProperties.Add("PatchGUID");
325 standardProperties.Add("PATCHNEWPACKAGECODE");
326 standardProperties.Add("PATCHNEWSUMMARYCOMMENTS");
327 standardProperties.Add("PATCHNEWSUMMARYSUBJECT");
328 standardProperties.Add("PatchOutputPath");
329 standardProperties.Add("PatchSourceList");
330 standardProperties.Add("PhysicalMemory");
331 standardProperties.Add("PIDKEY");
332 standardProperties.Add("PIDTemplate");
333 standardProperties.Add("Preselected");
334 standardProperties.Add("PRIMARYFOLDER");
335 standardProperties.Add("PrimaryVolumePath");
336 standardProperties.Add("PrimaryVolumeSpaceAvailable");
337 standardProperties.Add("PrimaryVolumeSpaceRemaining");
338 standardProperties.Add("PrimaryVolumeSpaceRequired");
339 standardProperties.Add("Privileged");
340 standardProperties.Add("ProductCode");
341 standardProperties.Add("ProductID");
342 standardProperties.Add("ProductLanguage");
343 standardProperties.Add("ProductName");
344 standardProperties.Add("ProductState");
345 standardProperties.Add("ProductVersion");
346 standardProperties.Add("PROMPTROLLBACKCOST");
347 standardProperties.Add("REBOOT");
348 standardProperties.Add("REBOOTPROMPT");
349 standardProperties.Add("RedirectedDllSupport");
350 standardProperties.Add("REINSTALL");
351 standardProperties.Add("REINSTALLMODE");
352 standardProperties.Add("RemoveAdminTS");
353 standardProperties.Add("REMOVE");
354 standardProperties.Add("ReplacedInUseFiles");
355 standardProperties.Add("RestrictedUserControl");
356 standardProperties.Add("RESUME");
357 standardProperties.Add("RollbackDisabled");
358 standardProperties.Add("ROOTDRIVE");
359 standardProperties.Add("ScreenX");
360 standardProperties.Add("ScreenY");
361 standardProperties.Add("SecureCustomProperties");
362 standardProperties.Add("ServicePackLevel");
363 standardProperties.Add("ServicePackLevelMinor");
364 standardProperties.Add("SEQUENCE");
365 standardProperties.Add("SharedWindows");
366 standardProperties.Add("ShellAdvtSupport");
367 standardProperties.Add("SHORTFILENAMES");
368 standardProperties.Add("SourceDir");
369 standardProperties.Add("SOURCELIST");
370 standardProperties.Add("SystemLanguageID");
371 standardProperties.Add("TARGETDIR");
372 standardProperties.Add("TerminalServer");
373 standardProperties.Add("TextHeight");
374 standardProperties.Add("Time");
375 standardProperties.Add("TRANSFORMS");
376 standardProperties.Add("TRANSFORMSATSOURCE");
377 standardProperties.Add("TRANSFORMSSECURE");
378 standardProperties.Add("TTCSupport");
379 standardProperties.Add("UILevel");
380 standardProperties.Add("UpdateStarted");
381 standardProperties.Add("UpgradeCode");
382 standardProperties.Add("UPGRADINGPRODUCTCODE");
383 standardProperties.Add("UserLanguageID");
384 standardProperties.Add("USERNAME");
385 standardProperties.Add("UserSID");
386 standardProperties.Add("Version9X");
387 standardProperties.Add("VersionDatabase");
388 standardProperties.Add("VersionMsi");
389 standardProperties.Add("VersionNT");
390 standardProperties.Add("VersionNT64");
391 standardProperties.Add("VirtualMemory");
392 standardProperties.Add("WindowsBuild");
393 standardProperties.Add("WindowsVolume");
394 }
395 }
396
397 return standardProperties.Contains(propertyName);
398 }
399
400 /// <summary>
401 /// Sets up a hashtable with the set of standard MSI directories
402 /// </summary>
403 private static void LoadStandardDirectories()
404 {
405 lock (lockObject)
406 {
407 if (null == standardDirectories)
408 {
409 standardDirectories = new HashSet<string>();
410 standardDirectories.Add("TARGETDIR");
411 standardDirectories.Add("AdminToolsFolder");
412 standardDirectories.Add("AppDataFolder");
413 standardDirectories.Add("CommonAppDataFolder");
414 standardDirectories.Add("CommonFilesFolder");
415 standardDirectories.Add("DesktopFolder");
416 standardDirectories.Add("FavoritesFolder");
417 standardDirectories.Add("FontsFolder");
418 standardDirectories.Add("LocalAppDataFolder");
419 standardDirectories.Add("MyPicturesFolder");
420 standardDirectories.Add("PersonalFolder");
421 standardDirectories.Add("ProgramFilesFolder");
422 standardDirectories.Add("ProgramMenuFolder");
423 standardDirectories.Add("SendToFolder");
424 standardDirectories.Add("StartMenuFolder");
425 standardDirectories.Add("StartupFolder");
426 standardDirectories.Add("System16Folder");
427 standardDirectories.Add("SystemFolder");
428 standardDirectories.Add("TempFolder");
429 standardDirectories.Add("TemplateFolder");
430 standardDirectories.Add("WindowsFolder");
431 standardDirectories.Add("CommonFiles64Folder");
432 standardDirectories.Add("ProgramFiles64Folder");
433 standardDirectories.Add("System64Folder");
434 standardDirectories.Add("NetHoodFolder");
435 standardDirectories.Add("PrintHoodFolder");
436 standardDirectories.Add("RecentFolder");
437 standardDirectories.Add("WindowsVolume");
438 }
439 }
440 }
441 }
442}
diff --git a/src/WixToolset.Data.WindowsInstaller/WixInvalidIdtException.cs b/src/WixToolset.Data.WindowsInstaller/WixInvalidIdtException.cs
new file mode 100644
index 00000000..33fd0591
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/WixInvalidIdtException.cs
@@ -0,0 +1,32 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6
7 /// <summary>
8 /// WiX invalid idt exception.
9 /// </summary>
10 [Serializable]
11 public sealed class WixInvalidIdtException : WixException
12 {
13 /// <summary>
14 /// Instantiate a new WixInvalidIdtException.
15 /// </summary>
16 /// <param name="idtFile">The invalid idt file.</param>
17 public WixInvalidIdtException(string idtFile) :
18 base(WixDataErrors.InvalidIdt(new SourceLineNumber(idtFile), idtFile))
19 {
20 }
21
22 /// <summary>
23 /// Instantiate a new WixInvalidIdtException.
24 /// </summary>
25 /// <param name="idtFile">The invalid idt file.</param>
26 /// <param name="tableName">The table name of the invalid idt file.</param>
27 public WixInvalidIdtException(string idtFile, string tableName) :
28 base(WixDataErrors.InvalidIdt(new SourceLineNumber(idtFile), idtFile, tableName))
29 {
30 }
31 }
32}
diff --git a/src/WixToolset.Data.WindowsInstaller/WixMissingTableDefinitionException.cs b/src/WixToolset.Data.WindowsInstaller/WixMissingTableDefinitionException.cs
new file mode 100644
index 00000000..6295813b
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/WixMissingTableDefinitionException.cs
@@ -0,0 +1,22 @@
1// 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.
2
3namespace WixToolset.Data
4{
5 using System;
6
7 /// <summary>
8 /// Exception thrown when a table definition is missing.
9 /// </summary>
10 [Serializable]
11 public class WixMissingTableDefinitionException : WixException
12 {
13 /// <summary>
14 /// Instantiate new WixMissingTableDefinitionException.
15 /// </summary>
16 /// <param name="error">Localized error information.</param>
17 public WixMissingTableDefinitionException(MessageEventArgs error)
18 : base(error)
19 {
20 }
21 }
22}
diff --git a/src/WixToolset.Data.WindowsInstaller/WixToolset.Data.WindowsInstaller.csproj b/src/WixToolset.Data.WindowsInstaller/WixToolset.Data.WindowsInstaller.csproj
new file mode 100644
index 00000000..bd8140c3
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/WixToolset.Data.WindowsInstaller.csproj
@@ -0,0 +1,27 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFramework>netstandard2.0</TargetFramework>
7 <Description>Data for Windows Installer</Description>
8 <Title>WiX Toolset Data Windows Installer</Title>
9 </PropertyGroup>
10
11 <ItemGroup>
12 <EmbeddedResource Include="Data\actions.xml" />
13 <EmbeddedResource Include="Data\tables.xml" />
14 </ItemGroup>
15
16 <ItemGroup>
17 <ProjectReference Include="$(WixToolsetRootFolder)\Data\src\WixToolset.Data\WixToolset.Data.csproj" Condition=" '$(Configuration)' == 'Debug' And Exists('$(WixToolsetRootFolder)\Data\src\WixToolset.Data\WixToolset.Data.csproj') " />
18 <PackageReference Include="WixToolset.Data" Version="4.0.*" Condition=" '$(Configuration)' == 'Release' Or !Exists('$(WixToolsetRootFolder)\Data\src\WixToolset.Data\WixToolset.Data.csproj') " />
19
20 <ProjectReference Include="$(WixToolsetRootFolder)\Extensibility\src\WixToolset.Extensibility\WixToolset.Extensibility.csproj" Condition=" '$(Configuration)' == 'Debug' And Exists('$(WixToolsetRootFolder)\Extensibility\src\WixToolset.Extensibility\WixToolset.Extensibility.csproj') " />
21 <PackageReference Include="WixToolset.Extensibility" Version="4.0.*" Condition=" '$(Configuration)' == 'Release' Or !Exists('$(WixToolsetRootFolder)\Extensibility\src\WixToolset.Extensibility\WixToolset.Extensibility.csproj') " />
22 </ItemGroup>
23
24 <ItemGroup>
25 <PackageReference Include="Nerdbank.GitVersioning" Version="2.0.41" PrivateAssets="all" />
26 </ItemGroup>
27</Project>
diff --git a/src/test/WixToolsetTest.CoreIntegrationFixture/ProgramFixture.cs b/src/test/WixToolsetTest.CoreIntegrationFixture/ProgramFixture.cs
index daa3da42..46d15ed8 100644
--- a/src/test/WixToolsetTest.CoreIntegrationFixture/ProgramFixture.cs
+++ b/src/test/WixToolsetTest.CoreIntegrationFixture/ProgramFixture.cs
@@ -3,7 +3,10 @@
3namespace WixToolsetTest.CoreIntegrationFixture 3namespace WixToolsetTest.CoreIntegrationFixture
4{ 4{
5 using System.IO; 5 using System.IO;
6 using System.Linq;
6 using WixToolset.Core; 7 using WixToolset.Core;
8 using WixToolset.Data;
9 using WixToolset.Data.Tuples;
7 using WixToolsetTest.CoreIntegrationFixture.Utility; 10 using WixToolsetTest.CoreIntegrationFixture.Utility;
8 using Xunit; 11 using Xunit;
9 12
@@ -23,9 +26,18 @@ namespace WixToolsetTest.CoreIntegrationFixture
23 var result = program.Run(new WixToolsetServiceProvider(), new[] { "build", "Package.wxs", "PackageComponents.wxs", "-loc", "Package.en-us.wxl", "-bindpath", "data", "-intermediateFolder", intermediateFolder, "-o", $@"{intermediateFolder}\bin\test.msi" }); 26 var result = program.Run(new WixToolsetServiceProvider(), new[] { "build", "Package.wxs", "PackageComponents.wxs", "-loc", "Package.en-us.wxl", "-bindpath", "data", "-intermediateFolder", intermediateFolder, "-o", $@"{intermediateFolder}\bin\test.msi" });
24 27
25 Assert.Equal(0, result); 28 Assert.Equal(0, result);
29#if FIXED_MSI_BACKEND
26 Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\test.msi"))); 30 Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\test.msi")));
27 Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\test.wixpdb"))); 31 Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\test.wixpdb")));
28 Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\MsiPackage\test.txt"))); 32 Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\MsiPackage\test.txt")));
33#else
34 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"bin\test.msi"));
35 Assert.Single(intermediate.Sections);
36
37 var wixFile = intermediate.Sections.SelectMany(s => s.Tuples).OfType<WixFileTuple>().Single();
38 Assert.Equal(@"data\test.txt", wixFile[WixFileTupleFields.Source].AsPath().Path);
39 Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path);
40#endif
29 } 41 }
30 } 42 }
31 } 43 }