diff options
9 files changed, 338 insertions, 422 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs index 7a64b777..292f1572 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs | |||
@@ -192,6 +192,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
192 | command.Execute(); | 192 | command.Execute(); |
193 | } | 193 | } |
194 | 194 | ||
195 | if (section.Type == SectionType.Product || section.Type == SectionType.Module) | ||
195 | { | 196 | { |
196 | var command = new AddRequiredStandardDirectories(section, platform); | 197 | var command = new AddRequiredStandardDirectories(section, platform); |
197 | command.Execute(); | 198 | command.Execute(); |
@@ -329,7 +330,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
329 | 330 | ||
330 | if (dependencyRefs.Any()) | 331 | if (dependencyRefs.Any()) |
331 | { | 332 | { |
332 | var command = new ProcessDependencyReferencesCommand(this.WindowsInstallerBackendHelper, section, dependencyRefs); | 333 | var command = new ProcessDependencyReferencesCommand(section, dependencyRefs); |
333 | command.Execute(); | 334 | command.Execute(); |
334 | } | 335 | } |
335 | } | 336 | } |
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs index dc60a9ac..9ec26964 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs | |||
@@ -25,6 +25,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
25 | this.TableDefinitions = tableDefinitions; | 25 | this.TableDefinitions = tableDefinitions; |
26 | this.BackendExtensions = backendExtensions; | 26 | this.BackendExtensions = backendExtensions; |
27 | this.BackendHelper = backendHelper; | 27 | this.BackendHelper = backendHelper; |
28 | this.GeneratedShortNames = new Dictionary<string, List<FileSymbol>>(); | ||
28 | } | 29 | } |
29 | 30 | ||
30 | private IEnumerable<IWindowsInstallerBackendBinderExtension> BackendExtensions { get; } | 31 | private IEnumerable<IWindowsInstallerBackendBinderExtension> BackendExtensions { get; } |
@@ -37,6 +38,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
37 | 38 | ||
38 | private IntermediateSection Section { get; } | 39 | private IntermediateSection Section { get; } |
39 | 40 | ||
41 | private Dictionary<string, List<FileSymbol>> GeneratedShortNames { get; } | ||
42 | |||
40 | public WindowsInstallerData Data { get; private set; } | 43 | public WindowsInstallerData Data { get; private set; } |
41 | 44 | ||
42 | public WindowsInstallerData Execute() | 45 | public WindowsInstallerData Execute() |
@@ -136,6 +139,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
136 | 139 | ||
137 | case SymbolDefinitionType.ModuleConfiguration: | 140 | case SymbolDefinitionType.ModuleConfiguration: |
138 | this.AddModuleConfigurationSymbol((ModuleConfigurationSymbol)symbol); | 141 | this.AddModuleConfigurationSymbol((ModuleConfigurationSymbol)symbol); |
142 | this.EnsureModuleIgnoredTable(symbol, "ModuleConfiguration"); | ||
143 | break; | ||
144 | |||
145 | case SymbolDefinitionType.ModuleSubstitution: | ||
146 | this.EnsureModuleIgnoredTable(symbol, "ModuleSubstitution"); | ||
139 | break; | 147 | break; |
140 | 148 | ||
141 | case SymbolDefinitionType.MsiEmbeddedUI: | 149 | case SymbolDefinitionType.MsiEmbeddedUI: |
@@ -262,6 +270,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
262 | } | 270 | } |
263 | 271 | ||
264 | this.AddIndexedCellSymbols(cellsByTableAndRowId); | 272 | this.AddIndexedCellSymbols(cellsByTableAndRowId); |
273 | this.EnsureRequiredTables(); | ||
274 | this.ReportGeneratedShortFileNameConflicts(); | ||
275 | this.ReportIllegalTables(); | ||
276 | this.ReportMismatchedModularizations(); | ||
277 | this.ReportWindowsInstallerDataInconsistencies(); | ||
265 | } | 278 | } |
266 | 279 | ||
267 | private void AddAssemblySymbol(AssemblySymbol symbol) | 280 | private void AddAssemblySymbol(AssemblySymbol symbol) |
@@ -426,6 +439,15 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
426 | row[2] = symbol.Source; | 439 | row[2] = symbol.Source; |
427 | row[3] = symbol.Target; | 440 | row[3] = symbol.Target; |
428 | row[4] = symbol.PatchUninstall ? (int?)WindowsInstallerConstants.MsidbCustomActionTypePatchUninstall : null; | 441 | row[4] = symbol.PatchUninstall ? (int?)WindowsInstallerConstants.MsidbCustomActionTypePatchUninstall : null; |
442 | |||
443 | if (OutputType.Module == this.Data.Type) | ||
444 | { | ||
445 | this.Data.EnsureTable(this.TableDefinitions["AdminExecuteSequence"]); | ||
446 | this.Data.EnsureTable(this.TableDefinitions["AdminUISequence"]); | ||
447 | this.Data.EnsureTable(this.TableDefinitions["AdvtExecuteSequence"]); | ||
448 | this.Data.EnsureTable(this.TableDefinitions["InstallExecuteSequence"]); | ||
449 | this.Data.EnsureTable(this.TableDefinitions["InstallUISequence"]); | ||
450 | } | ||
429 | } | 451 | } |
430 | 452 | ||
431 | private void AddDialogSymbol(DialogSymbol symbol) | 453 | private void AddDialogSymbol(DialogSymbol symbol) |
@@ -483,6 +505,38 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
483 | row[0] = symbol.Id.Id; | 505 | row[0] = symbol.Id.Id; |
484 | row[1] = symbol.ParentDirectoryRef; | 506 | row[1] = symbol.ParentDirectoryRef; |
485 | row[2] = defaultDir; | 507 | row[2] = defaultDir; |
508 | |||
509 | if (OutputType.Module == this.Data.Type) | ||
510 | { | ||
511 | var directoryId = symbol.Id.Id; | ||
512 | |||
513 | if (WindowsInstallerStandard.IsStandardDirectory(directoryId)) | ||
514 | { | ||
515 | // If the directory table contains references to standard windows folders | ||
516 | // mergemod.dll will add customactions to set the MSM directory to | ||
517 | // the same directory as the standard windows folder and will add references to | ||
518 | // custom action to all the standard sequence tables. A problem will occur | ||
519 | // if the MSI does not have these tables as mergemod.dll does not add these | ||
520 | // tables to the MSI if absent. This code adds the tables in case mergemod.dll | ||
521 | // needs them. | ||
522 | this.Data.EnsureTable(this.TableDefinitions["CustomAction"]); | ||
523 | this.Data.EnsureTable(this.TableDefinitions["AdminExecuteSequence"]); | ||
524 | this.Data.EnsureTable(this.TableDefinitions["AdminUISequence"]); | ||
525 | this.Data.EnsureTable(this.TableDefinitions["AdvtExecuteSequence"]); | ||
526 | this.Data.EnsureTable(this.TableDefinitions["InstallExecuteSequence"]); | ||
527 | this.Data.EnsureTable(this.TableDefinitions["InstallUISequence"]); | ||
528 | } | ||
529 | else | ||
530 | { | ||
531 | foreach (var standardDirectory in WindowsInstallerStandard.StandardDirectories()) | ||
532 | { | ||
533 | if (directoryId.StartsWith(standardDirectory.Id.Id, StringComparison.Ordinal)) | ||
534 | { | ||
535 | this.Messaging.Write(WarningMessages.StandardDirectoryConflictInMergeModule(symbol.SourceLineNumbers, directoryId, standardDirectory.Id.Id)); | ||
536 | } | ||
537 | } | ||
538 | } | ||
539 | } | ||
486 | } | 540 | } |
487 | 541 | ||
488 | private void AddDuplicateFileSymbol(DuplicateFileSymbol symbol) | 542 | private void AddDuplicateFileSymbol(DuplicateFileSymbol symbol) |
@@ -570,6 +624,14 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
570 | if (null == symbol.ShortName && null != name && !Common.IsValidShortFilename(name, false)) | 624 | if (null == symbol.ShortName && null != name && !Common.IsValidShortFilename(name, false)) |
571 | { | 625 | { |
572 | symbol.ShortName = CreateShortName(name, true, false, "File", symbol.DirectoryRef); | 626 | symbol.ShortName = CreateShortName(name, true, false, "File", symbol.DirectoryRef); |
627 | |||
628 | if (!this.GeneratedShortNames.TryGetValue(symbol.ShortName, out var potentialConflicts)) | ||
629 | { | ||
630 | potentialConflicts = new List<FileSymbol>(); | ||
631 | this.GeneratedShortNames.Add(symbol.ShortName, potentialConflicts); | ||
632 | } | ||
633 | |||
634 | potentialConflicts.Add(symbol); | ||
573 | } | 635 | } |
574 | 636 | ||
575 | var row = (FileRow)this.CreateRow(symbol, "File"); | 637 | var row = (FileRow)this.CreateRow(symbol, "File"); |
@@ -612,7 +674,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
612 | var tableName = (IniFileActionType.AddLine == symbol.Action || IniFileActionType.AddTag == symbol.Action || IniFileActionType.CreateLine == symbol.Action) ? "IniFile" : "RemoveIniFile"; | 674 | var tableName = (IniFileActionType.AddLine == symbol.Action || IniFileActionType.AddTag == symbol.Action || IniFileActionType.CreateLine == symbol.Action) ? "IniFile" : "RemoveIniFile"; |
613 | 675 | ||
614 | var name = symbol.FileName; | 676 | var name = symbol.FileName; |
615 | if (null == symbol.ShortFileName && null != name && !Common.IsValidShortFilename(name, false)) | 677 | if (null == symbol.ShortFileName && null != name && !Common.IsValidShortFilename(name, false)) |
616 | { | 678 | { |
617 | symbol.ShortFileName = CreateShortName(name, true, false, "IniFile", symbol.ComponentRef); | 679 | symbol.ShortFileName = CreateShortName(name, true, false, "IniFile", symbol.ComponentRef); |
618 | } | 680 | } |
@@ -1168,6 +1230,238 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
1168 | private bool AddSymbolDefaultly(IntermediateSymbol symbol) => | 1230 | private bool AddSymbolDefaultly(IntermediateSymbol symbol) => |
1169 | this.BackendHelper.TryAddSymbolToMatchingTableDefinitions(this.Section, symbol, this.Data, this.TableDefinitions); | 1231 | this.BackendHelper.TryAddSymbolToMatchingTableDefinitions(this.Section, symbol, this.Data, this.TableDefinitions); |
1170 | 1232 | ||
1233 | private void EnsureModuleIgnoredTable(IntermediateSymbol symbol, string ignoredTable) | ||
1234 | { | ||
1235 | var tableDefinition = this.TableDefinitions["ModuleIgnoreTable"]; | ||
1236 | var table = this.Data.EnsureTable(tableDefinition); | ||
1237 | if (!table.Rows.Any(r => r.FieldAsString(0) == ignoredTable)) | ||
1238 | { | ||
1239 | var row = this.CreateRow(symbol, tableDefinition); | ||
1240 | row[0] = ignoredTable; | ||
1241 | } | ||
1242 | } | ||
1243 | |||
1244 | private void EnsureRequiredTables() | ||
1245 | { | ||
1246 | // check for missing table and add them or display an error as appropriate | ||
1247 | switch (this.Data.Type) | ||
1248 | { | ||
1249 | case OutputType.Module: | ||
1250 | this.Data.EnsureTable(this.TableDefinitions["Component"]); | ||
1251 | this.Data.EnsureTable(this.TableDefinitions["Directory"]); | ||
1252 | this.Data.EnsureTable(this.TableDefinitions["FeatureComponents"]); | ||
1253 | this.Data.EnsureTable(this.TableDefinitions["File"]); | ||
1254 | this.Data.EnsureTable(this.TableDefinitions["ModuleComponents"]); | ||
1255 | this.Data.EnsureTable(this.TableDefinitions["ModuleSignature"]); | ||
1256 | break; | ||
1257 | |||
1258 | case OutputType.PatchCreation: | ||
1259 | var imageFamiliesCount = this.Data.Tables["ImageFamilies"]?.Rows.Count ?? 0; | ||
1260 | var targetImagesCount = this.Data.Tables["TargetImages"]?.Rows.Count ?? 0; | ||
1261 | var upgradedImagesCount = this.Data.Tables["UpgradedImages"]?.Rows.Count ?? 0; | ||
1262 | |||
1263 | if (imageFamiliesCount < 1) | ||
1264 | { | ||
1265 | this.Messaging.Write(ErrorMessages.ExpectedRowInPatchCreationPackage("ImageFamilies")); | ||
1266 | } | ||
1267 | |||
1268 | if (targetImagesCount < 1) | ||
1269 | { | ||
1270 | this.Messaging.Write(ErrorMessages.ExpectedRowInPatchCreationPackage("TargetImages")); | ||
1271 | } | ||
1272 | |||
1273 | if (upgradedImagesCount < 1) | ||
1274 | { | ||
1275 | this.Messaging.Write(ErrorMessages.ExpectedRowInPatchCreationPackage("UpgradedImages")); | ||
1276 | } | ||
1277 | |||
1278 | this.Data.EnsureTable(this.TableDefinitions["Properties"]); | ||
1279 | break; | ||
1280 | |||
1281 | case OutputType.Product: | ||
1282 | this.Data.EnsureTable(this.TableDefinitions["File"]); | ||
1283 | this.Data.EnsureTable(this.TableDefinitions["Media"]); | ||
1284 | break; | ||
1285 | } | ||
1286 | } | ||
1287 | |||
1288 | private void ReportGeneratedShortFileNameConflicts() | ||
1289 | { | ||
1290 | foreach (var conflicts in this.GeneratedShortNames.Values.Where(l => l.Count > 1)) | ||
1291 | { | ||
1292 | this.Messaging.Write(WarningMessages.GeneratedShortFileNameConflict(conflicts[0].SourceLineNumbers, conflicts[0].ShortName)); | ||
1293 | for (var i = 1; i < conflicts.Count; ++i) | ||
1294 | { | ||
1295 | this.Messaging.Write(WarningMessages.GeneratedShortFileNameConflict2(conflicts[i].SourceLineNumbers)); | ||
1296 | } | ||
1297 | } | ||
1298 | } | ||
1299 | |||
1300 | private void ReportIllegalTables() | ||
1301 | { | ||
1302 | foreach (var table in this.Data.Tables) | ||
1303 | { | ||
1304 | switch (this.Data.Type) | ||
1305 | { | ||
1306 | case OutputType.Module: | ||
1307 | if ("BBControl" == table.Name || | ||
1308 | "Billboard" == table.Name || | ||
1309 | "CCPSearch" == table.Name || | ||
1310 | "Feature" == table.Name || | ||
1311 | "LaunchCondition" == table.Name || | ||
1312 | "Media" == table.Name || | ||
1313 | "Patch" == table.Name || | ||
1314 | "Upgrade" == table.Name || | ||
1315 | "WixMerge" == table.Name) | ||
1316 | { | ||
1317 | foreach (Row row in table.Rows) | ||
1318 | { | ||
1319 | this.Messaging.Write(ErrorMessages.UnexpectedTableInMergeModule(row.SourceLineNumbers, table.Name)); | ||
1320 | } | ||
1321 | } | ||
1322 | else if ("Error" == table.Name) | ||
1323 | { | ||
1324 | foreach (var row in table.Rows) | ||
1325 | { | ||
1326 | this.Messaging.Write(WarningMessages.DangerousTableInMergeModule(row.SourceLineNumbers, table.Name)); | ||
1327 | } | ||
1328 | } | ||
1329 | break; | ||
1330 | |||
1331 | case OutputType.PatchCreation: | ||
1332 | if (!table.Definition.Unreal && | ||
1333 | "_SummaryInformation" != table.Name && | ||
1334 | "ExternalFiles" != table.Name && | ||
1335 | "FamilyFileRanges" != table.Name && | ||
1336 | "ImageFamilies" != table.Name && | ||
1337 | "PatchMetadata" != table.Name && | ||
1338 | "PatchSequence" != table.Name && | ||
1339 | "Properties" != table.Name && | ||
1340 | "TargetFiles_OptionalData" != table.Name && | ||
1341 | "TargetImages" != table.Name && | ||
1342 | "UpgradedFiles_OptionalData" != table.Name && | ||
1343 | "UpgradedFilesToIgnore" != table.Name && | ||
1344 | "UpgradedImages" != table.Name) | ||
1345 | { | ||
1346 | foreach (var row in table.Rows) | ||
1347 | { | ||
1348 | this.Messaging.Write(ErrorMessages.UnexpectedTableInPatchCreationPackage(row.SourceLineNumbers, table.Name)); | ||
1349 | } | ||
1350 | } | ||
1351 | break; | ||
1352 | |||
1353 | case OutputType.Patch: | ||
1354 | if (!table.Definition.Unreal && | ||
1355 | "_SummaryInformation" != table.Name && | ||
1356 | "Media" != table.Name && | ||
1357 | "MsiFileHash" != table.Name && | ||
1358 | "MsiPatchMetadata" != table.Name && | ||
1359 | "MsiPatchSequence" != table.Name) | ||
1360 | { | ||
1361 | foreach (var row in table.Rows) | ||
1362 | { | ||
1363 | this.Messaging.Write(ErrorMessages.UnexpectedTableInPatch(row.SourceLineNumbers, table.Name)); | ||
1364 | } | ||
1365 | } | ||
1366 | break; | ||
1367 | |||
1368 | case OutputType.Product: | ||
1369 | if ("ModuleAdminExecuteSequence" == table.Name || | ||
1370 | "ModuleAdminUISequence" == table.Name || | ||
1371 | "ModuleAdvtExecuteSequence" == table.Name || | ||
1372 | "ModuleAdvtUISequence" == table.Name || | ||
1373 | "ModuleComponents" == table.Name || | ||
1374 | "ModuleConfiguration" == table.Name || | ||
1375 | "ModuleDependency" == table.Name || | ||
1376 | "ModuleExclusion" == table.Name || | ||
1377 | "ModuleIgnoreTable" == table.Name || | ||
1378 | "ModuleInstallExecuteSequence" == table.Name || | ||
1379 | "ModuleInstallUISequence" == table.Name || | ||
1380 | "ModuleSignature" == table.Name || | ||
1381 | "ModuleSubstitution" == table.Name) | ||
1382 | { | ||
1383 | foreach (var row in table.Rows) | ||
1384 | { | ||
1385 | this.Messaging.Write(WarningMessages.UnexpectedTableInProduct(row.SourceLineNumbers, table.Name)); | ||
1386 | } | ||
1387 | } | ||
1388 | break; | ||
1389 | } | ||
1390 | } | ||
1391 | } | ||
1392 | |||
1393 | private void ReportMismatchedModularizations() | ||
1394 | { | ||
1395 | // verify that modularization types match for foreign key relationships | ||
1396 | foreach (var tableDefinition in this.TableDefinitions) | ||
1397 | { | ||
1398 | foreach (var columnDefinition in tableDefinition.Columns) | ||
1399 | { | ||
1400 | if (null != columnDefinition.KeyTable && 0 > columnDefinition.KeyTable.IndexOf(';') && columnDefinition.KeyColumn.HasValue) | ||
1401 | { | ||
1402 | if (this.TableDefinitions.TryGet(columnDefinition.KeyTable, out var keyTableDefinition)) | ||
1403 | { | ||
1404 | var keyColumnIndex = columnDefinition.KeyColumn ?? -1; | ||
1405 | |||
1406 | if (keyColumnIndex <= 0 || keyColumnIndex > keyTableDefinition.Columns.Length) | ||
1407 | { | ||
1408 | this.Messaging.Write(ErrorMessages.InvalidKeyColumn(tableDefinition.Name, columnDefinition.Name, columnDefinition.KeyTable, keyColumnIndex)); | ||
1409 | } | ||
1410 | else if (keyTableDefinition.Columns[keyColumnIndex - 1].ModularizeType != columnDefinition.ModularizeType && ColumnModularizeType.CompanionFile != columnDefinition.ModularizeType) | ||
1411 | { | ||
1412 | this.Messaging.Write(ErrorMessages.CollidingModularizationTypes(tableDefinition.Name, columnDefinition.Name, columnDefinition.KeyTable, keyColumnIndex, columnDefinition.ModularizeType.ToString(), keyTableDefinition.Columns[keyColumnIndex - 1].ModularizeType.ToString())); | ||
1413 | } | ||
1414 | } | ||
1415 | // else - ignore missing table definitions as that error is caught in other places | ||
1416 | } | ||
1417 | } | ||
1418 | } | ||
1419 | } | ||
1420 | |||
1421 | private void ReportWindowsInstallerDataInconsistencies() | ||
1422 | { | ||
1423 | // Get the output's minimum installer version | ||
1424 | var outputInstallerVersion = Int32.MaxValue; | ||
1425 | |||
1426 | if (this.Data.Tables.TryGetTable("_SummaryInformation", out var summaryInformationTable)) | ||
1427 | { | ||
1428 | outputInstallerVersion = summaryInformationTable.Rows.FirstOrDefault(r => 14 == r.FieldAsInteger(0))?.FieldAsInteger(1) ?? Int32.MaxValue; | ||
1429 | } | ||
1430 | |||
1431 | // Ensure the Error table exists if output is marked for MSI 1.0 or below (see ICE40). | ||
1432 | if (outputInstallerVersion <= 100 && OutputType.Product == this.Data.Type) | ||
1433 | { | ||
1434 | this.Data.EnsureTable(this.TableDefinitions["Error"]); | ||
1435 | } | ||
1436 | |||
1437 | // Check for the presence of tables/rows/columns that require MSI 1.1 or later. | ||
1438 | if (outputInstallerVersion < 110) | ||
1439 | { | ||
1440 | if (this.Data.Tables.TryGetTable("IsolatedComponent", out var isolatedComponentTable)) | ||
1441 | { | ||
1442 | foreach (var row in isolatedComponentTable.Rows) | ||
1443 | { | ||
1444 | this.Messaging.Write(WarningMessages.TableIncompatibleWithInstallerVersion(row.SourceLineNumbers, "IsolatedComponent", outputInstallerVersion)); | ||
1445 | } | ||
1446 | } | ||
1447 | } | ||
1448 | |||
1449 | // Check for the presence of tables/rows/columns that require MSI 4.0 or later | ||
1450 | if (outputInstallerVersion < 400) | ||
1451 | { | ||
1452 | if (this.Data.Tables.TryGetTable("Shortcut", out var shortcutTable)) | ||
1453 | { | ||
1454 | foreach (var row in shortcutTable.Rows) | ||
1455 | { | ||
1456 | if (null != row[12] || null != row[13] || null != row[14] || null != row[15]) | ||
1457 | { | ||
1458 | this.Messaging.Write(WarningMessages.ColumnsIncompatibleWithInstallerVersion(row.SourceLineNumbers, "Shortcut", outputInstallerVersion)); | ||
1459 | } | ||
1460 | } | ||
1461 | } | ||
1462 | } | ||
1463 | } | ||
1464 | |||
1171 | private static OutputType SectionTypeToOutputType(SectionType type) | 1465 | private static OutputType SectionTypeToOutputType(SectionType type) |
1172 | { | 1466 | { |
1173 | switch (type) | 1467 | switch (type) |
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs index e96dfd91..67515154 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs | |||
@@ -36,7 +36,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
36 | { | 36 | { |
37 | var canonicalComponentTargetPaths = this.ComponentTargetPaths(); | 37 | var canonicalComponentTargetPaths = this.ComponentTargetPaths(); |
38 | 38 | ||
39 | this.FileFacades.Sort(new FileFacadeOptimizer(canonicalComponentTargetPaths)); | 39 | this.FileFacades.Sort(new FileFacadeOptimizer(canonicalComponentTargetPaths, this.Section.Type == SectionType.Module)); |
40 | 40 | ||
41 | return this.FileFacades; | 41 | return this.FileFacades; |
42 | } | 42 | } |
@@ -71,17 +71,21 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
71 | 71 | ||
72 | private class FileFacadeOptimizer : IComparer<FileFacade> | 72 | private class FileFacadeOptimizer : IComparer<FileFacade> |
73 | { | 73 | { |
74 | public FileFacadeOptimizer(Dictionary<string, string> componentTargetPaths) | 74 | public FileFacadeOptimizer(Dictionary<string, string> componentTargetPaths, bool optimizingMergeModule) |
75 | { | 75 | { |
76 | this.ComponentTargetPaths = componentTargetPaths; | 76 | this.ComponentTargetPaths = componentTargetPaths; |
77 | this.OptimizingMergeModule = optimizingMergeModule; | ||
77 | } | 78 | } |
78 | 79 | ||
79 | private Dictionary<string, string> ComponentTargetPaths { get; } | 80 | private Dictionary<string, string> ComponentTargetPaths { get; } |
80 | 81 | ||
82 | private bool OptimizingMergeModule { get; } | ||
83 | |||
81 | public int Compare(FileFacade x, FileFacade y) | 84 | public int Compare(FileFacade x, FileFacade y) |
82 | { | 85 | { |
83 | // First group files by DiskId. | 86 | // First group files by DiskId but ignore if processing a Merge Module |
84 | var compare = x.DiskId.CompareTo(y.DiskId); | 87 | // because Merge Modules don't have separate disks. |
88 | var compare = this.OptimizingMergeModule ? 0 : x.DiskId.CompareTo(y.DiskId); | ||
85 | 89 | ||
86 | if (compare != 0) | 90 | if (compare != 0) |
87 | { | 91 | { |
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/ProcessDependencyReferencesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/ProcessDependencyReferencesCommand.cs index 0ae7ca73..7a7c2649 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/ProcessDependencyReferencesCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/ProcessDependencyReferencesCommand.cs | |||
@@ -17,7 +17,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
17 | private const string DependencyRegistryRoot = @"Software\Classes\Installer\Dependencies\"; | 17 | private const string DependencyRegistryRoot = @"Software\Classes\Installer\Dependencies\"; |
18 | private const string RegistryDependents = "Dependents"; | 18 | private const string RegistryDependents = "Dependents"; |
19 | 19 | ||
20 | public ProcessDependencyReferencesCommand(IWindowsInstallerBackendHelper backendHelper, IntermediateSection section, IEnumerable<WixDependencyRefSymbol> dependencyRefSymbols) | 20 | public ProcessDependencyReferencesCommand(IntermediateSection section, IEnumerable<WixDependencyRefSymbol> dependencyRefSymbols) |
21 | { | 21 | { |
22 | this.Section = section; | 22 | this.Section = section; |
23 | this.DependencyRefSymbols = dependencyRefSymbols; | 23 | this.DependencyRefSymbols = dependencyRefSymbols; |
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs index 8aa82d47..f311a5f6 100644 --- a/src/WixToolset.Core/Compiler.cs +++ b/src/WixToolset.Core/Compiler.cs | |||
@@ -7178,7 +7178,7 @@ namespace WixToolset.Core | |||
7178 | cabinet = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 7178 | cabinet = this.Core.GetAttributeValue(sourceLineNumbers, attrib); |
7179 | break; | 7179 | break; |
7180 | case "CompressionLevel": | 7180 | case "CompressionLevel": |
7181 | compressionLevel = this.ParseCompressionLevel(sourceLineNumbers, node, attrib); | 7181 | compressionLevel = this.ParseCompressionLevel(sourceLineNumbers, attrib); |
7182 | break; | 7182 | break; |
7183 | case "DiskPrompt": | 7183 | case "DiskPrompt": |
7184 | diskPrompt = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 7184 | diskPrompt = this.Core.GetAttributeValue(sourceLineNumbers, attrib); |
@@ -7381,7 +7381,7 @@ namespace WixToolset.Core | |||
7381 | } | 7381 | } |
7382 | break; | 7382 | break; |
7383 | case "CompressionLevel": | 7383 | case "CompressionLevel": |
7384 | compressionLevel = this.ParseCompressionLevel(sourceLineNumbers, node, attrib); | 7384 | compressionLevel = this.ParseCompressionLevel(sourceLineNumbers, attrib); |
7385 | break; | 7385 | break; |
7386 | case "DiskPrompt": | 7386 | case "DiskPrompt": |
7387 | diskPrompt = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 7387 | diskPrompt = this.Core.GetAttributeValue(sourceLineNumbers, attrib); |
diff --git a/src/WixToolset.Core/Compiler_Package.cs b/src/WixToolset.Core/Compiler_Package.cs index 2cc77a60..03ba1c40 100644 --- a/src/WixToolset.Core/Compiler_Package.cs +++ b/src/WixToolset.Core/Compiler_Package.cs | |||
@@ -4950,7 +4950,7 @@ namespace WixToolset.Core | |||
4950 | } | 4950 | } |
4951 | } | 4951 | } |
4952 | 4952 | ||
4953 | private CompressionLevel? ParseCompressionLevel(SourceLineNumber sourceLineNumbers, XElement node, XAttribute attribute) | 4953 | private CompressionLevel? ParseCompressionLevel(SourceLineNumber sourceLineNumbers, XAttribute attribute) |
4954 | { | 4954 | { |
4955 | var compressionLevel = this.Core.GetAttributeValue(sourceLineNumbers, attribute); | 4955 | var compressionLevel = this.Core.GetAttributeValue(sourceLineNumbers, attribute); |
4956 | switch (compressionLevel) | 4956 | switch (compressionLevel) |
diff --git a/src/WixToolset.Core/Linker.cs b/src/WixToolset.Core/Linker.cs index 41e0db7d..3281cbd0 100644 --- a/src/WixToolset.Core/Linker.cs +++ b/src/WixToolset.Core/Linker.cs | |||
@@ -93,52 +93,12 @@ namespace WixToolset.Core | |||
93 | } | 93 | } |
94 | } | 94 | } |
95 | 95 | ||
96 | #if MOVE_TO_BACKEND | ||
97 | bool containsModuleSubstitution = false; | ||
98 | bool containsModuleConfiguration = false; | ||
99 | #endif | ||
100 | |||
101 | //this.activeOutput = null; | 96 | //this.activeOutput = null; |
102 | 97 | ||
103 | #if MOVE_TO_BACKEND | ||
104 | StringCollection generatedShortFileNameIdentifiers = new StringCollection(); | ||
105 | Hashtable generatedShortFileNames = new Hashtable(); | ||
106 | #endif | ||
107 | |||
108 | var multipleFeatureComponents = new Hashtable(); | 98 | var multipleFeatureComponents = new Hashtable(); |
109 | 99 | ||
110 | var wixVariables = new Dictionary<string, WixVariableSymbol>(); | 100 | var wixVariables = new Dictionary<string, WixVariableSymbol>(); |
111 | 101 | ||
112 | #if MOVE_TO_BACKEND | ||
113 | // verify that modularization types match for foreign key relationships | ||
114 | foreach (TableDefinition tableDefinition in this.tableDefinitions) | ||
115 | { | ||
116 | foreach (ColumnDefinition columnDefinition in tableDefinition.Columns) | ||
117 | { | ||
118 | if (null != columnDefinition.KeyTable && 0 > columnDefinition.KeyTable.IndexOf(';') && columnDefinition.IsKeyColumnSet) | ||
119 | { | ||
120 | try | ||
121 | { | ||
122 | TableDefinition keyTableDefinition = this.tableDefinitions[columnDefinition.KeyTable]; | ||
123 | |||
124 | if (0 >= columnDefinition.KeyColumn || keyTableDefinition.Columns.Count < columnDefinition.KeyColumn) | ||
125 | { | ||
126 | this.Messaging.Write(WixErrors.InvalidKeyColumn(tableDefinition.Name, columnDefinition.Name, columnDefinition.KeyTable, columnDefinition.KeyColumn)); | ||
127 | } | ||
128 | else if (keyTableDefinition.Columns[columnDefinition.KeyColumn - 1].ModularizeType != columnDefinition.ModularizeType && ColumnModularizeType.CompanionFile != columnDefinition.ModularizeType) | ||
129 | { | ||
130 | this.Messaging.Write(WixErrors.CollidingModularizationTypes(tableDefinition.Name, columnDefinition.Name, columnDefinition.KeyTable, columnDefinition.KeyColumn, columnDefinition.ModularizeType.ToString(), keyTableDefinition.Columns[columnDefinition.KeyColumn - 1].ModularizeType.ToString())); | ||
131 | } | ||
132 | } | ||
133 | catch (WixMissingTableDefinitionException) | ||
134 | { | ||
135 | // ignore missing table definitions - this error is caught in other places | ||
136 | } | ||
137 | } | ||
138 | } | ||
139 | } | ||
140 | #endif | ||
141 | |||
142 | // First find the entry section and while processing all sections load all the symbols from all of the sections. | 102 | // First find the entry section and while processing all sections load all the symbols from all of the sections. |
143 | var find = new FindEntrySectionAndLoadSymbolsCommand(this.Messaging, sections, this.Context.ExpectedOutputType); | 103 | var find = new FindEntrySectionAndLoadSymbolsCommand(this.Messaging, sections, this.Context.ExpectedOutputType); |
144 | find.Execute(); | 104 | find.Execute(); |
@@ -211,7 +171,8 @@ namespace WixToolset.Core | |||
211 | // resolve the feature to feature connects | 171 | // resolve the feature to feature connects |
212 | this.ResolveFeatureToFeatureConnects(featuresToFeatures, find.SymbolsByName); | 172 | this.ResolveFeatureToFeatureConnects(featuresToFeatures, find.SymbolsByName); |
213 | 173 | ||
214 | // Create the section to hold the linked content. | 174 | // Create a new section to hold the linked content. Start with the entry section's |
175 | // metadata. | ||
215 | var resolvedSection = new IntermediateSection(find.EntrySection.Id, find.EntrySection.Type, find.EntrySection.Codepage); | 176 | var resolvedSection = new IntermediateSection(find.EntrySection.Id, find.EntrySection.Type, find.EntrySection.Codepage); |
216 | 177 | ||
217 | var sectionCount = 0; | 178 | var sectionCount = 0; |
@@ -245,54 +206,6 @@ namespace WixToolset.Core | |||
245 | } | 206 | } |
246 | break; | 207 | break; |
247 | 208 | ||
248 | #if MOVE_TO_BACKEND | ||
249 | case "CustomAction": | ||
250 | if (OutputType.Module == this.activeOutput.Type) | ||
251 | { | ||
252 | this.activeOutput.EnsureTable(this.tableDefinitions["AdminExecuteSequence"]); | ||
253 | this.activeOutput.EnsureTable(this.tableDefinitions["AdminUISequence"]); | ||
254 | this.activeOutput.EnsureTable(this.tableDefinitions["AdvtExecuteSequence"]); | ||
255 | this.activeOutput.EnsureTable(this.tableDefinitions["InstallExecuteSequence"]); | ||
256 | this.activeOutput.EnsureTable(this.tableDefinitions["InstallUISequence"]); | ||
257 | } | ||
258 | break; | ||
259 | |||
260 | case "Directory": | ||
261 | foreach (Row row in table.Rows) | ||
262 | { | ||
263 | if (OutputType.Module == this.activeOutput.Type) | ||
264 | { | ||
265 | string directory = row[0].ToString(); | ||
266 | if (WindowsInstallerStandard.IsStandardDirectory(directory)) | ||
267 | { | ||
268 | // if the directory table contains references to standard windows folders | ||
269 | // mergemod.dll will add customactions to set the MSM directory to | ||
270 | // the same directory as the standard windows folder and will add references to | ||
271 | // custom action to all the standard sequence tables. A problem will occur | ||
272 | // if the MSI does not have these tables as mergemod.dll does not add these | ||
273 | // tables to the MSI if absent. This code adds the tables in case mergemod.dll | ||
274 | // needs them. | ||
275 | this.activeOutput.EnsureTable(this.tableDefinitions["CustomAction"]); | ||
276 | this.activeOutput.EnsureTable(this.tableDefinitions["AdminExecuteSequence"]); | ||
277 | this.activeOutput.EnsureTable(this.tableDefinitions["AdminUISequence"]); | ||
278 | this.activeOutput.EnsureTable(this.tableDefinitions["AdvtExecuteSequence"]); | ||
279 | this.activeOutput.EnsureTable(this.tableDefinitions["InstallExecuteSequence"]); | ||
280 | this.activeOutput.EnsureTable(this.tableDefinitions["InstallUISequence"]); | ||
281 | } | ||
282 | else | ||
283 | { | ||
284 | foreach (string standardDirectory in WindowsInstallerStandard.GetStandardDirectories()) | ||
285 | { | ||
286 | if (directory.StartsWith(standardDirectory, StringComparison.Ordinal)) | ||
287 | { | ||
288 | this.Messaging.Write(WixWarnings.StandardDirectoryConflictInMergeModule(row.SourceLineNumbers, directory, standardDirectory)); | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | break; | ||
295 | #endif | ||
296 | case SymbolDefinitionType.Extension: | 209 | case SymbolDefinitionType.Extension: |
297 | if (SectionType.Product == resolvedSection.Type) | 210 | if (SectionType.Product == resolvedSection.Type) |
298 | { | 211 | { |
@@ -300,16 +213,6 @@ namespace WixToolset.Core | |||
300 | } | 213 | } |
301 | break; | 214 | break; |
302 | 215 | ||
303 | #if MOVE_TO_BACKEND | ||
304 | case SymbolDefinitionType.ModuleSubstitution: | ||
305 | containsModuleSubstitution = true; | ||
306 | break; | ||
307 | |||
308 | case SymbolDefinitionType.ModuleConfiguration: | ||
309 | containsModuleConfiguration = true; | ||
310 | break; | ||
311 | #endif | ||
312 | |||
313 | case SymbolDefinitionType.Assembly: | 216 | case SymbolDefinitionType.Assembly: |
314 | if (SectionType.Product == resolvedSection.Type) | 217 | if (SectionType.Product == resolvedSection.Type) |
315 | { | 218 | { |
@@ -338,26 +241,6 @@ namespace WixToolset.Core | |||
338 | } | 241 | } |
339 | break; | 242 | break; |
340 | 243 | ||
341 | #if MOVE_TO_BACKEND | ||
342 | case "WixFile": | ||
343 | foreach (Row row in table.Rows) | ||
344 | { | ||
345 | // DiskId is not valid when creating a module, so set it to | ||
346 | // 0 for all files to ensure proper sorting in the binder | ||
347 | if (SectionType.Module == entrySection.Type) | ||
348 | { | ||
349 | row[5] = 0; | ||
350 | } | ||
351 | |||
352 | // if the short file name was generated, check for collisions | ||
353 | if (0x1 == (int)row[9]) | ||
354 | { | ||
355 | generatedShortFileNameIdentifiers.Add((string)row[0]); | ||
356 | } | ||
357 | } | ||
358 | break; | ||
359 | #endif | ||
360 | |||
361 | case SymbolDefinitionType.WixMerge: | 244 | case SymbolDefinitionType.WixMerge: |
362 | if (SectionType.Product == resolvedSection.Type) | 245 | if (SectionType.Product == resolvedSection.Type) |
363 | { | 246 | { |
@@ -374,30 +257,9 @@ namespace WixToolset.Core | |||
374 | break; | 257 | break; |
375 | 258 | ||
376 | case SymbolDefinitionType.WixVariable: | 259 | case SymbolDefinitionType.WixVariable: |
377 | // check for colliding values and collect the wix variable rows | 260 | this.AddWixVariable(wixVariables, (WixVariableSymbol)symbol); |
378 | { | 261 | copySymbol = false; // Do not copy the symbol, it will be added later after all overriding has been handled. |
379 | var wixVariableSymbol = (WixVariableSymbol)symbol; | 262 | break; |
380 | var id = wixVariableSymbol.Id.Id; | ||
381 | |||
382 | if (wixVariables.TryGetValue(id, out var collidingSymbol)) | ||
383 | { | ||
384 | if (collidingSymbol.Overridable && !wixVariableSymbol.Overridable) | ||
385 | { | ||
386 | wixVariables[id] = wixVariableSymbol; | ||
387 | } | ||
388 | else if (!wixVariableSymbol.Overridable || (collidingSymbol.Overridable && wixVariableSymbol.Overridable)) | ||
389 | { | ||
390 | this.Messaging.Write(ErrorMessages.WixVariableCollision(wixVariableSymbol.SourceLineNumbers, id)); | ||
391 | } | ||
392 | } | ||
393 | else | ||
394 | { | ||
395 | wixVariables.Add(id, wixVariableSymbol); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | copySymbol = false; | ||
400 | break; | ||
401 | } | 263 | } |
402 | 264 | ||
403 | if (copySymbol) | 265 | if (copySymbol) |
@@ -407,7 +269,7 @@ namespace WixToolset.Core | |||
407 | } | 269 | } |
408 | } | 270 | } |
409 | 271 | ||
410 | // copy the module to feature connections into the output | 272 | // Copy the module to feature connections into the output. |
411 | foreach (ConnectToFeature connectToFeature in modulesToFeatures) | 273 | foreach (ConnectToFeature connectToFeature in modulesToFeatures) |
412 | { | 274 | { |
413 | foreach (var feature in connectToFeature.ConnectFeatures) | 275 | foreach (var feature in connectToFeature.ConnectFeatures) |
@@ -420,136 +282,23 @@ namespace WixToolset.Core | |||
420 | } | 282 | } |
421 | } | 283 | } |
422 | 284 | ||
423 | #if MOVE_TO_BACKEND | 285 | // Correct the section Id in FeatureComponents table. |
424 | // check for missing table and add them or display an error as appropriate | ||
425 | switch (this.activeOutput.Type) | ||
426 | { | ||
427 | case OutputType.Module: | ||
428 | this.activeOutput.EnsureTable(this.tableDefinitions["Component"]); | ||
429 | this.activeOutput.EnsureTable(this.tableDefinitions["Directory"]); | ||
430 | this.activeOutput.EnsureTable(this.tableDefinitions["FeatureComponents"]); | ||
431 | this.activeOutput.EnsureTable(this.tableDefinitions["File"]); | ||
432 | this.activeOutput.EnsureTable(this.tableDefinitions["ModuleComponents"]); | ||
433 | this.activeOutput.EnsureTable(this.tableDefinitions["ModuleSignature"]); | ||
434 | break; | ||
435 | case OutputType.PatchCreation: | ||
436 | Table imageFamiliesTable = this.activeOutput.Tables["ImageFamilies"]; | ||
437 | Table targetImagesTable = this.activeOutput.Tables["TargetImages"]; | ||
438 | Table upgradedImagesTable = this.activeOutput.Tables["UpgradedImages"]; | ||
439 | |||
440 | if (null == imageFamiliesTable || 1 > imageFamiliesTable.Rows.Count) | ||
441 | { | ||
442 | this.Messaging.Write(WixErrors.ExpectedRowInPatchCreationPackage("ImageFamilies")); | ||
443 | } | ||
444 | |||
445 | if (null == targetImagesTable || 1 > targetImagesTable.Rows.Count) | ||
446 | { | ||
447 | this.Messaging.Write(WixErrors.ExpectedRowInPatchCreationPackage("TargetImages")); | ||
448 | } | ||
449 | |||
450 | if (null == upgradedImagesTable || 1 > upgradedImagesTable.Rows.Count) | ||
451 | { | ||
452 | this.Messaging.Write(WixErrors.ExpectedRowInPatchCreationPackage("UpgradedImages")); | ||
453 | } | ||
454 | |||
455 | this.activeOutput.EnsureTable(this.tableDefinitions["Properties"]); | ||
456 | break; | ||
457 | case OutputType.Product: | ||
458 | this.activeOutput.EnsureTable(this.tableDefinitions["File"]); | ||
459 | this.activeOutput.EnsureTable(this.tableDefinitions["Media"]); | ||
460 | break; | ||
461 | } | ||
462 | |||
463 | this.CheckForIllegalTables(this.activeOutput); | ||
464 | #endif | ||
465 | |||
466 | //correct the section Id in FeatureComponents table | ||
467 | if (this.sectionIdOnRows) | 286 | if (this.sectionIdOnRows) |
468 | { | 287 | { |
469 | //var componentSectionIds = new Dictionary<string, string>(); | 288 | #if TODO_DO_SYMBOLS_NEED_SECTIONIDS |
470 | 289 | var componentSectionIds = resolvedSection.Symbols.OfType<ComponentSymbol>().ToDictionary(c => c.Id.Id, c => c.SectionId); | |
471 | //foreach (var componentSymbol in entrySection.Symbols.OfType<ComponentSymbol>()) | ||
472 | //{ | ||
473 | // componentSectionIds.Add(componentSymbol.Id.Id, componentSymbol.SectionId); | ||
474 | //} | ||
475 | |||
476 | //foreach (var featureComponentSymbol in entrySection.Symbols.OfType<FeatureComponentsSymbol>()) | ||
477 | //{ | ||
478 | // if (componentSectionIds.TryGetValue(featureComponentSymbol.Component_, out var componentSectionId)) | ||
479 | // { | ||
480 | // featureComponentSymbol.SectionId = componentSectionId; | ||
481 | // } | ||
482 | //} | ||
483 | } | ||
484 | |||
485 | #if MOVE_TO_BACKEND | ||
486 | // add the ModuleSubstitution table to the ModuleIgnoreTable | ||
487 | if (containsModuleSubstitution) | ||
488 | { | ||
489 | Table moduleIgnoreTableTable = this.activeOutput.EnsureTable(this.tableDefinitions["ModuleIgnoreTable"]); | ||
490 | |||
491 | Row moduleIgnoreTableRow = moduleIgnoreTableTable.CreateRow(null); | ||
492 | moduleIgnoreTableRow[0] = "ModuleSubstitution"; | ||
493 | } | ||
494 | |||
495 | // add the ModuleConfiguration table to the ModuleIgnoreTable | ||
496 | if (containsModuleConfiguration) | ||
497 | { | ||
498 | Table moduleIgnoreTableTable = this.activeOutput.EnsureTable(this.tableDefinitions["ModuleIgnoreTable"]); | ||
499 | |||
500 | Row moduleIgnoreTableRow = moduleIgnoreTableTable.CreateRow(null); | ||
501 | moduleIgnoreTableRow[0] = "ModuleConfiguration"; | ||
502 | } | ||
503 | #endif | ||
504 | |||
505 | #if MOVE_TO_BACKEND | ||
506 | // index all the file rows | ||
507 | Table fileTable = this.activeOutput.Tables["File"]; | ||
508 | RowDictionary<FileRow> indexedFileRows = (null == fileTable) ? new RowDictionary<FileRow>() : new RowDictionary<FileRow>(fileTable); | ||
509 | |||
510 | // flag all the generated short file name collisions | ||
511 | foreach (string fileId in generatedShortFileNameIdentifiers) | ||
512 | { | ||
513 | FileRow fileRow = indexedFileRows[fileId]; | ||
514 | |||
515 | string[] names = fileRow.FileName.Split('|'); | ||
516 | string shortFileName = names[0]; | ||
517 | 290 | ||
518 | // create lists of conflicting generated short file names | 291 | foreach (var featureComponentSymbol in resolvedSection.Symbols.OfType<FeatureComponentsSymbol>()) |
519 | if (!generatedShortFileNames.Contains(shortFileName)) | ||
520 | { | 292 | { |
521 | generatedShortFileNames.Add(shortFileName, new ArrayList()); | 293 | if (componentSectionIds.TryGetValue(featureComponentSymbol.ComponentRef, out var componentSectionId)) |
522 | } | ||
523 | ((ArrayList)generatedShortFileNames[shortFileName]).Add(fileRow); | ||
524 | } | ||
525 | |||
526 | // check for generated short file name collisions | ||
527 | foreach (DictionaryEntry entry in generatedShortFileNames) | ||
528 | { | ||
529 | string shortFileName = (string)entry.Key; | ||
530 | ArrayList fileRows = (ArrayList)entry.Value; | ||
531 | |||
532 | if (1 < fileRows.Count) | ||
533 | { | ||
534 | // sort the rows by DiskId | ||
535 | fileRows.Sort(); | ||
536 | |||
537 | this.Messaging.Write(WixWarnings.GeneratedShortFileNameConflict(((FileRow)fileRows[0]).SourceLineNumbers, shortFileName)); | ||
538 | |||
539 | for (int i = 1; i < fileRows.Count; i++) | ||
540 | { | 294 | { |
541 | FileRow fileRow = (FileRow)fileRows[i]; | 295 | featureComponentSymbol.SectionId = componentSectionId; |
542 | |||
543 | if (null != fileRow.SourceLineNumbers) | ||
544 | { | ||
545 | this.Messaging.Write(WixWarnings.GeneratedShortFileNameConflict2(fileRow.SourceLineNumbers)); | ||
546 | } | ||
547 | } | 296 | } |
548 | } | 297 | } |
549 | } | ||
550 | #endif | 298 | #endif |
299 | } | ||
551 | 300 | ||
552 | // copy the wix variable rows to the output after all overriding has been accounted for. | 301 | // Copy the wix variable rows to the output now that all overriding has been accounted for. |
553 | foreach (var symbol in wixVariables.Values) | 302 | foreach (var symbol in wixVariables.Values) |
554 | { | 303 | { |
555 | resolvedSection.AddSymbol(symbol); | 304 | resolvedSection.AddSymbol(symbol); |
@@ -567,10 +316,6 @@ namespace WixToolset.Core | |||
567 | var localizationsByCulture = collate.Execute(); | 316 | var localizationsByCulture = collate.Execute(); |
568 | 317 | ||
569 | intermediate = new Intermediate(resolvedSection.Id, Data.IntermediateLevels.Linked, new[] { resolvedSection }, localizationsByCulture); | 318 | intermediate = new Intermediate(resolvedSection.Id, Data.IntermediateLevels.Linked, new[] { resolvedSection }, localizationsByCulture); |
570 | |||
571 | #if MOVE_TO_BACKEND | ||
572 | this.CheckOutputConsistency(output); | ||
573 | #endif | ||
574 | } | 319 | } |
575 | finally | 320 | finally |
576 | { | 321 | { |
@@ -583,159 +328,31 @@ namespace WixToolset.Core | |||
583 | return this.Messaging.EncounteredError ? null : intermediate; | 328 | return this.Messaging.EncounteredError ? null : intermediate; |
584 | } | 329 | } |
585 | 330 | ||
586 | #if MOVE_TO_BACKEND | ||
587 | /// <summary> | 331 | /// <summary> |
588 | /// Checks for any tables in the output which are not allowed in the output type. | 332 | /// Check for colliding values and collect the wix variable rows. |
589 | /// </summary> | 333 | /// </summary> |
590 | /// <param name="output">The output to check.</param> | 334 | /// <param name="wixVariables">Collection of WixVariableSymbols by id.</param> |
591 | private void CheckForIllegalTables(Output output) | 335 | /// <param name="symbol">WixVariableSymbol to add, if not overridden.</param> |
336 | private void AddWixVariable(Dictionary<string, WixVariableSymbol> wixVariables, WixVariableSymbol symbol) | ||
592 | { | 337 | { |
593 | foreach (Table table in output.Tables) | 338 | var id = symbol.Id.Id; |
594 | { | ||
595 | switch (output.Type) | ||
596 | { | ||
597 | case OutputType.Module: | ||
598 | if ("BBControl" == table.Name || | ||
599 | "Billboard" == table.Name || | ||
600 | "CCPSearch" == table.Name || | ||
601 | "Feature" == table.Name || | ||
602 | "LaunchCondition" == table.Name || | ||
603 | "Media" == table.Name || | ||
604 | "Patch" == table.Name || | ||
605 | "Upgrade" == table.Name || | ||
606 | "WixMerge" == table.Name) | ||
607 | { | ||
608 | foreach (Row row in table.Rows) | ||
609 | { | ||
610 | this.Messaging.Write(WixErrors.UnexpectedTableInMergeModule(row.SourceLineNumbers, table.Name)); | ||
611 | } | ||
612 | } | ||
613 | else if ("Error" == table.Name) | ||
614 | { | ||
615 | foreach (Row row in table.Rows) | ||
616 | { | ||
617 | this.Messaging.Write(WixWarnings.DangerousTableInMergeModule(row.SourceLineNumbers, table.Name)); | ||
618 | } | ||
619 | } | ||
620 | break; | ||
621 | case OutputType.PatchCreation: | ||
622 | if (!table.Definition.Unreal && | ||
623 | "_SummaryInformation" != table.Name && | ||
624 | "ExternalFiles" != table.Name && | ||
625 | "FamilyFileRanges" != table.Name && | ||
626 | "ImageFamilies" != table.Name && | ||
627 | "PatchMetadata" != table.Name && | ||
628 | "PatchSequence" != table.Name && | ||
629 | "Properties" != table.Name && | ||
630 | "TargetFiles_OptionalData" != table.Name && | ||
631 | "TargetImages" != table.Name && | ||
632 | "UpgradedFiles_OptionalData" != table.Name && | ||
633 | "UpgradedFilesToIgnore" != table.Name && | ||
634 | "UpgradedImages" != table.Name) | ||
635 | { | ||
636 | foreach (Row row in table.Rows) | ||
637 | { | ||
638 | this.Messaging.Write(WixErrors.UnexpectedTableInPatchCreationPackage(row.SourceLineNumbers, table.Name)); | ||
639 | } | ||
640 | } | ||
641 | break; | ||
642 | case OutputType.Patch: | ||
643 | if (!table.Definition.Unreal && | ||
644 | "_SummaryInformation" != table.Name && | ||
645 | "Media" != table.Name && | ||
646 | "MsiPatchMetadata" != table.Name && | ||
647 | "MsiPatchSequence" != table.Name) | ||
648 | { | ||
649 | foreach (Row row in table.Rows) | ||
650 | { | ||
651 | this.Messaging.Write(WixErrors.UnexpectedTableInPatch(row.SourceLineNumbers, table.Name)); | ||
652 | } | ||
653 | } | ||
654 | break; | ||
655 | case OutputType.Product: | ||
656 | if ("ModuleAdminExecuteSequence" == table.Name || | ||
657 | "ModuleAdminUISequence" == table.Name || | ||
658 | "ModuleAdvtExecuteSequence" == table.Name || | ||
659 | "ModuleAdvtUISequence" == table.Name || | ||
660 | "ModuleComponents" == table.Name || | ||
661 | "ModuleConfiguration" == table.Name || | ||
662 | "ModuleDependency" == table.Name || | ||
663 | "ModuleExclusion" == table.Name || | ||
664 | "ModuleIgnoreTable" == table.Name || | ||
665 | "ModuleInstallExecuteSequence" == table.Name || | ||
666 | "ModuleInstallUISequence" == table.Name || | ||
667 | "ModuleSignature" == table.Name || | ||
668 | "ModuleSubstitution" == table.Name) | ||
669 | { | ||
670 | foreach (Row row in table.Rows) | ||
671 | { | ||
672 | this.Messaging.Write(WixWarnings.UnexpectedTableInProduct(row.SourceLineNumbers, table.Name)); | ||
673 | } | ||
674 | } | ||
675 | break; | ||
676 | } | ||
677 | } | ||
678 | } | ||
679 | #endif | ||
680 | 339 | ||
681 | #if MOVE_TO_BACKEND | 340 | if (wixVariables.TryGetValue(id, out var collidingSymbol)) |
682 | /// <summary> | ||
683 | /// Performs various consistency checks on the output. | ||
684 | /// </summary> | ||
685 | /// <param name="output">Output containing instance transform definitions.</param> | ||
686 | private void CheckOutputConsistency(Output output) | ||
687 | { | ||
688 | // Get the output's minimum installer version | ||
689 | int outputInstallerVersion = int.MinValue; | ||
690 | Table summaryInformationTable = output.Tables["_SummaryInformation"]; | ||
691 | if (null != summaryInformationTable) | ||
692 | { | 341 | { |
693 | foreach (Row row in summaryInformationTable.Rows) | 342 | if (collidingSymbol.Overridable && !symbol.Overridable) |
694 | { | 343 | { |
695 | if (14 == (int)row[0]) | 344 | wixVariables[id] = symbol; |
696 | { | ||
697 | outputInstallerVersion = Convert.ToInt32(row[1], CultureInfo.InvariantCulture); | ||
698 | break; | ||
699 | } | ||
700 | } | 345 | } |
701 | } | 346 | else if (!symbol.Overridable || (collidingSymbol.Overridable && symbol.Overridable)) |
702 | |||
703 | // ensure the Error table exists if output is marked for MSI 1.0 or below (see ICE40) | ||
704 | if (100 >= outputInstallerVersion && OutputType.Product == output.Type) | ||
705 | { | ||
706 | output.EnsureTable(this.tableDefinitions["Error"]); | ||
707 | } | ||
708 | |||
709 | // check for the presence of tables/rows/columns that require MSI 1.1 or later | ||
710 | if (110 > outputInstallerVersion) | ||
711 | { | ||
712 | Table isolatedComponentTable = output.Tables["IsolatedComponent"]; | ||
713 | if (null != isolatedComponentTable) | ||
714 | { | 347 | { |
715 | foreach (Row row in isolatedComponentTable.Rows) | 348 | this.Messaging.Write(ErrorMessages.WixVariableCollision(symbol.SourceLineNumbers, id)); |
716 | { | ||
717 | this.Messaging.Write(WixWarnings.TableIncompatibleWithInstallerVersion(row.SourceLineNumbers, "IsolatedComponent", outputInstallerVersion)); | ||
718 | } | ||
719 | } | 349 | } |
720 | } | 350 | } |
721 | 351 | else | |
722 | // check for the presence of tables/rows/columns that require MSI 4.0 or later | ||
723 | if (400 > outputInstallerVersion) | ||
724 | { | 352 | { |
725 | Table shortcutTable = output.Tables["Shortcut"]; | 353 | wixVariables.Add(id, symbol); |
726 | if (null != shortcutTable) | ||
727 | { | ||
728 | foreach (Row row in shortcutTable.Rows) | ||
729 | { | ||
730 | if (null != row[12] || null != row[13] || null != row[14] || null != row[15]) | ||
731 | { | ||
732 | this.Messaging.Write(WixWarnings.ColumnsIncompatibleWithInstallerVersion(row.SourceLineNumbers, "Shortcut", outputInstallerVersion)); | ||
733 | } | ||
734 | } | ||
735 | } | ||
736 | } | 354 | } |
737 | } | 355 | } |
738 | #endif | ||
739 | 356 | ||
740 | /// <summary> | 357 | /// <summary> |
741 | /// Load the standard action and directory symbols. | 358 | /// Load the standard action and directory symbols. |
diff --git a/src/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs b/src/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs index 8c3487f0..2af47034 100644 --- a/src/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs +++ b/src/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs | |||
@@ -1022,7 +1022,7 @@ namespace WixToolsetTest.CoreIntegration | |||
1022 | Assert.Empty(section.Symbols.OfType<FileSymbol>()); | 1022 | Assert.Empty(section.Symbols.OfType<FileSymbol>()); |
1023 | 1023 | ||
1024 | var data = WindowsInstallerData.Load(Path.Combine(intermediateFolder, @"bin\test.wixpdb")); | 1024 | var data = WindowsInstallerData.Load(Path.Combine(intermediateFolder, @"bin\test.wixpdb")); |
1025 | Assert.Null(data.Tables["File"]); | 1025 | Assert.Empty(data.Tables["File"].Rows); |
1026 | 1026 | ||
1027 | var results = Query.QueryDatabase(msiPath, new[] { "File" }); | 1027 | var results = Query.QueryDatabase(msiPath, new[] { "File" }); |
1028 | WixAssert.CompareLineByLine(new[] | 1028 | WixAssert.CompareLineByLine(new[] |
diff --git a/src/test/WixToolsetTest.CoreIntegration/TestData/CustomTable/CustomTable.wxs b/src/test/WixToolsetTest.CoreIntegration/TestData/CustomTable/CustomTable.wxs index 7f4a43e5..d32e808c 100644 --- a/src/test/WixToolsetTest.CoreIntegration/TestData/CustomTable/CustomTable.wxs +++ b/src/test/WixToolsetTest.CoreIntegration/TestData/CustomTable/CustomTable.wxs | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | <CustomTable Id="CustomTable1"> | 8 | <CustomTable Id="CustomTable1"> |
9 | <Column Id="Column1" Type="string" PrimaryKey="yes" Category="text" Modularize="column" Description="The first custom column." /> | 9 | <Column Id="Column1" Type="string" PrimaryKey="yes" Category="text" Modularize="column" Description="The first custom column." /> |
10 | <Column Id="Component_" Type="string" Width="72" KeyTable="Component" KeyColumn="1" Description="The custom table's Component reference" /> | 10 | <Column Id="Component_" Type="string" Width="72" KeyTable="Component" KeyColumn="1" Description="The custom table's Component reference" Modularize="column" /> |
11 | <Row> | 11 | <Row> |
12 | <Data Column="Column1" Value="Row1" /> | 12 | <Data Column="Column1" Value="Row1" /> |
13 | <Data Column="Component_" Value="test.txt" /> | 13 | <Data Column="Component_" Value="test.txt" /> |
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | <CustomTable Id="CustomTable2" Unreal="yes"> | 21 | <CustomTable Id="CustomTable2" Unreal="yes"> |
22 | <Column Id="ColumnA" Type="string" PrimaryKey="yes" /> | 22 | <Column Id="ColumnA" Type="string" PrimaryKey="yes" /> |
23 | <Column Id="Component_" Type="string" Width="72" KeyTable="Component" KeyColumn="1" /> | 23 | <Column Id="Component_" Type="string" Width="72" KeyTable="Component" KeyColumn="1" Modularize="column" /> |
24 | <Row> | 24 | <Row> |
25 | <Data Column="ColumnA" Value="RowA" /> | 25 | <Data Column="ColumnA" Value="RowA" /> |
26 | <Data Column="Component_" Value="test.txt" /> | 26 | <Data Column="Component_" Value="test.txt" /> |